This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] Fix gdb/277 by separating types, take 3


On Tue, May 14, 2002 at 11:23:38AM -0400, Elena Zannoni wrote:
> Daniel Jacobowitz writes:
>  > On Mon, May 13, 2002 at 10:39:26PM -0400, Elena Zannoni wrote:
>  > > 
>  > > Ok with me, except (now he shoots her....) I don't like the 'core'
>  > > name.  It gets a bit confusing between TYPE_CODE and TYPE_CORE, not to
>  > > mention the use of core as in corefiles. How about base, basis,
>  > > nucleus, main, nub (just going through my dictionary)....
>  > > Probably any of you, native English speakers, has a better suggestion.
>  > 
>  > How about TYPE_MAIN_TYPE, then?
>  > 
>  > Amusingly, I found a couple dozen more cases where this patch helps
>  > today in fooling around with C++ method printing...
>  > 
>  > 
> 
> Groovy.

Thanks, it's in - the attached version using struct main_type and
TYPE_MAIN_TYPE.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2002-05-14  Daniel Jacobowitz  <drow@mvista.com>

	* gdbtypes.h: Update accessor macros to use TYPE_MAIN_TYPE.
	(TYPE_CONST, TYPE_VOLATILE, TYPE_CODE_SPACE, TYPE_DATA_SPACE): Use
	TYPE_INSTANCE_FLAGS.
	(struct main_type): New.
	(struct type): Move most members to struct main_type.  Change
	cv_type and as_type to new type_chain member.  Add instance_flags.
	(TYPE_MAIN_TYPE, TYPE_CHAIN, TYPE_INSTANCE_FLAGS): New macros.
	(TYPE_CV_TYPE, TYPE_AS_TYPE): Remove.
	(finish_cv_type): Remove prototype.
	* gdbtypes.c (alloc_type): Update comment.  Allocate TYPE_MAIN_TYPE.
	Set TYPE_CHAIN.
	(alloc_type_instance): New function.
	(smash_type): New function.
	(make_pointer_type, make_reference_type, make_function_type)
	(smash_to_member_type, smash_to_method_type): Call smash_type.
	(make_qualified_type): New function.
	(make_type_with_address_space): Call make_qualified_type.
	(make_cv_type): Likewise.
	(finish_cv_type): Remove unnecessary function.
	(replace_type): Update comment.  Copy TYPE_MAIN_TYPE.
	(recursive_dump_type): Dump TYPE_CHAIN and TYPE_INSTANCE_FLAGS;
	remove TYPE_CV_TYPE and TYPE_AS_TYPE.
	* c-typeprint.c (c_type_print_modifier): Use TYPE_INSTANCE_FLAGS.
	* dwarf2read.c (read_structure_scope): Don't call finish_cv_type.
	* hpread.c (hpread_read_struct_type): Likewise.
	* stabsread.c (read_struct_type): Likewise.

2002-05-14  Daniel Jacobowitz  <drow@mvista.com>

	* gdb.base/maint.exp (maint print type): Update for new type
	structure.

Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.19
diff -u -p -r1.19 c-typeprint.c
--- c-typeprint.c	13 May 2002 14:00:35 -0000	1.19
+++ c-typeprint.c	14 May 2002 18:25:34 -0000
@@ -316,7 +316,7 @@ c_type_print_modifier (struct type *type
       did_print_modifier = 1;
     }
 
-  address_space_id = address_space_int_to_name (TYPE_FLAGS (type));
+  address_space_id = address_space_int_to_name (TYPE_INSTANCE_FLAGS (type));
   if (address_space_id)
     {
       if (did_print_modifier || need_pre_space)
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.55
diff -u -p -r1.55 dwarf2read.c
--- dwarf2read.c	10 May 2002 17:03:25 -0000	1.55
+++ dwarf2read.c	14 May 2002 18:25:36 -0000
@@ -2486,8 +2486,6 @@ read_structure_scope (struct die_info *d
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
-
-  finish_cv_type (die->type);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.50
diff -u -p -r1.50 gdbtypes.c
--- gdbtypes.c	13 May 2002 14:00:36 -0000	1.50
+++ gdbtypes.c	14 May 2002 18:25:36 -0000
@@ -135,7 +135,8 @@ static void virtual_base_list_aux (struc
 
 /* Alloc a new type structure and fill it with some defaults.  If
    OBJFILE is non-NULL, then allocate the space for the type structure
-   in that objfile's type_obstack. */
+   in that objfile's type_obstack.  Otherwise allocate the new type structure
+   by xmalloc () (for permanent types).  */
 
 struct type *
 alloc_type (struct objfile *objfile)
@@ -146,27 +147,73 @@ alloc_type (struct objfile *objfile)
 
   if (objfile == NULL)
     {
-      type = (struct type *) xmalloc (sizeof (struct type));
+      type = xmalloc (sizeof (struct type));
+      memset (type, 0, sizeof (struct type));
+      TYPE_MAIN_TYPE (type) = xmalloc (sizeof (struct main_type));
     }
   else
     {
-      type = (struct type *) obstack_alloc (&objfile->type_obstack,
-					    sizeof (struct type));
+      type = obstack_alloc (&objfile->type_obstack,
+			    sizeof (struct type));
+      memset (type, 0, sizeof (struct type));
+      TYPE_MAIN_TYPE (type) = obstack_alloc (&objfile->type_obstack,
+					     sizeof (struct main_type));
       OBJSTAT (objfile, n_types++);
     }
-  memset ((char *) type, 0, sizeof (struct type));
+  memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type));
 
   /* Initialize the fields that might not be zero. */
 
   TYPE_CODE (type) = TYPE_CODE_UNDEF;
   TYPE_OBJFILE (type) = objfile;
   TYPE_VPTR_FIELDNO (type) = -1;
-  TYPE_CV_TYPE (type) = type;	/* chain back to itself */
-  TYPE_AS_TYPE (type) = type;	/* ditto */
+  TYPE_CHAIN (type) = type;	/* Chain back to itself.  */
 
   return (type);
 }
 
+/* Alloc a new type instance structure, fill it with some defaults,
+   and point it at OLDTYPE.  Allocate the new type instance from the
+   same place as OLDTYPE.  */
+
+static struct type *
+alloc_type_instance (struct type *oldtype)
+{
+  struct type *type;
+
+  /* Allocate the structure.  */
+
+  if (TYPE_OBJFILE (oldtype) == NULL)
+    {
+      type = xmalloc (sizeof (struct type));
+      memset (type, 0, sizeof (struct type));
+    }
+  else
+    {
+      type = obstack_alloc (&TYPE_OBJFILE (oldtype)->type_obstack,
+			    sizeof (struct type));
+      memset (type, 0, sizeof (struct type));
+    }
+  TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype);
+
+  TYPE_CHAIN (type) = type;	/* Chain back to itself for now.  */
+
+  return (type);
+}
+
+/* Clear all remnants of the previous type at TYPE, in preparation for
+   replacing it with something else.  */
+static void
+smash_type (struct type *type)
+{
+  memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type));
+
+  /* For now, delete the rings.  */
+  TYPE_CHAIN (type) = type;
+
+  /* For now, leave the pointer/reference types alone.  */
+}
+
 /* Lookup a pointer to a type TYPE.  TYPEPTR, if nonzero, points
    to a pointer to memory where the pointer type should be stored.
    If *TYPEPTR is zero, update it to point to the pointer type we return.
@@ -202,7 +249,7 @@ make_pointer_type (struct type *type, st
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
-      memset ((char *) ntype, 0, sizeof (struct type));
+      smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
     }
 
@@ -269,7 +316,7 @@ make_reference_type (struct type *type, 
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
-      memset ((char *) ntype, 0, sizeof (struct type));
+      smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
     }
 
@@ -318,7 +365,7 @@ make_function_type (struct type *type, s
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
-      memset ((char *) ntype, 0, sizeof (struct type));
+      smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
     }
 
@@ -368,45 +415,63 @@ address_space_int_to_name (int space_fla
     return NULL;
 }
 
-/* Make an address-space-delimited variant of a type -- a type that
-   is identical to the one supplied except that it has an address
-   space attribute attached to it (such as "code" or "data").
-
-   This is for Harvard architectures. */
+/* Create a new type with instance flags NEW_FLAGS, based on TYPE.
+   If STORAGE is non-NULL, create the new type instance there.  */
 
 struct type *
-make_type_with_address_space (struct type *type, int space_flag)
+make_qualified_type (struct type *type, int new_flags,
+		     struct type *storage)
 {
   struct type *ntype;
 
   ntype = type;
   do {
-    if ((ntype->flags & space_flag) != 0)
+    if (TYPE_INSTANCE_FLAGS (ntype) == new_flags)
       return ntype;
-    ntype = TYPE_AS_TYPE (ntype);
+    ntype = TYPE_CHAIN (ntype);
   } while (ntype != type);
 
-  /* Create a new, duplicate type. */
-  ntype = alloc_type (TYPE_OBJFILE (type));
-  /* Copy original type. */
-  memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+  /* Create a new type instance.  */
+  if (storage == NULL)
+    ntype = alloc_type_instance (type);
+  else
+    {
+      ntype = storage;
+      TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type);
+      TYPE_CHAIN (ntype) = ntype;
+    }
 
   /* Pointers or references to the original type are not relevant to
-     the new type; but if the original type is a pointer, the new type
-     points to the same thing (so TYPE_TARGET_TYPE remains unchanged). */
+     the new type.  */
   TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
   TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;
-  TYPE_CV_TYPE (ntype) = ntype;
 
-  /* Chain the new address-space-specific type to the old type. */
-  ntype->as_type = type->as_type;
-  type->as_type = ntype;
+  /* Chain the new qualified type to the old type.  */
+  TYPE_CHAIN (ntype) = TYPE_CHAIN (type);
+  TYPE_CHAIN (type) = ntype;
+
+  /* Now set the instance flags and return the new type.  */
+  TYPE_INSTANCE_FLAGS (ntype) = new_flags;
 
-  /* Now set the address-space flag, and return the new type. */
-  ntype->flags |= space_flag;
   return ntype;
 }
 
+/* Make an address-space-delimited variant of a type -- a type that
+   is identical to the one supplied except that it has an address
+   space attribute attached to it (such as "code" or "data").
+
+   This is for Harvard architectures. */
+
+struct type *
+make_type_with_address_space (struct type *type, int space_flag)
+{
+  struct type *ntype;
+  int new_flags = ((TYPE_INSTANCE_FLAGS (type)
+		    & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE))
+		   | space_flag);
+
+  return make_qualified_type (type, new_flags, NULL);
+}
 
 /* Make a "c-v" variant of a type -- a type that is identical to the
    one supplied except that it may have const or volatile attributes
@@ -425,142 +490,60 @@ make_cv_type (int cnst, int voltl, struc
   register struct type *tmp_type = type;	/* tmp type */
   struct objfile *objfile;
 
