gdb/ChangeLog:

Add support for DW_AT_GNAT_descriptive_type.
        * gdbtypes.h (enum type_specific_kind): New enum.
        (struct main_type) [type_specific_field]: New component.
        [type_specific]: Add new component "gnat_stuff".
        (struct gnat_aux_type): New type.
        (INIT_CPLUS_SPECIFIC): Also set TYPE_SPECIFIC_FIELD (type).
        (HAVE_CPLUS_STRUCT): Also check TYPE_SPECIFIC_FIELD (type).
        (gnat_aux_default, allocate_gnat_aux_type): Add declaration.
        (INIT_GNAT_SPECIFIC, ALLOCATE_GNAT_AUX_TYPE, HAVE_GNAT_AUX_INFO)
        (TYPE_SPECIFIC_FIELD): New macros.
        (TYPE_CPLUS_SPECIFIC): Return cplus_struct_default if the given
        type does not hold any cplus-specific data.
        (TYPE_RAW_CPLUS_SPECIFIC): New macro.
        (TYPE_GNAT_SPECIFIC, TYPE_DESCRIPTIVE_TYPE): New macros.
        (TYPE_IS_OPAQUE): Use HAVE_CPLUS_STRUCT to check if type has
        cplus-specific data.
        * gdbtypes.c (allocate_cplus_struct_type): Minor stylistic rewrite.
        Set new component TYPE_SPECIFIC_FIELD (type).
        (gnat_aux_default): New constant.
        (allocate_gnat_aux_type): New function.
        (init_type): Add initialization the type-specific stuff for
        TYPE_CODE_FLT and TYPE_CODE_FUNC types.
        (print_gnat_stuff): New function.
        (recursive_dump_type): Use HAVE_CPLUS_STRUCT to check for cplus-
        specific data.  Adjust code that prints the contents of the
        type-specific union using the TYPE_SPECIFIC_FIELD value.
        * dwarf2read.c (dwarf2_attach_fields_to_type): Do not allocate
        the type cplus stuff for Ada types.
        (dwarf2_add_member_fn, dwarf2_attach_fn_fields_to_type):
        Error out if these routines are called with an Ada type.
        (read_structure_type, read_array_type, read_subrange_type):
        Add call to set_descriptive_type.
        (set_die_type): Initialize the gnat-specific data if necessary.
        (need_gnat_info, die_descriptive_type, set_descriptive_type):
        New functions.
        * ada-lang.c (decode_constrained_packed_array_type): Use
        decode_constrained_packed_array_type instead of doing a standard
        lookup to locate a parallel type.
        (find_parallel_type_by_descriptive_type): New function.
        (ada_find_parallel_type_with_name): New function.
        (ada_find_parallel_type): Reimplement using
        ada_find_parallel_type_with_name.
        * ada-valprint.c (print_field_values): Use HAVE_CPLUS_STRUCT
        to check if type has a cplus stuff.
        * linespec.c (total_number_of_methods): Likewise.
        * mdebugread.c (new_type): Likewise.

gdb/testsuite/ChangeLog:

        * gdb.base/maint.exp: Adjust the expected output for the
        "maint print type" test. Use gdb_test_multiple instead of
        gdb_sent/gdb_expect.
This commit is contained in:
Joel Brobecker 2010-01-12 05:49:00 +00:00
parent cc761f759c
commit b4ba55a181
10 changed files with 398 additions and 81 deletions

View File

@ -1,3 +1,52 @@
2010-01-12 Joel Brobecker <brobecker@adacore.com>
Add support for DW_AT_GNAT_descriptive_type.
* gdbtypes.h (enum type_specific_kind): New enum.
(struct main_type) [type_specific_field]: New component.
[type_specific]: Add new component "gnat_stuff".
(struct gnat_aux_type): New type.
(INIT_CPLUS_SPECIFIC): Also set TYPE_SPECIFIC_FIELD (type).
(HAVE_CPLUS_STRUCT): Also check TYPE_SPECIFIC_FIELD (type).
(gnat_aux_default, allocate_gnat_aux_type): Add declaration.
(INIT_GNAT_SPECIFIC, ALLOCATE_GNAT_AUX_TYPE, HAVE_GNAT_AUX_INFO)
(TYPE_SPECIFIC_FIELD): New macros.
(TYPE_CPLUS_SPECIFIC): Return cplus_struct_default if the given
type does not hold any cplus-specific data.
(TYPE_RAW_CPLUS_SPECIFIC): New macro.
(TYPE_GNAT_SPECIFIC, TYPE_DESCRIPTIVE_TYPE): New macros.
(TYPE_IS_OPAQUE): Use HAVE_CPLUS_STRUCT to check if type has
cplus-specific data.
* gdbtypes.c (allocate_cplus_struct_type): Minor stylistic rewrite.
Set new component TYPE_SPECIFIC_FIELD (type).
(gnat_aux_default): New constant.
(allocate_gnat_aux_type): New function.
(init_type): Add initialization the type-specific stuff for
TYPE_CODE_FLT and TYPE_CODE_FUNC types.
(print_gnat_stuff): New function.
(recursive_dump_type): Use HAVE_CPLUS_STRUCT to check for cplus-
specific data. Adjust code that prints the contents of the
type-specific union using the TYPE_SPECIFIC_FIELD value.
* dwarf2read.c (dwarf2_attach_fields_to_type): Do not allocate
the type cplus stuff for Ada types.
(dwarf2_add_member_fn, dwarf2_attach_fn_fields_to_type):
Error out if these routines are called with an Ada type.
(read_structure_type, read_array_type, read_subrange_type):
Add call to set_descriptive_type.
(set_die_type): Initialize the gnat-specific data if necessary.
(need_gnat_info, die_descriptive_type, set_descriptive_type):
New functions.
* ada-lang.c (decode_constrained_packed_array_type): Use
decode_constrained_packed_array_type instead of doing a standard
lookup to locate a parallel type.
(find_parallel_type_by_descriptive_type): New function.
(ada_find_parallel_type_with_name): New function.
(ada_find_parallel_type): Reimplement using
ada_find_parallel_type_with_name.
* ada-valprint.c (print_field_values): Use HAVE_CPLUS_STRUCT
to check if type has a cplus stuff.
* linespec.c (total_number_of_methods): Likewise.
* mdebugread.c (new_type): Likewise.
2010-01-11 Jan Kratochvil <jan.kratochvil@redhat.com>
* NEWS: Document the 0b binary number prefix parsing.

View File

@ -157,6 +157,9 @@ static struct type *ada_lookup_struct_elt_type (struct type *, char *,
static struct value *evaluate_subexp_type (struct expression *, int *);
static struct type *ada_find_parallel_type_with_name (struct type *,
const char *);
static int is_dynamic_field (struct type *, int);
static struct type *to_fixed_variant_branch_type (struct type *,
@ -1874,13 +1877,13 @@ decode_constrained_packed_array_type (struct type *type)
memcpy (name, raw_name, tail - raw_name);
name[tail - raw_name] = '\000';
sym = standard_lookup (name, get_selected_block (0), VAR_DOMAIN);
if (sym == NULL || SYMBOL_TYPE (sym) == NULL)
shadow_type = ada_find_parallel_type_with_name (type, name);
if (shadow_type == NULL)
{
lim_warning (_("could not find bounds information on packed array"));
return NULL;
}
shadow_type = SYMBOL_TYPE (sym);
CHECK_TYPEDEF (shadow_type);
if (TYPE_CODE (shadow_type) != TYPE_CODE_ARRAY)
@ -6666,31 +6669,90 @@ ada_type_name (struct type *type)
return TYPE_TAG_NAME (type);
}
/* Find a parallel type to TYPE whose name is formed by appending
/* Search the list of "descriptive" types associated to TYPE for a type
whose name is NAME. */
static struct type *
find_parallel_type_by_descriptive_type (struct type *type, const char *name)
{
struct type *result;
/* If there no descriptive-type info, then there is no parallel type
to be found. */
if (!HAVE_GNAT_AUX_INFO (type))
return NULL;
result = TYPE_DESCRIPTIVE_TYPE (type);
while (result != NULL)
{
char *result_name = ada_type_name (result);
if (result_name == NULL)
{
warning (_("unexpected null name on descriptive type"));
return NULL;
}
/* If the names match, stop. */
if (strcmp (result_name, name) == 0)
break;
/* Otherwise, look at the next item on the list, if any. */
if (HAVE_GNAT_AUX_INFO (result))
result = TYPE_DESCRIPTIVE_TYPE (result);
else
result = NULL;
}
/* If we didn't find a match, see whether this is a packed array. With
older compilers, the descriptive type information is either absent or
irrelevant when it comes to packed arrays so the above lookup fails.
Fall back to using a parallel lookup by name in this case. */
if (result == NULL && ada_is_packed_array_type (type))
return ada_find_any_type (name);
return result;
}
/* Find a parallel type to TYPE with the specified NAME, using the
descriptive type taken from the debugging information, if available,
and otherwise using the (slower) name-based method. */
static struct type *
ada_find_parallel_type_with_name (struct type *type, const char *name)
{
struct type *result = NULL;
if (HAVE_GNAT_AUX_INFO (type))
result = find_parallel_type_by_descriptive_type (type, name);
else
result = ada_find_any_type (name);
return result;
}
/* Same as above, but specify the name of the parallel type by appending
SUFFIX to the name of TYPE. */
struct type *
ada_find_parallel_type (struct type *type, const char *suffix)
{
static char *name;
static size_t name_len = 0;
char *name, *typename = ada_type_name (type);
int len;
char *typename = ada_type_name (type);
if (typename == NULL)
return NULL;
len = strlen (typename);
GROW_VECT (name, name_len, len + strlen (suffix) + 1);
name = (char *) alloca (len + strlen (suffix) + 1);
strcpy (name, typename);
strcpy (name + len, suffix);
return ada_find_any_type (name);
return ada_find_parallel_type_with_name (type, name);
}
/* If TYPE is a variable-size record type, return the corresponding template
type describing its fields. Otherwise, return NULL. */

View File

@ -1077,8 +1077,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr,
/* Bitfields require special handling, especially due to byte
order problems. */
if (TYPE_CPLUS_SPECIFIC (type) != NULL
&& TYPE_FIELD_IGNORE (type, i))
if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i))
{
fputs_filtered (_("<optimized out or zero length>"), stream);
}

View File

@ -926,6 +926,13 @@ static void dwarf2_const_value_data (struct attribute *attr,
static struct type *die_type (struct die_info *, struct dwarf2_cu *);
static int need_gnat_info (struct dwarf2_cu *);
static struct type *die_descriptive_type (struct die_info *, struct dwarf2_cu *);
static void set_descriptive_type (struct type *, struct die_info *,
struct dwarf2_cu *);
static struct type *die_containing_type (struct die_info *,
struct dwarf2_cu *);
@ -4564,7 +4571,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
TYPE_ALLOC (type, sizeof (struct field) * nfields);
memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
if (fip->non_public_fields)
if (fip->non_public_fields && cu->language != language_ada)
{
ALLOCATE_CPLUS_STRUCT_TYPE (type);
@ -4583,7 +4590,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
/* If the type has baseclasses, allocate and clear a bit vector for
TYPE_FIELD_VIRTUAL_BITS. */
if (fip->nbaseclasses)
if (fip->nbaseclasses && cu->language != language_ada)
{
int num_bytes = B_BYTES (fip->nbaseclasses);
unsigned char *pointer;
@ -4617,11 +4624,13 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
switch (fieldp->accessibility)
{
case DW_ACCESS_private:
SET_TYPE_FIELD_PRIVATE (type, nfields);
if (cu->language != language_ada)
SET_TYPE_FIELD_PRIVATE (type, nfields);
break;
case DW_ACCESS_protected:
SET_TYPE_FIELD_PROTECTED (type, nfields);
if (cu->language != language_ada)
SET_TYPE_FIELD_PROTECTED (type, nfields);
break;
case DW_ACCESS_public:
@ -4641,6 +4650,8 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
{
case DW_VIRTUALITY_virtual:
case DW_VIRTUALITY_pure_virtual:
if (cu->language == language_ada)
error ("unexpected virtuality in component of Ada type");
SET_TYPE_FIELD_VIRTUAL (type, nfields);
break;
}
@ -4664,6 +4675,9 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
struct nextfnfield *new_fnfield;
struct type *this_type;
if (cu->language == language_ada)
error ("unexpected member function in Ada type");
/* Get name of member function. */
fieldname = dwarf2_name (die, cu);
if (fieldname == NULL)
@ -4837,6 +4851,9 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
int total_length = 0;
int i;
if (cu->language == language_ada)
error ("unexpected member functions in Ada type");
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields);
@ -5038,6 +5055,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
if (die_is_declaration (die, cu))
TYPE_STUB (type) = 1;
set_descriptive_type (type, die, cu);
/* We need to add the type field to the die immediately so we don't
infinitely recurse when dealing with pointers to the structure
type within the structure itself. */
@ -5451,6 +5470,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
if (name)
TYPE_NAME (type) = name;
set_descriptive_type (type, die, cu);
do_cleanups (back_to);
/* Install the type in the die. */
@ -6113,6 +6134,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (attr)
TYPE_LENGTH (range_type) = DW_UNSND (attr);
set_descriptive_type (range_type, die, cu);
return set_die_type (die, range_type, cu);
}
@ -8768,6 +8791,67 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
return type;
}
/* True iff CU's producer generates GNAT Ada auxiliary information
that allows to find parallel types through that information instead
of having to do expensive parallel lookups by type name. */
static int
need_gnat_info (struct dwarf2_cu *cu)
{
/* FIXME: brobecker/2010-10-12: As of now, only the AdaCore version
of GNAT produces this auxiliary information, without any indication
that it is produced. Part of enhancing the FSF version of GNAT
to produce that information will be to put in place an indicator
that we can use in order to determine whether the descriptive type
info is available or not. One suggestion that has been made is
to use a new attribute, attached to the CU die. For now, assume
that the descriptive type info is not available. */
return 0;
}
/* Return the auxiliary type of the die in question using its
DW_AT_GNAT_descriptive_type attribute. Returns NULL if the
attribute is not present. */
static struct type *
die_descriptive_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct type *type;
struct attribute *type_attr;
struct die_info *type_die;
type_attr = dwarf2_attr (die, DW_AT_GNAT_descriptive_type, cu);
if (!type_attr)
return NULL;
type_die = follow_die_ref (die, type_attr, &cu);
type = tag_type_to_type (type_die, cu);
if (!type)
{
dump_die_for_error (type_die);
error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"),
cu->objfile->name);
}
return type;
}
/* If DIE has a descriptive_type attribute, then set the TYPE's
descriptive type accordingly. */
static void
set_descriptive_type (struct type *type, struct die_info *die,
struct dwarf2_cu *cu)
{
struct type *descriptive_type = die_descriptive_type (die, cu);
if (descriptive_type)
{
ALLOCATE_GNAT_AUX_TYPE (type);
TYPE_DESCRIPTIVE_TYPE (type) = descriptive_type;
}
}
/* Return the containing type of the die in question using its
DW_AT_containing_type attribute. */
@ -11724,6 +11808,19 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct dwarf2_offset_and_type **slot, ofs;
/* For Ada types, make sure that the gnat-specific data is always
initialized (if not already set). There are a few types where
we should not be doing so, because the type-specific area is
already used to hold some other piece of info (eg: TYPE_CODE_FLT
where the type-specific area is used to store the floatformat).
But this is not a problem, because the gnat-specific information
is actually not needed for these types. */
if (need_gnat_info (cu)
&& TYPE_CODE (type) != TYPE_CODE_FUNC
&& TYPE_CODE (type) != TYPE_CODE_FLT
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
if (cu->type_hash == NULL)
{
gdb_assert (cu->per_cu != NULL);

View File

@ -1717,14 +1717,32 @@ const struct cplus_struct_type cplus_struct_default;
void
allocate_cplus_struct_type (struct type *type)
{
if (!HAVE_CPLUS_STRUCT (type))
{
TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
TYPE_ALLOC (type, sizeof (struct cplus_struct_type));
*(TYPE_CPLUS_SPECIFIC (type)) = cplus_struct_default;
}
if (HAVE_CPLUS_STRUCT (type))
/* Structure was already allocated. Nothing more to do. */
return;
TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_CPLUS_STUFF;
TYPE_RAW_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
TYPE_ALLOC (type, sizeof (struct cplus_struct_type));
*(TYPE_RAW_CPLUS_SPECIFIC (type)) = cplus_struct_default;
}
const struct gnat_aux_type gnat_aux_default =
{ NULL };
/* Set the TYPE's type-specific kind to TYPE_SPECIFIC_GNAT_STUFF,
and allocate the associated gnat-specific data. The gnat-specific
data is also initialized to gnat_aux_default. */
void
allocate_gnat_aux_type (struct type *type)
{
TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_GNAT_STUFF;
TYPE_GNAT_SPECIFIC (type) = (struct gnat_aux_type *)
TYPE_ALLOC (type, sizeof (struct gnat_aux_type));
*(TYPE_GNAT_SPECIFIC (type)) = gnat_aux_default;
}
/* Helper function to initialize the standard scalar types.
If NAME is non-NULL, then we make a copy of the string pointed
@ -1777,10 +1795,19 @@ init_type (enum type_code code, int length, int flags,
if (name && strcmp (name, "char") == 0)
TYPE_NOSIGN (type) = 1;
if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION
|| code == TYPE_CODE_NAMESPACE)
switch (code)
{
INIT_CPLUS_SPECIFIC (type);
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
case TYPE_CODE_NAMESPACE:
INIT_CPLUS_SPECIFIC (type);
break;
case TYPE_CODE_FLT:
TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
break;
case TYPE_CODE_FUNC:
TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_CALLING_CONVENTION;
break;
}
return type;
}
@ -2495,6 +2522,17 @@ print_cplus_stuff (struct type *type, int spaces)
}
}
/* Print the contents of the TYPE's type_specific union, assuming that
its type-specific kind is TYPE_SPECIFIC_GNAT_STUFF. */
static void
print_gnat_stuff (struct type *type, int spaces)
{
struct type *descriptive_type = TYPE_DESCRIPTIVE_TYPE (type);
recursive_dump_type (descriptive_type, spaces + 2);
}
static struct obstack dont_print_type_obstack;
void
@ -2506,7 +2544,7 @@ recursive_dump_type (struct type *type, int spaces)
obstack_begin (&dont_print_type_obstack, 0);
if (TYPE_NFIELDS (type) > 0
|| (TYPE_CPLUS_SPECIFIC (type) && TYPE_NFN_FIELDS (type) > 0))
|| (HAVE_CPLUS_STRUCT (type) && TYPE_NFN_FIELDS (type) > 0))
{
struct type **first_dont_print
= (struct type **) obstack_base (&dont_print_type_obstack);
@ -2775,55 +2813,55 @@ recursive_dump_type (struct type *type, int spaces)
}
printfi_filtered (spaces, "vptr_fieldno %d\n",
TYPE_VPTR_FIELDNO (type));
switch (TYPE_CODE (type))
switch (TYPE_SPECIFIC_FIELD (type))
{
case TYPE_CODE_STRUCT:
printfi_filtered (spaces, "cplus_stuff ");
gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type),
gdb_stdout);
puts_filtered ("\n");
print_cplus_stuff (type, spaces);
break;
case TYPE_SPECIFIC_CPLUS_STUFF:
printfi_filtered (spaces, "cplus_stuff ");
gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type),
gdb_stdout);
puts_filtered ("\n");
print_cplus_stuff (type, spaces);
break;
case TYPE_CODE_FLT:
printfi_filtered (spaces, "floatformat ");
if (TYPE_FLOATFORMAT (type) == NULL)
puts_filtered ("(null)");
else
{
puts_filtered ("{ ");
if (TYPE_FLOATFORMAT (type)[0] == NULL
|| TYPE_FLOATFORMAT (type)[0]->name == NULL)
puts_filtered ("(null)");
else
puts_filtered (TYPE_FLOATFORMAT (type)[0]->name);
case TYPE_SPECIFIC_GNAT_STUFF:
printfi_filtered (spaces, "gnat_stuff ");
gdb_print_host_address (TYPE_GNAT_SPECIFIC (type), gdb_stdout);
puts_filtered ("\n");
print_gnat_stuff (type, spaces);
break;
puts_filtered (", ");
if (TYPE_FLOATFORMAT (type)[1] == NULL
|| TYPE_FLOATFORMAT (type)[1]->name == NULL)
puts_filtered ("(null)");
else
puts_filtered (TYPE_FLOATFORMAT (type)[1]->name);
case TYPE_SPECIFIC_FLOATFORMAT:
printfi_filtered (spaces, "floatformat ");
if (TYPE_FLOATFORMAT (type) == NULL)
puts_filtered ("(null)");
else
{
puts_filtered ("{ ");
if (TYPE_FLOATFORMAT (type)[0] == NULL
|| TYPE_FLOATFORMAT (type)[0]->name == NULL)
puts_filtered ("(null)");
else
puts_filtered (TYPE_FLOATFORMAT (type)[0]->name);
puts_filtered (" }");
}
puts_filtered ("\n");
break;
puts_filtered (", ");
if (TYPE_FLOATFORMAT (type)[1] == NULL
|| TYPE_FLOATFORMAT (type)[1]->name == NULL)
puts_filtered ("(null)");
else
puts_filtered (TYPE_FLOATFORMAT (type)[1]->name);
default:
/* We have to pick one of the union types to be able print and
test the value. Pick cplus_struct_type, even though we know
it isn't any particular one. */
printfi_filtered (spaces, "type_specific ");
gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
if (TYPE_CPLUS_SPECIFIC (type) != NULL)
{
printf_filtered (_(" (unknown data form)"));
}
printf_filtered ("\n");
break;
puts_filtered (" }");
}
puts_filtered ("\n");
break;
case TYPE_SPECIFIC_CALLING_CONVENTION:
printfi_filtered (spaces, "calling_convention %d\n",
TYPE_CALLING_CONVENTION (type));
break;
}
if (spaces == 0)
obstack_free (&dont_print_type_obstack, NULL);
}

