* [RFA] Fix gdb/277 by separating types, take 3
@ 2002-05-13 9:03 Daniel Jacobowitz
2002-05-13 19:40 ` Elena Zannoni
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2002-05-13 9:03 UTC (permalink / raw)
To: gdb-patches
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" }
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types, take 3
2002-05-13 9:03 [RFA] Fix gdb/277 by separating types, take 3 Daniel Jacobowitz
@ 2002-05-13 19:40 ` Elena Zannoni
2002-05-13 21:08 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Elena Zannoni @ 2002-05-13 19:40 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
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" }
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types, take 3
2002-05-13 19:40 ` Elena Zannoni
@ 2002-05-13 21:08 ` Daniel Jacobowitz
2002-05-14 8:24 ` Elena Zannoni
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2002-05-13 21:08 UTC (permalink / raw)
To: Elena Zannoni; +Cc: gdb-patches
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...
>
> 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" }
>
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types, take 3
2002-05-13 21:08 ` Daniel Jacobowitz
@ 2002-05-14 8:24 ` Elena Zannoni
2002-05-14 11:31 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Elena Zannoni @ 2002-05-14 8:24 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Elena Zannoni, gdb-patches
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.
Elena
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types, take 3
2002-05-14 8:24 ` Elena Zannoni
@ 2002-05-14 11:31 ` Daniel Jacobowitz
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Jacobowitz @ 2002-05-14 11:31 UTC (permalink / raw)
To: Elena Zannoni; +Cc: gdb-patches
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" }
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types, take 3
@ 2002-05-13 9:18 Michael Elizabeth Chastain
0 siblings, 0 replies; 6+ messages in thread
From: Michael Elizabeth Chastain @ 2002-05-13 9:18 UTC (permalink / raw)
To: drow, gdb-patches
I proofread the maint.exp part and it's fine with me.
> 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 :)
I agree, I feel comfortable without testing again (it gets tested
again on the next test run anyways).
Michael C
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2002-05-14 18:31 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-13 9:03 [RFA] Fix gdb/277 by separating types, take 3 Daniel Jacobowitz
2002-05-13 19:40 ` Elena Zannoni
2002-05-13 21:08 ` Daniel Jacobowitz
2002-05-14 8:24 ` Elena Zannoni
2002-05-14 11:31 ` Daniel Jacobowitz
2002-05-13 9:18 Michael Elizabeth Chastain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox