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

@ -1,3 +1,32 @@
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 Elena Zannoni <ezannoni@redhat.com>
* configure.tgt: Add a catch all sh* target, for cases like

View file

@ -316,7 +316,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
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)

View file

@ -2486,8 +2486,6 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
/* 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

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");

View file

@ -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 */
struct type
{
enum type_code code;
/* Code for kind of type */
/* Name of this type, or NULL if none.
enum type_code code;
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. */
/* Name of this type, or NULL if none.
char *name;
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. */
/* 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.
char *name;
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. */
/* 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.
char *tag_name;
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. */
/* 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.
char *tag_name;
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.
/* 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.
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. */
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.
unsigned length;
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;
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. */
/* 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;
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. */
/* 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;
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. */
/* Flags about this type. */
struct type *pointer_type;
int flags;
/* C++: also need a reference type. */
/* Number of fields described for this type */
struct type *reference_type;
short nfields;
/* 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;
/* 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.
/* 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;
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. */
/* Flags about this type. */
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 flags;
int bitpos;
/* Number of fields described for this type */
/* 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. */
short nfields;
CORE_ADDR physaddr;
char *physname;
/* 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.
/* 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;
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. */
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 bitsize;
int bitpos;
/* 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 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. */
struct type *type;
CORE_ADDR physaddr;
char *physname;
/* Name of field, value or argument.
NULL for range bounds and array domains. */
/* 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;
char *name;
/* 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. */
} *fields;
int bitsize;
/* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
is the base class which defined the virtual function table pointer.
/* 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
{
/* 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 *vptr_basetype;
struct type **arg_types;
/* 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.
/* 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. */
Unused if this type does not have virtual functions. */
struct cplus_struct_type *cplus_stuff;
int vptr_fieldno;
/* 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. */
/* Slot to point to additional language-specific fields of this type. */
const struct floatformat *floatformat;
} type_specific;
};
union 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. */
/* 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 *pointer_type;
struct type **arg_types;
/* C++: also need a reference type. */
/* 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 type *reference_type;
struct cplus_struct_type *cplus_stuff;
/* 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;
/* 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. */
/* Flags specific to this instance of the type, indicating where
on the ring we are. */
int instance_flags;
const struct floatformat *floatformat;
}
type_specific;
};
/* 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 (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 (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 (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 (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 (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))
@ -1077,8 +1082,6 @@ 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 *);
extern int address_space_name_to_int (char *);

View file

@ -4403,9 +4403,6 @@ hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
/* 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;
}

View file

@ -4302,8 +4302,6 @@ read_struct_type (char **pp, struct type *type, enum type_code type_code,
type = error_type (pp, objfile);
}
/* Fix up any cv-qualified versions of this type. */
finish_cv_type (type);
do_cleanups (back_to);
return (type);
}

View file

@ -1,3 +1,8 @@
2002-05-14 Daniel Jacobowitz <drow@mvista.com>
* gdb.base/maint.exp (maint print type): Update for new type
structure.
2002-05-14 Elena Zannoni <ezannoni@redhat.com>
* gdb.arch: New directory.

View file

@ -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" }