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.
This commit is contained in:
Daniel Jacobowitz 2002-05-14 18:30:53 +00:00
parent e31f1a7cdb
commit 2fdde8f831
9 changed files with 400 additions and 388 deletions

View file

@ -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,6 +415,47 @@ address_space_int_to_name (int space_flag)
return NULL;
}
/* 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_qualified_type (struct type *type, int new_flags,
struct type *storage)
{
struct type *ntype;
ntype = type;
do {
if (TYPE_INSTANCE_FLAGS (ntype) == new_flags)
return ntype;
ntype = TYPE_CHAIN (ntype);
} while (ntype != 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. */
TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;
/* 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;
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").
@ -378,36 +466,13 @@ 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);
ntype = type;
do {
if ((ntype->flags & space_flag) != 0)
return ntype;
ntype = TYPE_AS_TYPE (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));
/* 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). */
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;
/* Now set the address-space flag, and return the new type. */
ntype->flags |= space_flag;
return ntype;
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
CNST is a flag for setting the const attribute
@ -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);
int new_flags = (TYPE_INSTANCE_FLAGS (type)
& ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE));
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 */
/* 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;
new_flags |= TYPE_FLAG_VOLATILE;
/* Fix the chain of cv variants */
TYPE_CV_TYPE (ntype) = type;
TYPE_CV_TYPE (tmp_type) = ntype;
if (typeptr && *typeptr != NULL)
{
/* 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);
if (typeptr != NULL)
*typeptr = 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;
gdb_assert (!TYPE_CONST (type) && !TYPE_VOLATILE (type));
ntype = type;
while ((ntype = TYPE_CV_TYPE (ntype)) != type)
{
/* 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));
/* 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;
TYPE_AS_TYPE (ntype) = 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);
*TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
*ntype = *type;
TYPE_POINTER_TYPE (ntype) = ptr;
TYPE_REFERENCE_TYPE (ntype) = ref;
TYPE_CV_TYPE (ntype) = cv_chain;
TYPE_AS_TYPE (ntype) = as_chain;
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");