-  ntype = TYPE_CV_TYPE (type);
-
-  while (ntype != type)
-    {
-      if ((TYPE_CONST (ntype) == cnst) &&
-	  (TYPE_VOLATILE (ntype) == voltl))
-	{
-	  if (typeptr == 0)
-	    return ntype;
-	  else if (*typeptr == 0)
-	    {
-	      *typeptr = ntype;	/* Tracking alloc, and we have new type.  */
-	      return ntype;
-	    }
-	}
-      tmp_type = ntype;
-      ntype = TYPE_CV_TYPE (ntype);
-    }
-
-  if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
-    {
-      ntype = alloc_type (TYPE_OBJFILE (type));
-      if (typeptr)
-	*typeptr = ntype;
-    }
-  else
-    /* We have storage, but need to reset it.  */
-    {
-      ntype = *typeptr;
-      objfile = TYPE_OBJFILE (ntype);
-      /* memset ((char *) ntype, 0, sizeof (struct type)); */
-      TYPE_OBJFILE (ntype) = objfile;
-    }
-
-  /* Copy original type */
-  memcpy ((char *) ntype, (char *) type, sizeof (struct type));
-  /* But zero out fields that shouldn't be copied */
-  TYPE_POINTER_TYPE (ntype) = (struct type *) 0;	/* Need new pointer kind */
-  TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;	/* Need new referene kind */
-  TYPE_AS_TYPE (ntype) = ntype;		/* Need new address-space kind. */
-  /* Note: TYPE_TARGET_TYPE can be left as is */
+  int new_flags = (TYPE_INSTANCE_FLAGS (type)
+		   & ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE));
 
-  /* Set flags appropriately */
   if (cnst)
-    TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST;
-  else
-    TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST;
+    new_flags |= TYPE_FLAG_CONST;
 
   if (voltl)
-    TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE;
-  else
-    TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE;
-
-  /* Fix the chain of cv variants */
-  TYPE_CV_TYPE (ntype) = type;
-  TYPE_CV_TYPE (tmp_type) = ntype;
-
-  return ntype;
-}
-
-/* When reading in a class type, we may have created references to
-   cv-qualified versions of the type (in method arguments, for
-   instance).  Update everything on the cv ring from the primary
-   type TYPE.
-
-   The only reason we do not need to do the same thing for address
-   spaces is that type readers do not create address space qualified
-   types.  */
-void
-finish_cv_type (struct type *type)
-{
-  struct type *ntype, *cv_type, *ptr_type, *ref_type;
-  int cv_flags;
+    new_flags |= TYPE_FLAG_VOLATILE;
 
-  gdb_assert (!TYPE_CONST (type) && !TYPE_VOLATILE (type));
-
-  ntype = type;
-  while ((ntype = TYPE_CV_TYPE (ntype)) != type)
+  if (typeptr && *typeptr != NULL)
     {
-      /* Save cv_flags.  */
-      cv_flags = TYPE_FLAGS (ntype) & (TYPE_FLAG_VOLATILE | TYPE_FLAG_CONST);
-
-      /* If any reference or pointer types were created, save them too.  */
-      ptr_type = TYPE_POINTER_TYPE (ntype);
-      ref_type = TYPE_REFERENCE_TYPE (ntype);
-
-      /* Don't disturb the CV chain.  */
-      cv_type = TYPE_CV_TYPE (ntype);
-
-      /* Verify that we haven't added any address-space qualified types,
-	 for the future.  */
-      gdb_assert (ntype == TYPE_AS_TYPE (ntype));
-
-      /* Copy original type */
-      memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+      /* Objfile is per-core-type.  This const-qualified type had best
+	 belong to the same objfile as the type it is qualifying, unless
+	 we are overwriting a stub type, in which case the safest thing
+	 to do is to copy the core type into the new objfile.  */
+
+      gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)
+		  || TYPE_STUB (*typeptr));
+      if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type))
+	{
+	  TYPE_MAIN_TYPE (*typeptr)
+	    = TYPE_ALLOC (*typeptr, sizeof (struct main_type));
+	  *TYPE_MAIN_TYPE (*typeptr)
+	    = *TYPE_MAIN_TYPE (type);
+	}
+    }
+  
+  ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL);
 
-      /* Restore everything.  */
-      TYPE_POINTER_TYPE (ntype) = ptr_type;
-      TYPE_REFERENCE_TYPE (ntype) = ref_type;
-      TYPE_CV_TYPE (ntype) = cv_type;
-      TYPE_FLAGS (ntype) = TYPE_FLAGS (ntype) | cv_flags;
+  if (typeptr != NULL)
+    *typeptr = ntype;
 
-      TYPE_AS_TYPE (ntype) = ntype;
-    }
+  return ntype;
 }
 
-/* Replace the contents of ntype with the type *type.
+/* Replace the contents of ntype with the type *type.  This changes the
+   contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
+   the changes are propogated to all types in the TYPE_CHAIN.
 
    In order to build recursive types, it's inevitable that we'll need
    to update types in place --- but this sort of indiscriminate
    smashing is ugly, and needs to be replaced with something more
-   controlled.  For example, Daniel Jacobowitz has suggested moving
-   the fields common to a set of c/v variants into their own object,
-   which the variants would share.
-
-   This function does not handle the replacement type being
-   cv-qualified; it could be easily fixed to, but it would be better
-   to just change the whole approach.  */
+   controlled.  TYPE_MAIN_TYPE is a step in this direction; it's not
+   clear if more steps are needed.  */
 void
 replace_type (struct type *ntype, struct type *type)
 {
   struct type *cv_chain, *as_chain, *ptr, *ref;
 
-  cv_chain = TYPE_CV_TYPE (ntype);
-  as_chain = TYPE_AS_TYPE (ntype);
-  ptr = TYPE_POINTER_TYPE (ntype);
-  ref = TYPE_REFERENCE_TYPE (ntype);
-
-  *ntype = *type;
-
-  TYPE_POINTER_TYPE (ntype) = ptr;
-  TYPE_REFERENCE_TYPE (ntype) = ref;
-  TYPE_CV_TYPE (ntype) = cv_chain;
-  TYPE_AS_TYPE (ntype) = as_chain;
+  *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
 
-  finish_cv_type (ntype);
+  /* Assert that the two types have equivalent instance qualifiers.
+     This should be true for at least all of our debug readers.  */
+  gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type));
 }
 
 /* Implement direct support for MEMBER_TYPE in GNU C++.
@@ -879,7 +862,7 @@ smash_to_member_type (struct type *type,
 
   objfile = TYPE_OBJFILE (type);
 
-  memset ((char *) type, 0, sizeof (struct type));
+  smash_type (type);
   TYPE_OBJFILE (type) = objfile;
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
@@ -902,7 +885,7 @@ smash_to_method_type (struct type *type,
 
   objfile = TYPE_OBJFILE (type);
 
-  memset ((char *) type, 0, sizeof (struct type));
+  smash_type (type);
   TYPE_OBJFILE (type) = objfile;
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
@@ -3011,12 +2994,27 @@ recursive_dump_type (struct type *type, 
   printfi_filtered (spaces, "reference_type ");
   gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
   printf_filtered ("\n");
-  printfi_filtered (spaces, "cv_type ");
-  gdb_print_host_address (TYPE_CV_TYPE (type), gdb_stdout);
-  printf_filtered ("\n");
-  printfi_filtered (spaces, "as_type ");
-  gdb_print_host_address (TYPE_AS_TYPE (type), gdb_stdout);
+  printfi_filtered (spaces, "type_chain ");
+  gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout);
   printf_filtered ("\n");
+  printfi_filtered (spaces, "instance_flags 0x%x", TYPE_INSTANCE_FLAGS (type));
+  if (TYPE_CONST (type))
+    {
+      puts_filtered (" TYPE_FLAG_CONST");
+    }
+  if (TYPE_VOLATILE (type))
+    {
+      puts_filtered (" TYPE_FLAG_VOLATILE");
+    }
+  if (TYPE_CODE_SPACE (type))
+    {
+      puts_filtered (" TYPE_FLAG_CODE_SPACE");
+    }
+  if (TYPE_DATA_SPACE (type))
+    {
+      puts_filtered (" TYPE_FLAG_DATA_SPACE");
+    }
+  puts_filtered ("\n");
   printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
   if (TYPE_UNSIGNED (type))
     {
@@ -3038,14 +3036,6 @@ recursive_dump_type (struct type *type, 
     {
       puts_filtered (" TYPE_FLAG_STATIC");
     }
-  if (TYPE_CONST (type))
-    {
-      puts_filtered (" TYPE_FLAG_CONST");
-    }
-  if (TYPE_VOLATILE (type))
-    {
-      puts_filtered (" TYPE_FLAG_VOLATILE");
-    }
   if (TYPE_PROTOTYPED (type))
     {
       puts_filtered (" TYPE_FLAG_PROTOTYPED");
@@ -3053,14 +3043,6 @@ recursive_dump_type (struct type *type, 
   if (TYPE_INCOMPLETE (type))
     {
       puts_filtered (" TYPE_FLAG_INCOMPLETE");
-    }
-  if (TYPE_CODE_SPACE (type))
-    {
-      puts_filtered (" TYPE_FLAG_CODE_SPACE");
-    }
-  if (TYPE_DATA_SPACE (type))
-    {
-      puts_filtered (" TYPE_FLAG_DATA_SPACE");
     }
   if (TYPE_VARARGS (type))
     {
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.29
diff -u -p -r1.29 gdbtypes.h
--- gdbtypes.h	13 May 2002 14:21:12 -0000	1.29
+++ gdbtypes.h	14 May 2002 18:25:36 -0000
@@ -187,14 +187,14 @@ enum type_code
  */
 
 #define TYPE_FLAG_CONST		(1 << 5)
-#define TYPE_CONST(t)		(TYPE_FLAGS (t) & TYPE_FLAG_CONST)
+#define TYPE_CONST(t)		(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CONST)
 
 /* Volatile type.  If this is set, the corresponding type has a
  * volatile modifier.
  */
 
 #define TYPE_FLAG_VOLATILE	(1 << 6)
-#define TYPE_VOLATILE(t)	(TYPE_FLAGS (t) & TYPE_FLAG_VOLATILE)
+#define TYPE_VOLATILE(t)	(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_VOLATILE)
 
 
 /* This is a function type which appears to have a prototype.  We need this
@@ -235,10 +235,10 @@ enum type_code
    is instruction space, and for data objects is data memory.  */
 
 #define TYPE_FLAG_CODE_SPACE	(1 << 9)
-#define TYPE_CODE_SPACE(t)	(TYPE_FLAGS (t) & TYPE_FLAG_CODE_SPACE)
+#define TYPE_CODE_SPACE(t)	(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CODE_SPACE)
 
 #define TYPE_FLAG_DATA_SPACE	(1 << 10)
-#define TYPE_DATA_SPACE(t)	(TYPE_FLAGS (t) & TYPE_FLAG_DATA_SPACE)
+#define TYPE_DATA_SPACE(t)	(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_DATA_SPACE)
 
 /* FIXME: Kludge to mark a varargs function type for C++ member
    function argument processing.  Currently only used in dwarf2read.c,
@@ -254,238 +254,240 @@ enum type_code
 #define TYPE_FLAG_VECTOR	(1 << 12)
 #define TYPE_VECTOR(t)		(TYPE_FLAGS (t) & TYPE_FLAG_VECTOR)
 
+struct main_type
+{
+  /* Code for kind of type */
+
+  enum type_code code;
+
+  /* Name of this type, or NULL if none.
+
+     This is used for printing only, except by poorly designed C++ code.
+     For looking up a name, look for a symbol in the VAR_NAMESPACE.  */
+
+  char *name;
+
+  /* Tag name for this type, or NULL if none.  This means that the
+     name of the type consists of a keyword followed by the tag name.
+     Which keyword is determined by the type code ("struct" for
+     TYPE_CODE_STRUCT, etc.).  As far as I know C/C++ are the only languages
+     with this feature.
+
+     This is used for printing only, except by poorly designed C++ code.
+     For looking up a name, look for a symbol in the STRUCT_NAMESPACE.
+     One more legitimate use is that if TYPE_FLAG_STUB is set, this is
+     the name to use to look for definitions in other files.  */
+
+  char *tag_name;
+
+  /* Length of storage for a value of this type.  This is what
+     sizeof(type) would return; use it for address arithmetic,
+     memory reads and writes, etc.  This size includes padding.  For
+     example, an i386 extended-precision floating point value really
+     only occupies ten bytes, but most ABI's declare its size to be
+     12 bytes, to preserve alignment.  A `struct type' representing
+     such a floating-point type would have a `length' value of 12,
+     even though the last two bytes are unused.
+
+     There's a bit of a host/target mess here, if you're concerned
+     about machines whose bytes aren't eight bits long, or who don't
+     have byte-addressed memory.  Various places pass this to memcpy
+     and such, meaning it must be in units of host bytes.  Various
+     other places expect they can calculate addresses by adding it
+     and such, meaning it must be in units of target bytes.  For
+     some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8
+     and TARGET_CHAR_BIT will be (say) 32, this is a problem.
+
+     One fix would be to make this field in bits (requiring that it
+     always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) ---
+     the other choice would be to make it consistently in units of
+     HOST_CHAR_BIT.  However, this would still fail to address
+     machines based on a ternary or decimal representation.  */
+  
+  unsigned length;
 
-struct type
-  {
-
-    /* Code for kind of type */
-
-    enum type_code code;
-
-    /* Name of this type, or NULL if none.
-
-       This is used for printing only, except by poorly designed C++ code.
-       For looking up a name, look for a symbol in the VAR_NAMESPACE.  */
-
-    char *name;
-
-    /* Tag name for this type, or NULL if none.  This means that the
-       name of the type consists of a keyword followed by the tag name.
-       Which keyword is determined by the type code ("struct" for
-       TYPE_CODE_STRUCT, etc.).  As far as I know C/C++ are the only languages
-       with this feature.
-
-       This is used for printing only, except by poorly designed C++ code.
-       For looking up a name, look for a symbol in the STRUCT_NAMESPACE.
-       One more legitimate use is that if TYPE_FLAG_STUB is set, this is
-       the name to use to look for definitions in other files.  */
-
-    char *tag_name;
-
-    /* Length of storage for a value of this type.  This is what
-       sizeof(type) would return; use it for address arithmetic,
-       memory reads and writes, etc.  This size includes padding.  For
-       example, an i386 extended-precision floating point value really
-       only occupies ten bytes, but most ABI's declare its size to be
-       12 bytes, to preserve alignment.  A `struct type' representing
-       such a floating-point type would have a `length' value of 12,
-       even though the last two bytes are unused.
-
-       There's a bit of a host/target mess here, if you're concerned
-       about machines whose bytes aren't eight bits long, or who don't
-       have byte-addressed memory.  Various places pass this to memcpy
-       and such, meaning it must be in units of host bytes.  Various
-       other places expect they can calculate addresses by adding it
-       and such, meaning it must be in units of target bytes.  For
-       some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8
-       and TARGET_CHAR_BIT will be (say) 32, this is a problem.
-
-       One fix would be to make this field in bits (requiring that it
-       always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) ---
-       the other choice would be to make it consistently in units of
-       HOST_CHAR_BIT.  However, this would still fail to address
-       machines based on a ternary or decimal representation.  */
-    unsigned length;
-
-    /* FIXME, these should probably be restricted to a Fortran-specific
-       field in some fashion.  */
+  /* FIXME, these should probably be restricted to a Fortran-specific
+     field in some fashion.  */
 #define BOUND_CANNOT_BE_DETERMINED   5
 #define BOUND_BY_REF_ON_STACK        4
 #define BOUND_BY_VALUE_ON_STACK      3
 #define BOUND_BY_REF_IN_REG          2
 #define BOUND_BY_VALUE_IN_REG        1
 #define BOUND_SIMPLE                 0
-    int upper_bound_type;
-    int lower_bound_type;
-
-    /* Every type is now associated with a particular objfile, and the
-       type is allocated on the type_obstack for that objfile.  One problem
-       however, is that there are times when gdb allocates new types while
-       it is not in the process of reading symbols from a particular objfile.
-       Fortunately, these happen when the type being created is a derived
-       type of an existing type, such as in lookup_pointer_type().  So
-       we can just allocate the new type using the same objfile as the
-       existing type, but to do this we need a backpointer to the objfile
-       from the existing type.  Yes this is somewhat ugly, but without
-       major overhaul of the internal type system, it can't be avoided
-       for now. */
-
-    struct objfile *objfile;
-
-    /* For a pointer type, describes the type of object pointed to.
-       For an array type, describes the type of the elements.
-       For a function or method type, describes the type of the return value.
-       For a range type, describes the type of the full range.
-       For a complex type, describes the type of each coordinate.
-       Unused otherwise.  */
-
-    struct type *target_type;
-
-    /* Type that is a pointer to this type.
-       NULL if no such pointer-to type is known yet.
-       The debugger may add the address of such a type
-       if it has to construct one later.  */
-
-    struct type *pointer_type;
-
-    /* C++: also need a reference type.  */
-
-    struct type *reference_type;
-
-    /* C-v variant chain. This points to a type that
-       differs from this one only in a const or volatile
-       attribute (or both). The various c-v variants
-       are chained together in a ring. */
-    struct type *cv_type;
-
-    /* Address-space delimited variant chain.  This points to a type
-       that differs from this one only in an address-space qualifier
-       attribute.  The otherwise-identical address-space delimited 
-       types are chained together in a ring. */
-    struct type *as_type;
-
-    /* Flags about this type.  */
-
-    int flags;
-
-    /* Number of fields described for this type */
-
-    short nfields;
-
-    /* For structure and union types, a description of each field.
-       For set and pascal array types, there is one "field",
-       whose type is the domain type of the set or array.
-       For range types, there are two "fields",
-       the minimum and maximum values (both inclusive).
-       For enum types, each possible value is described by one "field".
-       For a function type, a "field" for each parameter type.
-       For C++ classes, there is one field for each base class (if it is
-       a derived class) plus one field for each class data member.  Member
-       functions are recorded elsewhere.
-
-       Using a pointer to a separate array of fields
-       allows all types to have the same size, which is useful
-       because we can allocate the space for a type before
-       we know what to put in it.  */
-
-    struct field
-      {
-	union field_location
-	  {
-	    /* Position of this field, counting in bits from start of
-	       containing structure.
-	       For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
-	       For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
-	       For a range bound or enum value, this is the value itself. */
-
-	    int bitpos;
-
-	    /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr
-	       is the location (in the target) of the static field.
-	       Otherwise, physname is the mangled label of the static field. */
-
-	    CORE_ADDR physaddr;
-	    char *physname;
+  int upper_bound_type;
+  int lower_bound_type;
 
-	    /* For a function type, this is 1 if the argument is marked
-	       artificial.  Artificial arguments should not be shown to the
-	       user.  */
-	    int artificial;
-	  }
-	loc;
+  /* Every type is now associated with a particular objfile, and the
+     type is allocated on the type_obstack for that objfile.  One problem
+     however, is that there are times when gdb allocates new types while
+     it is not in the process of reading symbols from a particular objfile.
+     Fortunately, these happen when the type being created is a derived
+     type of an existing type, such as in lookup_pointer_type().  So
+     we can just allocate the new type using the same objfile as the
+     existing type, but to do this we need a backpointer to the objfile
+     from the existing type.  Yes this is somewhat ugly, but without
+     major overhaul of the internal type system, it can't be avoided
+     for now. */
+
+  struct objfile *objfile;
+
+  /* For a pointer type, describes the type of object pointed to.
+     For an array type, describes the type of the elements.
+     For a function or method type, describes the type of the return value.
+     For a range type, describes the type of the full range.
+     For a complex type, describes the type of each coordinate.
+     Unused otherwise.  */
+
+  struct type *target_type;
+
+  /* Flags about this type.  */
+
+  int flags;
+
+  /* Number of fields described for this type */
+
+  short nfields;
+
+  /* For structure and union types, a description of each field.
+     For set and pascal array types, there is one "field",
+     whose type is the domain type of the set or array.
+     For range types, there are two "fields",
+     the minimum and maximum values (both inclusive).
+     For enum types, each possible value is described by one "field".
+     For a function type, a "field" for each parameter type.
+     For C++ classes, there is one field for each base class (if it is
+     a derived class) plus one field for each class data member.  Member
+     functions are recorded elsewhere.
+
+     Using a pointer to a separate array of fields
+     allows all types to have the same size, which is useful
+     because we can allocate the space for a type before
+     we know what to put in it.  */
 
-	/* Size of this field, in bits, or zero if not packed.
-	   For an unpacked field, the field's type's length
-	   says how many bytes the field occupies.
-	   A value of -1 or -2 indicates a static field;  -1 means the location
-	   is specified by the label loc.physname;  -2 means that loc.physaddr
-	   specifies the actual address. */
-
-	int bitsize;
-
-	/* In a struct or union type, type of this field.
-	   In a function type, type of this argument.
-	   In an array type, the domain-type of the array.  */
-
-	struct type *type;
-
-	/* Name of field, value or argument.
-	   NULL for range bounds and array domains.  */
-
-	char *name;
-
-      }
-     *fields;
-
-    /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
-       is the base class which defined the virtual function table pointer.  
+  struct field
+  {
+    union field_location
+    {
+      /* Position of this field, counting in bits from start of
+	 containing structure.
+	 For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
+	 For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
+	 For a range bound or enum value, this is the value itself. */
+
+      int bitpos;
+
+      /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr
+	 is the location (in the target) of the static field.
+	 Otherwise, physname is the mangled label of the static field. */
+
+      CORE_ADDR physaddr;
+      char *physname;
+
+      /* For a function type, this is 1 if the argument is marked
+	 artificial.  Artificial arguments should not be shown to the
+	 user.  */
+      int artificial;
+    }
+    loc;
+
+    /* Size of this field, in bits, or zero if not packed.
+       For an unpacked field, the field's type's length
+       says how many bytes the field occupies.
+       A value of -1 or -2 indicates a static field;  -1 means the location
+       is specified by the label loc.physname;  -2 means that loc.physaddr
+       specifies the actual address. */
+
+    int bitsize;
+
+    /* In a struct or union type, type of this field.
+       In a function type, type of this argument.
+       In an array type, the domain-type of the array.  */
 
-       For types that are pointer to member types (TYPE_CODE_MEMBER),
-       VPTR_BASETYPE is the type that this pointer is a member of.
+    struct type *type;
 
-       For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate
-       type that contains the method.
+    /* Name of field, value or argument.
+       NULL for range bounds and array domains.  */
 
-       Unused otherwise.  */
+    char *name;
 
-    struct type *vptr_basetype;
+  } *fields;
 
-    /* Field number of the virtual function table pointer in
-       VPTR_BASETYPE.  If -1, we were unable to find the virtual
-       function table pointer in initial symbol reading, and
-       fill_in_vptr_fieldno should be called to find it if possible.
+  /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
+     is the base class which defined the virtual function table pointer.  
 
-       Unused if this type does not have virtual functions.  */
+     For types that are pointer to member types (TYPE_CODE_MEMBER),
+     VPTR_BASETYPE is the type that this pointer is a member of.
 
-    int vptr_fieldno;
+     For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate
+     type that contains the method.
 
-    /* Slot to point to additional language-specific fields of this type.  */
+     Unused otherwise.  */
 
-    union type_specific
-      {
+  struct type *vptr_basetype;
 
-	/* ARG_TYPES is for TYPE_CODE_METHOD.
-	   Contains the type of each argument, ending with a void type
-	   after the last argument for normal member functions or a NULL
-	   pointer after the last argument for functions with variable
-	   arguments.  */
+  /* Field number of the virtual function table pointer in
+     VPTR_BASETYPE.  If -1, we were unable to find the virtual
+     function table pointer in initial symbol reading, and
+     fill_in_vptr_fieldno should be called to find it if possible.
 
-	struct type **arg_types;
+     Unused if this type does not have virtual functions.  */
 
-	/* CPLUS_STUFF is for TYPE_CODE_STRUCT.  It is initialized to point to
-	   cplus_struct_default, a default static instance of a struct
-	   cplus_struct_type. */
+  int vptr_fieldno;
 
-	struct cplus_struct_type *cplus_stuff;
+  /* Slot to point to additional language-specific fields of this type.  */
 
-	/* FLOATFORMAT is for TYPE_CODE_FLT.  It is a pointer to the
-           floatformat object that describes the floating-point value
-           that resides within the type.  */
+  union type_specific
+  {
+    /* ARG_TYPES is for TYPE_CODE_METHOD.
+       Contains the type of each argument, ending with a void type
+       after the last argument for normal member functions or a NULL
+       pointer after the last argument for functions with variable
+       arguments.  */
+
+    struct type **arg_types;
+
+    /* CPLUS_STUFF is for TYPE_CODE_STRUCT.  It is initialized to point to
+       cplus_struct_default, a default static instance of a struct
+       cplus_struct_type. */
+
+    struct cplus_struct_type *cplus_stuff;
+
+    /* FLOATFORMAT is for TYPE_CODE_FLT.  It is a pointer to the
+       floatformat object that describes the floating-point value
+       that resides within the type.  */
+
+    const struct floatformat *floatformat;
+  } type_specific;
+};
 
-	const struct floatformat *floatformat;
-      }
-    type_specific;
-  };
+/* A ``struct type'' describes a particular instance of a type, with
+   some particular qualification.  */
+struct type
+{
+  /* Type that is a pointer to this type.
+     NULL if no such pointer-to type is known yet.
+     The debugger may add the address of such a type
+     if it has to construct one later.  */
+
+  struct type *pointer_type;
+
+  /* C++: also need a reference type.  */
+
+  struct type *reference_type;
+
+  /* Variant chain.  This points to a type that differs from this one only
+     in qualifiers.  Currently, the possible qualifiers are const, volatile,
+     code-space, and data-space.  The variants are linked in a circular
+     ring and share MAIN_TYPE.  */
+  struct type *chain;
+
+  /* Flags specific to this instance of the type, indicating where
+     on the ring we are.  */
+  int instance_flags;
+
+  /* Core type, shared by a group of qualified types.  */
+  struct main_type *main_type;
+};
 
 #define	NULL_TYPE ((struct type *) 0)
 
@@ -738,25 +740,26 @@ extern void allocate_cplus_struct_type (
 #define HAVE_CPLUS_STRUCT(type) \
   (TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default)
 
-#define TYPE_NAME(thistype) (thistype)->name
-#define TYPE_TAG_NAME(type) ((type)->tag_name)
-#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type
+#define TYPE_INSTANCE_FLAGS(thistype) (thistype)->instance_flags
+#define TYPE_MAIN_TYPE(thistype) (thistype)->main_type
+#define TYPE_NAME(thistype) TYPE_MAIN_TYPE(thistype)->name
+#define TYPE_TAG_NAME(type) TYPE_MAIN_TYPE(type)->tag_name
+#define TYPE_TARGET_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->target_type
 #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
 #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
-#define TYPE_CV_TYPE(thistype) (thistype)->cv_type
-#define TYPE_AS_TYPE(thistype) (thistype)->as_type
+#define TYPE_CHAIN(thistype) (thistype)->chain
 /* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
    But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
    so you only have to call check_typedef once.  Since allocate_value
    calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe.  */
-#define TYPE_LENGTH(thistype) (thistype)->length
-#define TYPE_OBJFILE(thistype) (thistype)->objfile
-#define TYPE_FLAGS(thistype) (thistype)->flags
+#define TYPE_LENGTH(thistype) TYPE_MAIN_TYPE(thistype)->length
+#define TYPE_OBJFILE(thistype) TYPE_MAIN_TYPE(thistype)->objfile
+#define TYPE_FLAGS(thistype) TYPE_MAIN_TYPE(thistype)->flags
 /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
    type, you need to do TYPE_CODE (check_type (this_type)). */
-#define TYPE_CODE(thistype) (thistype)->code
-#define TYPE_NFIELDS(thistype) (thistype)->nfields
-#define TYPE_FIELDS(thistype) (thistype)->fields
+#define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
+#define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields
+#define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields
 #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args
 #define TYPE_INSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->instantiations
 
@@ -766,8 +769,10 @@ extern void allocate_cplus_struct_type (
 
 /* Moto-specific stuff for FORTRAN arrays */
 
-#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) (thistype)->upper_bound_type
-#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) (thistype)->lower_bound_type
+#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) \
+	TYPE_MAIN_TYPE(thistype)->upper_bound_type
+#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) \
+	TYPE_MAIN_TYPE(thistype)->lower_bound_type
 
 #define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
    (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),1))
