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
/* 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
{
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
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)
/* 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
}
}
-/* 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. */
/* 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)
{
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;
}
}
+ /* 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);
}
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
};
-struct typedef_field
+struct decl_field
{
/* * Unqualified name to be prefixed by owning class qualified
name. */
/* * 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
/* * 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. */
#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]
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) \
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));
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);
}
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);
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));
{
char *applied;
void **slot;
- struct typedef_field tf, *new_tf;
+ struct decl_field tf, *new_tf;
if (flags->global_typedefs == NULL)
return NULL;
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;
{
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;