summaryrefslogtreecommitdiff
path: root/gdb/stabsread.c
diff options
context:
space:
mode:
authorJim Blandy <jimb@codesourcery.com>2002-05-04 00:02:50 +0000
committerJim Blandy <jimb@codesourcery.com>2002-05-04 00:02:50 +0000
commitd67a51785c119fb5f35b5a36ad6f5b5006a929c8 (patch)
tree25c1fc156d07919f19183545588f56fad00ef447 /gdb/stabsread.c
parentbde1f6489420259d5bb0c7a68f7c8b997ed6f72f (diff)
downloadgdb-d67a51785c119fb5f35b5a36ad6f5b5006a929c8.tar.gz
* stabsread.c (multiply_defined_struct): New complaint.
(read_struct_type): If the type we were passed isn't empty, or incomplete, don't read the new struct type into it; complain, and return the original type unchanged. Take a new `type_code' argument, which is the type code for the new type. (read_type): Rather than storing the type's type code here, pass it as an argument to read_struct_type, and let that take care of storing it. That way, we don't overwrite the original type code, so read_struct_type can use it to decide whether we're overwriting something we shouldn't. (complain_about_struct_wipeout): New function.
Diffstat (limited to 'gdb/stabsread.c')
-rw-r--r--gdb/stabsread.c91
1 files changed, 78 insertions, 13 deletions
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 671d4da46eb..74a873eb261 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -136,6 +136,7 @@ static int
attach_fields_to_type (struct field_info *, struct type *, struct objfile *);
static struct type *read_struct_type (char **, struct type *,
+ enum type_code,
struct objfile *);
static struct type *read_array_type (char **, struct type *,
@@ -2801,18 +2802,21 @@ again:
case 's': /* Struct type */
case 'u': /* Union type */
- type = dbx_alloc_type (typenums, objfile);
- switch (type_descriptor)
- {
- case 's':
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
- break;
- case 'u':
- TYPE_CODE (type) = TYPE_CODE_UNION;
- break;
- }
- type = read_struct_type (pp, type, objfile);
- break;
+ {
+ enum type_code type_code = TYPE_CODE_UNDEF;
+ type = dbx_alloc_type (typenums, objfile);
+ switch (type_descriptor)
+ {
+ case 's':
+ type_code = TYPE_CODE_STRUCT;
+ break;
+ case 'u':
+ type_code = TYPE_CODE_UNION;
+ break;
+ }
+ type = read_struct_type (pp, type, type_code, objfile);
+ break;
+ }
case 'a': /* Array type */
if (**pp != 'r')
@@ -4156,6 +4160,45 @@ attach_fields_to_type (struct field_info *fip, register struct type *type,
return 1;
}
+
+static struct complaint multiply_defined_struct =
+{"struct/union type gets multiply defined: %s%s", 0, 0};
+
+
+/* Complain that the compiler has emitted more than one definition for the
+ structure type TYPE. */
+static void
+complain_about_struct_wipeout (struct type *type)
+{
+ char *name = "";
+ char *kind = "";
+
+ if (TYPE_TAG_NAME (type))
+ {
+ name = TYPE_TAG_NAME (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT: kind = "struct "; break;
+ case TYPE_CODE_UNION: kind = "union "; break;
+ case TYPE_CODE_ENUM: kind = "enum "; break;
+ default: kind = "";
+ }
+ }
+ else if (TYPE_NAME (type))
+ {
+ name = TYPE_NAME (type);
+ kind = "";
+ }
+ else
+ {
+ name = "<unknown>";
+ kind = "";
+ }
+
+ complain (&multiply_defined_struct, kind, name);
+}
+
+
/* Read the description of a structure (or union type) and return an object
describing the type.
@@ -4171,7 +4214,8 @@ attach_fields_to_type (struct field_info *fip, register struct type *type,
*/
static struct type *
-read_struct_type (char **pp, struct type *type, struct objfile *objfile)
+read_struct_type (char **pp, struct type *type, enum type_code type_code,
+ struct objfile *objfile)
{
struct cleanup *back_to;
struct field_info fi;
@@ -4179,9 +4223,30 @@ read_struct_type (char **pp, struct type *type, struct objfile *objfile)
fi.list = NULL;
fi.fnlist = NULL;
+ /* When describing struct/union/class types in stabs, G++ always drops
+ all qualifications from the name. So if you've got:
+ struct A { ... struct B { ... }; ... };
+ then G++ will emit stabs for `struct A::B' that call it simply
+ `struct B'. Obviously, if you've got a real top-level definition for
+ `struct B', or other nested definitions, this is going to cause
+ problems.
+
+ Obviously, GDB can't fix this by itself, but it can at least avoid
+ scribbling on existing structure type objects when new definitions
+ appear. */
+ if (! (TYPE_CODE (type) == TYPE_CODE_UNDEF
+ || TYPE_STUB (type)))
+ {
+ complain_about_struct_wipeout (type);
+
+ /* It's probably best to return the type unchanged. */
+ return type;
+ }
+
back_to = make_cleanup (null_cleanup, 0);
INIT_CPLUS_SPECIFIC (type);
+ TYPE_CODE (type) = type_code;
TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
/* First comes the total size in bytes. */