diff options
author | Joel Brobecker <brobecker@gnat.com> | 2010-01-12 05:49:00 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2010-01-12 05:49:00 +0000 |
commit | b4ba55a1812c4bde23d52111e54d2b72a1ec4af1 (patch) | |
tree | b84c1cfcfebf30685854b3e01f7553ce70ac6bfc /gdb/dwarf2read.c | |
parent | cc761f759cdb2966648d33c92f85c6e6e3e5da82 (diff) | |
download | gdb-b4ba55a1812c4bde23d52111e54d2b72a1ec4af1.zip gdb-b4ba55a1812c4bde23d52111e54d2b72a1ec4af1.tar.gz gdb-b4ba55a1812c4bde23d52111e54d2b72a1ec4af1.tar.bz2 |
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.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 105 |
1 files changed, 101 insertions, 4 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 7623035..243859c 100644 --- a/gdb/dwarf2read.c +++ b/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); |