diff options
-rw-r--r-- | gdb/ChangeLog.intercu | 15 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 132 |
2 files changed, 107 insertions, 40 deletions
diff --git a/gdb/ChangeLog.intercu b/gdb/ChangeLog.intercu index f2eaf24..333c5e1 100644 --- a/gdb/ChangeLog.intercu +++ b/gdb/ChangeLog.intercu @@ -1,3 +1,18 @@ +2004-02-23 Daniel Jacobowitz <drow@mvista.com> + + * dwarf2read.c (read_structure_scope): Don't create a symbol + or call process_die. Return immediately if die->type is set. + Call read_type_die before dwarf2_add_member_fn. + (process_structure_scope): New function. + (read_enumeration_type, read_enumeration_scope): New functions, + broken out from read_enumeration. Don't create the enumeration + type if it has already been created. + (read_enumeration): Removed. + (process_die): Call process_structure_scope, read_enumeration_type, + and read_enumeration_scope. Just call new_symbol for base and + subrange types. Add a comment about other type dies. + (read_type_die): Call read_enumeration_type. + 2004-02-22 Daniel Jacobowitz <drow@mvista.com> * dwarf2read.c (dwarf2_attr_with_cu): New function, renamed diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 332001d..8ffdc83 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -863,6 +863,8 @@ static void dwarf2_attach_fn_fields_to_type (struct field_info *, static void read_structure_scope (struct die_info *, struct dwarf2_cu *); +static void process_structure_scope (struct die_info *, struct dwarf2_cu *); + static void read_common_block (struct die_info *, struct dwarf2_cu *); static void read_namespace (struct die_info *die, struct dwarf2_cu *); @@ -870,7 +872,9 @@ static void read_namespace (struct die_info *die, struct dwarf2_cu *); static const char *namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *); -static void read_enumeration (struct die_info *, struct dwarf2_cu *); +static void read_enumeration_type (struct die_info *, struct dwarf2_cu *); + +static void read_enumeration_scope (struct die_info *, struct dwarf2_cu *); static struct type *dwarf_base_type (int, int, struct dwarf2_cu *); @@ -2399,10 +2403,16 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_structure_type: case DW_TAG_union_type: read_structure_scope (die, cu); + process_structure_scope (die, cu); break; case DW_TAG_enumeration_type: - read_enumeration (die, cu); + read_enumeration_type (die, cu); + read_enumeration_scope (die, cu); break; + + /* FIXME: These initialize die->type, but do not create a symbol + or process any children. Therefore it doesn't do anything that + won't be done on-demand by read_type_die. */ case DW_TAG_subroutine_type: read_subroutine_type (die, cu); break; @@ -2421,21 +2431,19 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_string_type: read_tag_string_type (die, cu); break; + /* END FIXME */ + case DW_TAG_base_type: read_base_type (die, cu); - if (dwarf2_attr (die, DW_AT_name, cu)) - { - /* Add a typedef symbol for the base type definition. */ - new_symbol (die, die->type, cu); - } + /* Add a typedef symbol for the type definition, if it has a + DW_AT_name. */ + new_symbol (die, die->type, cu); break; case DW_TAG_subrange_type: read_subrange_type (die, cu); - if (dwarf2_attr (die, DW_AT_name, cu)) - { - /* Add a typedef symbol for the base type definition. */ - new_symbol (die, die->type, cu); - } + /* Add a typedef symbol for the type definition, if it has a + DW_AT_name. */ + new_symbol (die, die->type, cu); break; case DW_TAG_common_block: read_common_block (die, cu); @@ -3459,6 +3467,9 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu) any. */ int need_to_update_name = 0; + if (die->type) + return; + type = alloc_type (objfile); INIT_CPLUS_SPECIFIC (type); @@ -3559,7 +3570,7 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu) else if (child_die->tag == DW_TAG_subprogram) { /* C++ member function. */ - process_die (child_die, cu); + read_type_die (child_die, cu); dwarf2_add_member_fn (&fi, child_die, type, cu); if (need_to_update_name) { @@ -3602,10 +3613,6 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu) /* C++ base class field. */ dwarf2_add_field (&fi, child_die, cu); } - else - { - process_die (child_die, cu); - } child_die = sibling_die (child_die); } @@ -3665,8 +3672,6 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu) } } - new_symbol (die, type, cu); - do_cleanups (back_to); } else @@ -3680,26 +3685,53 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu) do_cleanups (back_to); } -/* Given a pointer to a die which begins an enumeration, process all - the dies that define the members of the enumeration. +static void +process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + const char *previous_prefix = processing_current_prefix; - This will be much nicer in draft 6 of the DWARF spec when our - members will be dies instead squished into the DW_AT_element_list - attribute. + if (TYPE_TAG_NAME (die->type) != NULL) + processing_current_prefix = TYPE_TAG_NAME (die->type); - NOTE: We reverse the order of the element list. */ + if (die->child != NULL && ! die_is_declaration (die, cu)) + { + struct die_info *child_die; + + child_die = die->child; + + while (child_die && child_die->tag) + { + if (child_die->tag == DW_TAG_member + || child_die->tag == DW_TAG_variable + || child_die->tag == DW_TAG_inheritance) + { + /* Do nothing. */ + } + else + process_die (child_die, cu); + + child_die = sibling_die (child_die); + } + + new_symbol (die, die->type, cu); + } + + processing_current_prefix = previous_prefix; +} + +/* Given a DW_AT_enumeration_type die, set its type. We do not + complete the type's fields yet, or create any symbols. */ static void -read_enumeration (struct die_info *die, struct dwarf2_cu *cu) +read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; - struct die_info *child_die; struct type *type; - struct field *fields; struct attribute *attr; - struct symbol *sym; - int num_fields; - int unsigned_enum = 1; + + if (die->type) + return; type = alloc_type (objfile); @@ -3734,6 +3766,26 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu) TYPE_LENGTH (type) = 0; } + die->type = type; +} + +/* Given a pointer to a die which begins an enumeration, process all + the dies that define the members of the enumeration, and create the + symbol for the enumeration type. + + NOTE: We reverse the order of the element list. */ + +static void +read_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct die_info *child_die; + struct field *fields; + struct attribute *attr; + struct symbol *sym; + int num_fields; + int unsigned_enum = 1; + num_fields = 0; fields = NULL; if (die->child != NULL) @@ -3750,7 +3802,7 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (child_die, DW_AT_name, cu); if (attr) { - sym = new_symbol (child_die, type, cu); + sym = new_symbol (child_die, die->type, cu); if (SYMBOL_VALUE (sym) < 0) unsigned_enum = 0; @@ -3777,18 +3829,18 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu) if (num_fields) { - TYPE_NFIELDS (type) = num_fields; - TYPE_FIELDS (type) = (struct field *) - TYPE_ALLOC (type, sizeof (struct field) * num_fields); - memcpy (TYPE_FIELDS (type), fields, + TYPE_NFIELDS (die->type) = num_fields; + TYPE_FIELDS (die->type) = (struct field *) + TYPE_ALLOC (die->type, sizeof (struct field) * num_fields); + memcpy (TYPE_FIELDS (die->type), fields, sizeof (struct field) * num_fields); xfree (fields); } if (unsigned_enum) - TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; + TYPE_FLAGS (die->type) |= TYPE_FLAG_UNSIGNED; } - die->type = type; - new_symbol (die, type, cu); + + new_symbol (die, die->type, cu); } /* Extract all information from a DW_TAG_array_type DIE and put it in @@ -6770,7 +6822,7 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu) read_structure_scope (die, cu); break; case DW_TAG_enumeration_type: - read_enumeration (die, cu); + read_enumeration_type (die, cu); break; case DW_TAG_subprogram: case DW_TAG_subroutine_type: |