aboutsummaryrefslogtreecommitdiff
path: root/gdb/stabsread.c
diff options
context:
space:
mode:
authorPierre Muller <muller@sourceware.org>2010-04-22 12:30:55 +0000
committerPierre Muller <muller@sourceware.org>2010-04-22 12:30:55 +0000
commit621791b854e8b14a82359ccd77f8dc436b7bfc43 (patch)
treee217140a1bbae6bffc29f8c7b44b24049a9f92fc /gdb/stabsread.c
parent105c2d85f7e0b7ac38ebb1e6f48f09f191274300 (diff)
downloadgdb-621791b854e8b14a82359ccd77f8dc436b7bfc43.zip
gdb-621791b854e8b14a82359ccd77f8dc436b7bfc43.tar.gz
gdb-621791b854e8b14a82359ccd77f8dc436b7bfc43.tar.bz2
PR stabs/11479.
* stabsread.c (set_length_in_type_chain): New function. (read_struct_type): Call set_length_in_type_chain function. (read_enum_type): Idem.
Diffstat (limited to 'gdb/stabsread.c')
-rw-r--r--gdb/stabsread.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index a6b8881..17aff06 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -3393,6 +3393,42 @@ complain_about_struct_wipeout (struct type *type)
_("struct/union type gets multiply defined: %s%s"), kind, name);
}
+/* Set the length for all variants of a same main_type, which are
+ connected in the closed chain.
+
+ This is something that needs to be done when a type is defined *after*
+ some cross references to this type have already been read. Consider
+ for instance the following scenario where we have the following two
+ stabs entries:
+
+ .stabs "t:p(0,21)=*(0,22)=k(0,23)=xsdummy:",160,0,28,-24
+ .stabs "dummy:T(0,23)=s16x:(0,1),0,3[...]"
+
+ A stubbed version of type dummy is created while processing the first
+ stabs entry. The length of that type is initially set to zero, since
+ it is unknown at this point. Also, a "constant" variation of type
+ "dummy" is created as well (this is the "(0,22)=k(0,23)" section of
+ the stabs line).
+
+ The second stabs entry allows us to replace the stubbed definition
+ with the real definition. However, we still need to adjust the length
+ of the "constant" variation of that type, as its length was left
+ untouched during the main type replacement... */
+
+static void
+set_length_in_type_chain (struct type * type)
+{
+ struct type *ntype = TYPE_CHAIN (type);
+
+ while (ntype != type)
+ {
+ if (TYPE_LENGTH(ntype) == 0)
+ TYPE_LENGTH (ntype) = TYPE_LENGTH (type);
+ else
+ complain_about_struct_wipeout (ntype);
+ ntype = TYPE_CHAIN (ntype);
+ }
+}
/* Read the description of a structure (or union type) and return an object
describing the type.
@@ -3451,6 +3487,7 @@ read_struct_type (char **pp, struct type *type, enum type_code type_code,
TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
+ set_length_in_type_chain (type);
}
/* Now read the baseclasses, if any, read the regular C struct or C++
@@ -3615,6 +3652,7 @@ read_enum_type (char **pp, struct type *type,
/* Now fill in the fields of the type-structure. */
TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT;
+ set_length_in_type_chain (type);
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_STUB (type) = 0;
if (unsigned_enum)