This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA] Fix gdb/277 by separating types, take 3
- From: Elena Zannoni <ezannoni at redhat dot com>
- To: Daniel Jacobowitz <drow at mvista dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Mon, 13 May 2002 22:39:26 -0400
- Subject: Re: [RFA] Fix gdb/277 by separating types, take 3
- References: <20020513160257.GC19484@nevyn.them.org>
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.
Elena
Daniel Jacobowitz writes:
> Same as last time, with three new changes:
>
> - testsuite fix included for maint.exp
> - formatting bug in the code that maint.exp was testing fixed
> - Excess casts removed.
>
> Michael, I don't really see a need to retest this one; I verified
> carefully that the only changes were to casts (no new warnings) and to
> the one failing test. If you prefer to, of course, I won't complain :)
>
> Retested i386-linux, verified that all cross targets still build.
>
> --
> Daniel Jacobowitz Carnegie Mellon University
> MontaVista Software Debian GNU/Linux Developer
>
> 2002-05-13 Daniel Jacobowitz <drow@mvista.com>
>
> * gdbtypes.h: Update accessor macros to use TYPE_CORE_TYPE.
> (TYPE_CONST, TYPE_VOLATILE, TYPE_CODE_SPACE, TYPE_DATA_SPACE): Use
> TYPE_INSTANCE_FLAGS.
> (struct type_core): New.
> (struct type): Move most members to struct type_core. Change
> cv_type and as_type to new type_chain member. Add instance_flags.
> (TYPE_CORE_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_CORE_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_CORE_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-13 Daniel Jacobowitz <drow@mvista.com>
>
> * gdb.base/maint.exp (maint print type): Update for new type
> structure.
>
> diff -x CVS -x *.orig -pur gdb.real/c-typeprint.c gdb/c-typeprint.c
> --- gdb.real/c-typeprint.c Mon May 13 10:02:10 2002
> +++ gdb/c-typeprint.c Mon May 13 10:09:50 2002
> @@ -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)
> diff -x CVS -x *.orig -pur gdb.real/dwarf2read.c gdb/dwarf2read.c
> --- gdb.real/dwarf2read.c Sun May 12 21:00:28 2002
> +++ gdb/dwarf2read.c Sun May 12 22:26:22 2002
> @@ -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
> diff -x CVS -x *.orig -pur gdb.real/gdbtypes.c gdb/gdbtypes.c
> --- gdb.real/gdbtypes.c Mon May 13 10:02:11 2002
> +++ gdb/gdbtypes.c Mon May 13 10:09:53 2002
> @@ -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_CORE_TYPE (type) = xmalloc (sizeof (struct type_core));
> }
> 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_CORE_TYPE (type) = obstack_alloc (&objfile->type_obstack,
> + sizeof (struct type_core));
> OBJSTAT (objfile, n_types++);
> }
> - memset ((char *) type, 0, sizeof (struct type));
> + memset (TYPE_CORE_TYPE (type), 0, sizeof (struct type_core));
>
> /* 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_CORE_TYPE (type) = TYPE_CORE_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_CORE_TYPE (type), 0, sizeof (struct type_core));
> +
> + /* 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_CORE_TYPE (ntype) = TYPE_CORE_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_CORE_TYPE (*typeptr)
> + = TYPE_ALLOC (*typeptr, sizeof (struct type_core));
> + *TYPE_CORE_TYPE (*typeptr)
> + = *TYPE_CORE_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_CORE_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_CORE_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_CORE_TYPE (ntype) = *TYPE_CORE_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))
> {
> diff -x CVS -x *.orig -pur gdb.real/gdbtypes.h gdb/gdbtypes.h
> --- gdb.real/gdbtypes.h Mon May 13 10:20:46 2002
> +++ gdb/gdbtypes.h Sun May 12 22:26:22 2002
> @@ -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 type_core
> +{
> + /* 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 CORE_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 type_core *core_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_CORE_TYPE(thistype) (thistype)->core_type
> +#define TYPE_NAME(thistype) TYPE_CORE_TYPE(thistype)->name
> +#define TYPE_TAG_NAME(type) TYPE_CORE_TYPE(type)->tag_name
> +#define TYPE_TARGET_TYPE(thistype) TYPE_CORE_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_CORE_TYPE(thistype)->length
> +#define TYPE_OBJFILE(thistype) TYPE_CORE_TYPE(thistype)->objfile
> +#define TYPE_FLAGS(thistype) TYPE_CORE_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_CORE_TYPE(thistype)->code
> +#define TYPE_NFIELDS(thistype) TYPE_CORE_TYPE(thistype)->nfields
> +#define TYPE_FIELDS(thistype) TYPE_CORE_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_CORE_TYPE(thistype)->upper_bound_type
> +#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) \
> + TYPE_CORE_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_CORE_TYPE(thistype)->vptr_basetype
> +#define TYPE_DOMAIN_TYPE(thistype) TYPE_CORE_TYPE(thistype)->vptr_basetype
> +#define TYPE_VPTR_FIELDNO(thistype) TYPE_CORE_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_CORE_TYPE(thistype)->type_specific
> +#define TYPE_ARG_TYPES(thistype) TYPE_CORE_TYPE(thistype)->type_specific.arg_types
> +#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_CORE_TYPE(thistype)->type_specific.cplus_stuff
> +#define TYPE_FLOATFORMAT(thistype) TYPE_CORE_TYPE(thistype)->type_specific.floatformat
> +#define TYPE_BASECLASS(thistype,index) TYPE_CORE_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_CORE_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_CORE_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_CORE_TYPE (thistype)->fields[n].bitsize < 0)
> +#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) (TYPE_CORE_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 *);
>
> diff -x CVS -x *.orig -pur gdb.real/hpread.c gdb/hpread.c
> --- gdb.real/hpread.c Mon May 13 10:02:11 2002
> +++ gdb/hpread.c Mon May 13 10:09:54 2002
> @@ -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;
> }
>
> diff -x CVS -x *.orig -pur gdb.real/stabsread.c gdb/stabsread.c
> --- gdb.real/stabsread.c Sun May 12 21:00:28 2002
> +++ gdb/stabsread.c Sun May 12 22:26:22 2002
> @@ -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);
> }
> diff -x CVS -x *.orig -pur gdb.real/testsuite/gdb.base/maint.exp gdb/testsuite/gdb.base/maint.exp
> --- gdb.real/testsuite/gdb.base/maint.exp Mon May 13 10:10:08 2002
> +++ gdb/testsuite/gdb.base/maint.exp Mon May 13 09:37:18 2002
> @@ -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" }