@@ -777,22 +782,22 @@ extern void allocate_cplus_struct_type (
 
 /* C++ */
 
-#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype
-#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype
-#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno
+#define TYPE_VPTR_BASETYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype
+#define TYPE_DOMAIN_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype
+#define TYPE_VPTR_FIELDNO(thistype) TYPE_MAIN_TYPE(thistype)->vptr_fieldno
 #define TYPE_FN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fields
 #define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields
 #define TYPE_NFN_FIELDS_TOTAL(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields_total
 #define TYPE_NTEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ntemplate_args
 #define TYPE_NINSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ninstantiations
 #define TYPE_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type
-#define	TYPE_TYPE_SPECIFIC(thistype) (thistype)->type_specific
-#define TYPE_ARG_TYPES(thistype) (thistype)->type_specific.arg_types
-#define TYPE_CPLUS_SPECIFIC(thistype) (thistype)->type_specific.cplus_stuff
-#define TYPE_FLOATFORMAT(thistype) (thistype)->type_specific.floatformat
-#define TYPE_BASECLASS(thistype,index) (thistype)->fields[index].type
+#define	TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific
+#define TYPE_ARG_TYPES(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.arg_types
+#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
+#define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
+#define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type
 #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
-#define TYPE_BASECLASS_NAME(thistype,index) (thistype)->fields[index].name
+#define TYPE_BASECLASS_NAME(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].name
 #define TYPE_BASECLASS_BITPOS(thistype,index) TYPE_FIELD_BITPOS(thistype,index)
 #define BASETYPE_VIA_PUBLIC(thistype, index) \
   ((!TYPE_FIELD_PRIVATE(thistype, index)) && (!TYPE_FIELD_PROTECTED(thistype, index)))
@@ -812,7 +817,7 @@ extern void allocate_cplus_struct_type (
   ((thisfld).bitsize = -1, FIELD_PHYSNAME(thisfld) = (name))
 #define SET_FIELD_PHYSADDR(thisfld, name) \
   ((thisfld).bitsize = -2, FIELD_PHYSADDR(thisfld) = (name))
-#define TYPE_FIELD(thistype, n) (thistype)->fields[n]
+#define TYPE_FIELD(thistype, n) TYPE_MAIN_TYPE(thistype)->fields[n]
 #define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n))
 #define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n))
 #define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS(TYPE_FIELD(thistype,n))
@@ -851,8 +856,8 @@ extern void allocate_cplus_struct_type (
   (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
     : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)))
 
-#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitsize < 0)
-#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) ((thistype)->fields[n].bitsize == -2)
+#define TYPE_FIELD_STATIC(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].bitsize < 0)
+#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].bitsize == -2)
 #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n))
 #define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_PHYSADDR(TYPE_FIELD(thistype, n))
 
@@ -1076,8 +1081,6 @@ extern struct type *lookup_reference_typ
 extern struct type *make_reference_type (struct type *, struct type **);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
-
-extern void finish_cv_type (struct type *);
 
 extern void replace_type (struct type *, struct type *);
 
Index: hpread.c
===================================================================
RCS file: /cvs/src/src/gdb/hpread.c,v
retrieving revision 1.18
diff -u -p -r1.18 hpread.c
--- hpread.c	13 May 2002 14:00:36 -0000	1.18
+++ hpread.c	14 May 2002 18:25:38 -0000
@@ -4403,9 +4403,6 @@ hpread_read_struct_type (dnttpointer hp_
   /* Clear the global saying what template we are in the middle of processing */
   current_template = NULL;
 
-  /* Fix up any cv-qualified versions of this type.  */
-  finish_cv_type (type);
-
   return type;
 }
 
Index: stabsread.c
===================================================================
RCS file: /cvs/src/src/gdb/stabsread.c,v
retrieving revision 1.33
diff -u -p -r1.33 stabsread.c
--- stabsread.c	9 May 2002 18:11:17 -0000	1.33
+++ stabsread.c	14 May 2002 18:25:40 -0000
@@ -4302,8 +4302,6 @@ read_struct_type (char **pp, struct type
       type = error_type (pp, objfile);
     }
 
-  /* Fix up any cv-qualified versions of this type.  */
-  finish_cv_type (type);
   do_cleanups (back_to);
   return (type);
 }
