summaryrefslogtreecommitdiffstats
path: root/gdb/gdbtypes.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2002-05-14 18:30:53 +0000
committerDaniel Jacobowitz <drow@false.org>2002-05-14 18:30:53 +0000
commit2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a (patch)
tree903dab80e68aebe7f27ef803ce4da2bc9632eaed /gdb/gdbtypes.c
parente31f1a7cdb547636f561a24f6c2288228c3cf3a0 (diff)
downloadppe42-binutils-2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a.tar.gz
ppe42-binutils-2fdde8f831d0cf29d3de4baf7e8af19fa6cd638a.zip
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.
Diffstat (limited to 'gdb/gdbtypes.c')
-rw-r--r--gdb/gdbtypes.c318
1 files changed, 150 insertions, 168 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index fff720d483..e8ba96d103 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -135,7 +135,8 @@ static void virtual_base_list_aux (struct type *dclass);
/* 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, struct type **typeptr)
{
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, struct type **typeptr)
{
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, struct type **typeptr)
{
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_flag)
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, struct type *type, struct type **typeptr)
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);
+ /* 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. */
- /* 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));
+ 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, struct type *domain,
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, struct type *domain,
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, int spaces)
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, int spaces)
{
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");
@@ -3054,14 +3044,6 @@ recursive_dump_type (struct type *type, int spaces)
{
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))
{
puts_filtered (" TYPE_FLAG_VARARGS");
OpenPOWER on IntegriCloud