forked from Imagelibrary/binutils-gdb
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:
105
gdb/dwarf2read.c
105
gdb/dwarf2read.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user