Index: testsuite/gdb.base/maint.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/maint.exp,v
retrieving revision 1.12
diff -u -p -r1.12 maint.exp
--- testsuite/gdb.base/maint.exp	18 Apr 2002 22:17:01 -0000	1.12
+++ testsuite/gdb.base/maint.exp	14 May 2002 18:25:44 -0000
@@ -345,7 +345,7 @@ set timeout $old_timeout
 
 send_gdb "maint print type argc\n"
 gdb_expect  {
-        -re "type node $hex\r\nname .int. \\($hex\\)\r\ntagname .<NULL>. \\($hex\\)\r\ncode $hex \\(TYPE_CODE_INT\\)\r\nlength \[24\]\r\nupper_bound_type $hex \\(BOUND_SIMPLE\\)\r\nlower_bound_type $hex \\(BOUND_SIMPLE\\)\r\nobjfile $hex\r\ntarget_type $hex\r\npointer_type $hex\r\nreference_type $hex\r\ncv_type $hex\r\nas_type $hex\r\nflags $hex\r\nnfields 0 $hex\r\nvptr_basetype $hex\r\nvptr_fieldno -1\r\ntype_specific $hex\r\n$gdb_prompt $"\
+        -re "type node $hex\r\nname .int. \\($hex\\)\r\ntagname .<NULL>. \\($hex\\)\r\ncode $hex \\(TYPE_CODE_INT\\)\r\nlength \[24\]\r\nupper_bound_type $hex \\(BOUND_SIMPLE\\)\r\nlower_bound_type $hex \\(BOUND_SIMPLE\\)\r\nobjfile $hex\r\ntarget_type $hex\r\npointer_type $hex\r\nreference_type $hex\r\ntype_chain $hex\r\ninstance_flags $hex\r\nflags $hex\r\nnfields 0 $hex\r\nvptr_basetype $hex\r\nvptr_fieldno -1\r\ntype_specific $hex\r\n$gdb_prompt $"\
                         { pass "maint print type" }
         -re ".*$gdb_prompt $"       { fail "maint print type" }
         timeout         { fail "(timeout) maint print type" }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]