View File

@ -340,6 +340,26 @@ enum field_loc_kind
FIELD_LOC_KIND_DWARF_BLOCK /* dwarf_block */
};
/* A discriminant to determine which field in the main_type.type_specific
union is being used, if any.
For types such as TYPE_CODE_FLT or TYPE_CODE_FUNC, the use of this
discriminant is really redundant, as we know from the type code
which field is going to be used. As such, it would be possible to
reduce the size of this enum in order to save a bit or two for
other fields of struct main_type. But, since we still have extra
room , and for the sake of clarity and consistency, we treat all fields
of the union the same way. */
enum type_specific_kind
{
TYPE_SPECIFIC_NONE,
TYPE_SPECIFIC_CPLUS_STUFF,
TYPE_SPECIFIC_GNAT_STUFF,
TYPE_SPECIFIC_FLOATFORMAT,
TYPE_SPECIFIC_CALLING_CONVENTION
};
/* This structure is space-critical.
Its layout has been tweaked to reduce the space used. */
@ -367,6 +387,10 @@ struct main_type
unsigned int flag_fixed_instance : 1;
unsigned int flag_objfile_owned : 1;
/* A discriminant telling us which field of the type_specific union
is being used for this type, if any. */
ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
/* Number of fields described for this type. This field appears at
this location because it packs nicely here. */
@ -554,6 +578,10 @@ struct main_type
struct cplus_struct_type *cplus_stuff;
/* GNAT_STUFF is for types for which the GNAT Ada compiler
provides additional information. */
struct gnat_aux_type *gnat_stuff;
/* FLOATFORMAT is for TYPE_CODE_FLT. It is a pointer to two
floatformat objects that describe the floating-point value
that resides within the type. The first is for big endian
@ -825,6 +853,15 @@ struct badness_vector
int *rank;
};
/* GNAT Ada-specific information for various Ada types. */
struct gnat_aux_type
{
/* Parallel type used to encode information about dynamic types
used in Ada (such as variant records, variable-size array,
etc). */
struct type* descriptive_type;
};
/* The default value of TYPE_CPLUS_SPECIFIC(T) points to the
this shared static structure. */
@ -833,10 +870,27 @@ extern const struct cplus_struct_type cplus_struct_default;
extern void allocate_cplus_struct_type (struct type *);
#define INIT_CPLUS_SPECIFIC(type) \
(TYPE_CPLUS_SPECIFIC(type)=(struct cplus_struct_type*)&cplus_struct_default)
(TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_CPLUS_STUFF, \
TYPE_RAW_CPLUS_SPECIFIC (type) = (struct cplus_struct_type*) &cplus_struct_default)
#define ALLOCATE_CPLUS_STRUCT_TYPE(type) allocate_cplus_struct_type (type)
#define HAVE_CPLUS_STRUCT(type) \
(TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default)
(TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_CPLUS_STUFF \
&& TYPE_RAW_CPLUS_SPECIFIC (type) != &cplus_struct_default)
extern const struct gnat_aux_type gnat_aux_default;
extern void allocate_gnat_aux_type (struct type *);
#define INIT_GNAT_SPECIFIC(type) \
(TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_GNAT_STUFF, \
TYPE_GNAT_SPECIFIC (type) = (struct gnat_aux_type *) &gnat_aux_default)
#define ALLOCATE_GNAT_AUX_TYPE(type) allocate_gnat_aux_type (type)
/* A macro that returns non-zero if the type-specific data should be
read as "gnat-stuff". */
#define HAVE_GNAT_AUX_INFO(type) \
(TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_GNAT_STUFF)
#define TYPE_INSTANCE_FLAGS(thistype) (thistype)->instance_flags
#define TYPE_MAIN_TYPE(thistype) (thistype)->main_type
@ -890,9 +944,22 @@ extern void allocate_cplus_struct_type (struct type *);
#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_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type
#define TYPE_SPECIFIC_FIELD(thistype) \
TYPE_MAIN_TYPE(thistype)->type_specific_field
#define TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific
#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
/* We need this tap-dance with the TYPE_RAW_SPECIFIC because of the case
where we're trying to print an Ada array using the C language.
In that case, there is no "cplus_stuff", but the C language assumes
that there is. What we do, in that case, is pretend that there is
an implicit one which is the default cplus stuff. */
#define TYPE_CPLUS_SPECIFIC(thistype) \
(!HAVE_CPLUS_STRUCT(thistype) \
? (struct cplus_struct_type*)&cplus_struct_default \
: TYPE_RAW_CPLUS_SPECIFIC(thistype))
#define TYPE_RAW_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
#define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
#define TYPE_GNAT_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.gnat_stuff
#define TYPE_DESCRIPTIVE_TYPE(thistype) TYPE_GNAT_SPECIFIC(thistype)->descriptive_type
#define TYPE_CALLING_CONVENTION(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.calling_convention
#define TYPE_BASECLASS(thistype,index) TYPE_FIELD_TYPE(thistype, index)
#define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
@ -1004,7 +1071,7 @@ extern void allocate_cplus_struct_type (struct type *);
#define TYPE_IS_OPAQUE(thistype) (((TYPE_CODE (thistype) == TYPE_CODE_STRUCT) || \
(TYPE_CODE (thistype) == TYPE_CODE_UNION)) && \
(TYPE_NFIELDS (thistype) == 0) && \
(TYPE_CPLUS_SPECIFIC (thistype) && (TYPE_NFN_FIELDS (thistype) == 0)) && \
(HAVE_CPLUS_STRUCT (thistype) && (TYPE_NFN_FIELDS (thistype) == 0)) && \
(TYPE_STUB (thistype) || !TYPE_STUB_SUPPORTED (thistype)))
struct builtin_type

