From 66a453345fa0eead2e473daee47ea394741b7902 Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Tue, 21 Feb 2017 13:32:52 -0800 Subject: [PATCH] Record nested types in ... --- gdb/dwarf2read.c | 120 +++++++++++++++++++++++++++++++++++++---------- gdb/gdbtypes.h | 49 +++++++++++++++++-- gdb/typeprint.c | 24 +++++----- 3 files changed, 152 insertions(+), 41 deletions(-) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index d6e074725af..d09aa417dba 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1348,10 +1348,10 @@ struct fnfieldlist struct nextfnfield *head; }; -struct typedef_field_list +struct decl_field_list { - struct typedef_field field; - struct typedef_field_list *next; + struct decl_field field; + struct decl_field_list *next; }; /* The routines that read and process dies for a C struct or C++ class @@ -1385,8 +1385,13 @@ struct field_info /* typedefs defined inside this class. TYPEDEF_FIELD_LIST contains head of a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements. */ - struct typedef_field_list *typedef_field_list; + struct decl_field_list *typedef_field_list; unsigned typedef_field_list_count; + + /* Nested types defined by this class and the number of elements in this + list. */ + struct decl_field_list *nested_types_list; + unsigned nested_types_list_count; }; /* One item on the queue of compilation units to read in full symbols @@ -6988,7 +6993,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) { case DW_TAG_subprogram: addr = gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr); - if (pdi->is_external || cu->language == language_ada) + if (pdi->is_external || cu->language == language_ada + || cu->language == language_cplus) { /* brobecker/2007-12-26: Normally, only "external" DIEs are part of the global scope. But in Ada, we want to be able to access @@ -7241,7 +7247,7 @@ add_partial_subprogram (struct partial_die_info *pdi, if (! pdi->has_children) return; - if (cu->language == language_ada) + if (cu->language == language_ada || cu->language == language_cplus) { pdi = pdi->die_child; while (pdi != NULL) @@ -12446,7 +12452,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die, /* If the language does not allow nested subprograms (either inside subprograms or lexical blocks), we're done. */ - if (cu->language != language_ada) + if (cu->language != language_ada && cu->language != language_cplus) return; /* Check all the children of the given DIE. If it contains nested @@ -12897,33 +12903,66 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } } -/* Add a typedef defined in the scope of the FIP's class. */ +/* Add a type definition defined in the scope of the FIP's class. */ static void -dwarf2_add_typedef (struct field_info *fip, struct die_info *die, - struct dwarf2_cu *cu) +dwarf2_add_type_defn (struct field_info *fip, struct die_info *die, + struct dwarf2_cu *cu) { - struct typedef_field_list *new_field; - struct typedef_field *fp; + struct decl_field_list *new_field; + struct attribute *attr; + struct decl_field *fp; + enum dwarf_access_attribute accessibility; /* Allocate a new field list entry and link it in. */ - new_field = XCNEW (struct typedef_field_list); + new_field = XCNEW (struct decl_field_list); make_cleanup (xfree, new_field); - gdb_assert (die->tag == DW_TAG_typedef); + gdb_assert (die->tag == DW_TAG_typedef + || die->tag == DW_TAG_class_type + || die->tag == DW_TAG_structure_type + || die->tag == DW_TAG_union_type + || die->tag == DW_TAG_enumeration_type); fp = &new_field->field; - /* Get name of field. */ + /* Get name of field. NULL is okay here, meaning an anonymous type. */ fp->name = dwarf2_name (die, cu); - if (fp->name == NULL) - return; - fp->type = read_type_die (die, cu); - new_field->next = fip->typedef_field_list; - fip->typedef_field_list = new_field; - fip->typedef_field_list_count++; + /* Save accessibility. */ + attr = dwarf2_attr (die, DW_AT_accessibility, cu); + if (attr != NULL) + accessibility = (enum dwarf_access_attribute) DW_UNSND (attr); + else + accessibility = dwarf2_default_access_attribute (die, cu); + switch (accessibility) + { + case DW_ACCESS_public: + fp->is_public = 1; + break; + case DW_ACCESS_private: + fp->is_private = 1; + break; + case DW_ACCESS_protected: + fp->is_protected = 1; + break; + default: + gdb_assert_not_reached ("unexpected accessibility attribute"); + } + + if (die->tag == DW_TAG_typedef) + { + new_field->next = fip->typedef_field_list; + fip->typedef_field_list = new_field; + fip->typedef_field_list_count++; + } + else + { + new_field->next = fip->nested_types_list; + fip->nested_types_list = new_field; + fip->nested_types_list_count++; + } } /* Create the vector of fields, and attach it to the type. */ @@ -13586,8 +13625,13 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) /* C++ base class field. */ dwarf2_add_field (&fi, child_die, cu); } - else if (child_die->tag == DW_TAG_typedef) - dwarf2_add_typedef (&fi, child_die, cu); + else if (child_die->tag == DW_TAG_typedef + || child_die->tag == DW_TAG_class_type + || child_die->tag == DW_TAG_structure_type + || child_die->tag == DW_TAG_union_type + || child_die->tag == DW_TAG_enumeration_type + /*|| child_die->tag == DW_TAG_namespace*/) + dwarf2_add_type_defn (&fi, child_die, cu); else if (child_die->tag == DW_TAG_template_type_param || child_die->tag == DW_TAG_template_value_param) { @@ -13696,14 +13740,14 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_TYPEDEF_FIELD_ARRAY (type) - = ((struct typedef_field *) + = ((struct decl_field *) TYPE_ALLOC (type, sizeof (TYPE_TYPEDEF_FIELD (type, 0)) * i)); TYPE_TYPEDEF_FIELD_COUNT (type) = i; /* Reverse the list order to keep the debug info elements order. */ while (--i >= 0) { - struct typedef_field *dest, *src; + struct decl_field *dest, *src; dest = &TYPE_TYPEDEF_FIELD (type, i); src = &fi.typedef_field_list->field; @@ -13712,6 +13756,30 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) } } + /* Copy fi.nested_types_list linked list elements content into the + allocated array TYPE_NESTED_TYPES_ARRAY (type). */ + if (fi.nested_types_list != NULL) + { + int i = fi.nested_types_list_count; + + ALLOCATE_CPLUS_STRUCT_TYPE (type); + TYPE_NESTED_TYPES_ARRAY (type) + = ((struct decl_field *) + TYPE_ALLOC (type, sizeof (struct decl_field) * i)); + TYPE_NESTED_TYPES_COUNT (type) = i; + + /* Reverse the list order to keep the debug info elements order. */ + while (--i >= 0) + { + struct decl_field *dest, *src; + + dest = &TYPE_NESTED_TYPES_FIELD (type, i); + src = &fi.nested_types_list->field; + fi.nested_types_list = fi.nested_types_list->next; + *dest = *src; + } + } + do_cleanups (back_to); } @@ -18958,7 +19026,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK; attr2 = dwarf2_attr (die, DW_AT_external, cu); if ((attr2 && (DW_UNSND (attr2) != 0)) - || cu->language == language_ada) + || cu->language == language_ada || cu->language == language_cplus) { /* Subprograms marked external are stored as a global symbol. Ada subprograms, whether marked external or not, are always diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index e094ecef3a9..b8910dcb047 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -869,7 +869,7 @@ struct fn_field }; -struct typedef_field +struct decl_field { /* * Unqualified name to be prefixed by owning class qualified name. */ @@ -879,6 +879,18 @@ struct typedef_field /* * Type this typedef named NAME represents. */ struct type *type; + + /* * True if this field was declared public, false otherwise. */ + unsigned int is_public : 1; + + /* * True if this field was declared protected, false otherwise. */ + unsigned int is_protected : 1; + + /* * True if this field was declared private, false otherwise. */ + unsigned int is_private : 1; + + /* * Unused. */ + unsigned int dummy : 13; }; /* * C++ language-specific information for TYPE_CODE_STRUCT and @@ -978,10 +990,17 @@ struct cplus_struct_type /* * typedefs defined inside this class. typedef_field points to an array of typedef_field_count elements. */ - struct typedef_field *typedef_field; + struct decl_field *typedef_field; unsigned typedef_field_count; + /* * The nested types defined by this type. nested_types points to + an array of nested_types_count elements. */ + + struct decl_field *nested_types; + + unsigned nested_types_count; + /* * The template arguments. This is an array with N_TEMPLATE_ARGUMENTS elements. This is NULL for non-template classes. */ @@ -1413,7 +1432,8 @@ extern void set_type_vptr_basetype (struct type *, struct type *); #define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1) #define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC) -#define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \ +/* Accessors for types and typedefs defined by a class. */ +#define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \ TYPE_CPLUS_SPECIFIC (thistype)->typedef_field #define TYPE_TYPEDEF_FIELD(thistype, n) \ TYPE_CPLUS_SPECIFIC (thistype)->typedef_field[n] @@ -1423,6 +1443,29 @@ extern void set_type_vptr_basetype (struct type *, struct type *); TYPE_TYPEDEF_FIELD (thistype, n).type #define TYPE_TYPEDEF_FIELD_COUNT(thistype) \ TYPE_CPLUS_SPECIFIC (thistype)->typedef_field_count +#define TYPE_TYPEDEF_FIELD_PUBLIC(thistype, n) \ + TYPE_TYPEDEF_FIELD (thistype, n).is_public +#define TYPE_TYPEDEF_FIELD_PROTECTED(thistype, n) \ + TYPE_TYPEDEF_FIELD (thistype, n).is_protected +#define TYPE_TYPEDEF_FIELD_PRIVATE(thistype, n) \ + TYPE_TYPEDEF_FIELD (thistype, n).is_private + +#define TYPE_NESTED_TYPES_ARRAY(thistype) \ + TYPE_CPLUS_SPECIFIC (thistype)->nested_types +#define TYPE_NESTED_TYPES_FIELD(thistype, n) \ + TYPE_CPLUS_SPECIFIC (thistype)->nested_types[n] +#define TYPE_NESTED_TYPES_FIELD_NAME(thistype, n) \ + TYPE_NESTED_TYPES_FIELD (thistype, n).name +#define TYPE_NESTED_TYPES_FIELD_TYPE(thistype, n) \ + TYPE_NESTED_TYPES_FIELD (thistype, n).type +#define TYPE_NESTED_TYPES_COUNT(thistype) \ + TYPE_CPLUS_SPECIFIC (thistype)->nested_types_count +#define TYPE_NESTED_TYPES_FIELD_PUBLIC(thistype, n) \ + TYPE_NESTED_TYPES_FIELD (thistype, n).is_public +#define TYPE_NESTED_TYPES_FIELD_PROTECTED(thistype, n) \ + TYPE_NESTED_TYPES_FIELD (thistype, n).is_protected +#define TYPE_NESTED_TYPES_FIELD_PRIVATE(thistype, n) \ + TYPE_NESTED_TYPES_FIELD (thistype, n).is_private #define TYPE_IS_OPAQUE(thistype) \ (((TYPE_CODE (thistype) == TYPE_CODE_STRUCT) \ diff --git a/gdb/typeprint.c b/gdb/typeprint.c index a22c6fba340..edc523e8d43 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -87,7 +87,7 @@ struct typedef_hash_table static hashval_t hash_typedef_field (const void *p) { - const struct typedef_field *tf = (const struct typedef_field *) p; + const struct decl_field *tf = (const struct decl_field *) p; struct type *t = check_typedef (tf->type); return htab_hash_string (TYPE_SAFE_NAME (t)); @@ -98,8 +98,8 @@ hash_typedef_field (const void *p) static int eq_typedef_field (const void *a, const void *b) { - const struct typedef_field *tfa = (const struct typedef_field *) a; - const struct typedef_field *tfb = (const struct typedef_field *) b; + const struct decl_field *tfa = (const struct decl_field *) a; + const struct decl_field *tfb = (const struct decl_field *) b; return types_equal (tfa->type, tfb->type); } @@ -117,7 +117,7 @@ recursively_update_typedef_hash (struct typedef_hash_table *table, for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (t); ++i) { - struct typedef_field *tdef = &TYPE_TYPEDEF_FIELD (t, i); + struct decl_field *tdef = &TYPE_TYPEDEF_FIELD (t, i); void **slot; slot = htab_find_slot (table->table, tdef, INSERT); @@ -145,14 +145,14 @@ add_template_parameters (struct typedef_hash_table *table, struct type *t) for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (t); ++i) { - struct typedef_field *tf; + struct decl_field *tf; void **slot; /* We only want type-valued template parameters in the hash. */ if (SYMBOL_CLASS (TYPE_TEMPLATE_ARGUMENT (t, i)) != LOC_TYPEDEF) continue; - tf = XOBNEW (&table->storage, struct typedef_field); + tf = XOBNEW (&table->storage, struct decl_field); tf->name = SYMBOL_LINKAGE_NAME (TYPE_TEMPLATE_ARGUMENT (t, i)); tf->type = SYMBOL_TYPE (TYPE_TEMPLATE_ARGUMENT (t, i)); @@ -270,7 +270,7 @@ find_global_typedef (const struct type_print_options *flags, { char *applied; void **slot; - struct typedef_field tf, *new_tf; + struct decl_field tf, *new_tf; if (flags->global_typedefs == NULL) return NULL; @@ -281,13 +281,13 @@ find_global_typedef (const struct type_print_options *flags, slot = htab_find_slot (flags->global_typedefs->table, &tf, INSERT); if (*slot != NULL) { - new_tf = (struct typedef_field *) *slot; + new_tf = (struct decl_field *) *slot; return new_tf->name; } /* Put an entry into the hash table now, in case apply_ext_lang_type_printers recurses. */ - new_tf = XOBNEW (&flags->global_typedefs->storage, struct typedef_field); + new_tf = XOBNEW (&flags->global_typedefs->storage, struct decl_field); new_tf->name = NULL; new_tf->type = t; @@ -316,12 +316,12 @@ find_typedef_in_hash (const struct type_print_options *flags, struct type *t) { if (flags->local_typedefs != NULL) { - struct typedef_field tf, *found; + struct decl_field tf, *found; tf.name = NULL; tf.type = t; - found = (struct typedef_field *) htab_find (flags->local_typedefs->table, - &tf); + found = (struct decl_field *) htab_find (flags->local_typedefs->table, + &tf); if (found != NULL) return found->name; -- 2.47.2