aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2010-01-12 05:49:00 +0000
committerJoel Brobecker <brobecker@gnat.com>2010-01-12 05:49:00 +0000
commitb4ba55a1812c4bde23d52111e54d2b72a1ec4af1 (patch)
treeb84c1cfcfebf30685854b3e01f7553ce70ac6bfc /gdb/dwarf2read.c
parentcc761f759cdb2966648d33c92f85c6e6e3e5da82 (diff)
downloadgdb-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.c105
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);