View File

@ -186,7 +186,7 @@ total_number_of_methods (struct type *type)
int count;
CHECK_TYPEDEF (type);
if (TYPE_CPLUS_SPECIFIC (type) == NULL)
if (! HAVE_CPLUS_STRUCT (type))
return 0;
count = TYPE_NFN_FIELDS_TOTAL (type);

View File

@ -4800,7 +4800,7 @@ new_type (char *name)
t = alloc_type (current_objfile);
TYPE_NAME (t) = name;
TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default;
INIT_CPLUS_SPECIFIC (t);
return t;
}

View File

@ -1,3 +1,9 @@
2010-01-12 Joel Brobecker <brobecker@adacore.com>
* gdb.base/maint.exp: Adjust the expected output for the
"maint print type" test. Use gdb_test_multiple instead of
gdb_sent/gdb_expect.
2010-01-11 Doug Evans <dje@google.com>
* lib/gdbserver-support.exp (gdbserver_download_current_prog): Rename

View File

@ -397,13 +397,12 @@ gdb_expect {
timeout { fail "(timeout) maint print symbols" }
}
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\nobjfile $hex\r\ntarget_type $hex\r\npointer_type $hex\r\nreference_type $hex\r\ntype_chain $hex\r\ninstance_flags $hex\r\nflags\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" }
}
set msg "maint print type"
gdb_test_multiple "maint print type argc" $msg {
-re "type node $hex\r\nname .int. \\($hex\\)\r\ntagname .<NULL>. \\($hex\\)\r\ncode $hex \\(TYPE_CODE_INT\\)\r\nlength \[24\]\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\r\nnfields 0 $hex\r\nvptr_basetype $hex\r\nvptr_fieldno -1\r\n$gdb_prompt $" {
pass $msg
}
}
if [istarget "hppa*-*-11*"] {
setup_xfail hppa*-*-*11* CLLbs14860