aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog.intercu15
-rw-r--r--gdb/dwarf2read.c132
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: