X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fstabsread.c;h=b74f52befda314d73636f0f66cccd94bff75547b;hb=1e6982353631fce67c8b11e8f286395265caac49;hp=190fc15cf3ed6ad6d6efa84518075e1f5d9978f4;hpb=5832ed7e43b777bc93783dac030e92ad9bba75f7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 190fc15cf3..b74f52befd 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -1,6 +1,6 @@ /* Support routines for decoding "stabs" debugging information format. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -29,7 +29,7 @@ #include "defs.h" #include "gdb_string.h" #include "bfd.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -44,6 +44,8 @@ #include "demangle.h" #include "language.h" #include "doublest.h" +#include "cp-abi.h" +#include "cp-support.h" #include @@ -136,12 +138,13 @@ 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 *, struct objfile *); -static struct type **read_args (char **, int, struct objfile *); +static struct field *read_args (char **, int, struct objfile *, int *, int *); static int read_cpp_abbrev (struct field_info *, char **, struct type *, @@ -166,6 +169,8 @@ static int read_cfront_member_functions (struct field_info *, char **, struct type *, struct objfile *); +static char *find_name_end (char *name); + /* end new functions added for cfront support */ static void @@ -182,10 +187,8 @@ resolve_symbol_reference (struct objfile *, struct symbol *, char *); void stabsread_clear_cache (void); -static const char vptr_name[] = -{'_', 'v', 'p', 't', 'r', CPLUS_MARKER, '\0'}; -static const char vb_name[] = -{'_', 'v', 'b', CPLUS_MARKER, '\0'}; +static const char vptr_name[] = "_vptr$"; +static const char vb_name[] = "_vb$"; /* Define this as 1 if a pcc declaration of a char or short argument gives the correct address. Otherwise assume pcc gives the @@ -199,47 +202,31 @@ static const char vb_name[] = #define BELIEVE_PCC_PROMOTION_TYPE 0 #endif -static struct complaint invalid_cpp_abbrev_complaint = -{"invalid C++ abbreviation `%s'", 0, 0}; - -static struct complaint invalid_cpp_type_complaint = -{"C++ abbreviated type name unknown at symtab pos %d", 0, 0}; - -static struct complaint member_fn_complaint = -{"member function type missing, got '%c'", 0, 0}; - -static struct complaint const_vol_complaint = -{"const/volatile indicator missing, got '%c'", 0, 0}; - -static struct complaint error_type_complaint = -{"During symbol reading, couldn't parse type; debugger out of date?", 0, 0}; - -static struct complaint invalid_member_complaint = -{"invalid (minimal) member type data format at symtab pos %d.", 0, 0}; - -static struct complaint range_type_base_complaint = -{"base type %d of range type is not defined", 0, 0}; - -static struct complaint reg_value_complaint = -{"register number %d too large (max %d) in symbol %s", 0, 0}; - -static struct complaint vtbl_notfound_complaint = -{"virtual function table pointer not found when defining class `%s'", 0, 0}; - -static struct complaint unrecognized_cplus_name_complaint = -{"Unknown C++ symbol name `%s'", 0, 0}; - -static struct complaint rs6000_builtin_complaint = -{"Unknown builtin type %d", 0, 0}; +static void +invalid_cpp_abbrev_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "invalid C++ abbreviation `%s'", arg1); +} -static struct complaint unresolved_sym_chain_complaint = -{"%s: common block `%s' from global_sym_chain unresolved", 0, 0}; +static void +reg_value_complaint (int arg1, int arg2, const char *arg3) +{ + complaint (&symfile_complaints, + "register number %d too large (max %d) in symbol %s", arg1, arg2, + arg3); +} -static struct complaint stabs_general_complaint = -{"%s", 0, 0}; +static void +stabs_general_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "%s", arg1); +} -static struct complaint lrs_general_complaint = -{"%s", 0, 0}; +static void +lrs_general_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "%s", arg1); +} /* Make a list of forward references which haven't been defined. */ @@ -255,34 +242,6 @@ static struct symbol *current_symbol = NULL; *(pp) = next_symbol_text (objfile); \ } while (0) -/* FIXME: These probably should be our own types (like rs6000_builtin_type - has its own types) rather than builtin_type_*. */ -static struct type **os9k_type_vector[] = -{ - 0, - &builtin_type_int, - &builtin_type_char, - &builtin_type_long, - &builtin_type_short, - &builtin_type_unsigned_char, - &builtin_type_unsigned_short, - &builtin_type_unsigned_long, - &builtin_type_unsigned_int, - &builtin_type_float, - &builtin_type_double, - &builtin_type_void, - &builtin_type_long_double -}; - -static void os9k_init_type_vector (struct type **); - -static void -os9k_init_type_vector (struct type **tv) -{ - unsigned int i; - for (i = 0; i < sizeof (os9k_type_vector) / sizeof (struct type **); i++) - tv[i] = (os9k_type_vector[i] == 0 ? 0 : *(os9k_type_vector[i])); -} /* Look up a dbx type-number pair. Return the address of the slot where the type for that number-pair is stored. @@ -306,11 +265,9 @@ dbx_lookup_type (int typenums[2]) if (filenum < 0 || filenum >= n_this_object_header_files) { - static struct complaint msg = - {"\ -Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", - 0, 0}; - complain (&msg, filenum, index, symnum); + complaint (&symfile_complaints, + "Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", + filenum, index, symnum); goto error_return; } @@ -349,10 +306,6 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", (type_vector_length * sizeof (struct type *))); memset (&type_vector[old_len], 0, (type_vector_length - old_len) * sizeof (struct type *)); - - if (os9k_stabs) - /* Deal with OS9000 fundamental types. */ - os9k_init_type_vector (type_vector); } return (&type_vector[index]); } @@ -599,6 +552,12 @@ get_cfront_method_physname (char *fname) return p; } +static void +msg_unknown_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "Unsupported token in stabs string %s", arg1); +} + /* Read base classes within cfront class definition. eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; ^^^^^^^^^^^^^^^^^^ @@ -611,14 +570,6 @@ static int read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - static struct complaint msg_unknown = - {"\ - Unsupported token in stabs string %s.\n", - 0, 0}; - static struct complaint msg_notfound = - {"\ - Unable to find base type for %s.\n", - 0, 0}; int bnum = 0; char *p; int i; @@ -685,10 +636,9 @@ read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type, /* Bad visibility format. Complain and treat it as public. */ { - static struct complaint msg = - { - "Unknown visibility `%c' for baseclass", 0, 0}; - complain (&msg, new->visibility); + complaint (&symfile_complaints, + "Unknown visibility `%c' for baseclass", + new->visibility); new->visibility = VISIBILITY_PUBLIC; } } @@ -696,7 +646,7 @@ read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type, /* "@" comes next - eg: @Bvir */ if (**pp != '@') { - complain (&msg_unknown, *pp); + msg_unknown_complaint (*pp); return 1; } ++(*pp); @@ -724,7 +674,7 @@ read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type, bname = get_substring (pp, ';'); if (!bname || !*bname) { - complain (&msg_unknown, *pp); + msg_unknown_complaint (*pp); return 1; } /* FIXME! attach base info to type */ @@ -736,7 +686,8 @@ read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type, } else { - complain (&msg_notfound, *pp); + complaint (&symfile_complaints, "Unable to find base type for %s", + *pp); return 1; } } @@ -803,11 +754,8 @@ read_cfront_member_functions (struct field_info *fip, char **pp, ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /* demangled name */ if (!ref_func) { - static struct complaint msg = - {"\ - Unable to find function symbol for %s\n", - 0, 0}; - complain (&msg, fname); + complaint (&symfile_complaints, + "Unable to find function symbol for %s", fname); continue; } sublist = NULL; @@ -1063,7 +1011,7 @@ resolve_symbol_reference (struct objfile *objfile, struct symbol *sym, char *p) ref_sym = ref_search (refnum); if (!ref_sym) { - complain (&lrs_general_complaint, "symbol for reference not found"); + lrs_general_complaint ("symbol for reference not found"); return 0; } @@ -1099,7 +1047,7 @@ resolve_symbol_reference (struct objfile *objfile, struct symbol *sym, char *p) sizeof (struct alias_list)); if (!alias) { - complain (&lrs_general_complaint, "Unable to allocate alias list memory"); + lrs_general_complaint ("Unable to allocate alias list memory"); return 0; } @@ -1266,7 +1214,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, struct objfile *objfile) { register struct symbol *sym; - char *p = (char *) strchr (string, ':'); + char *p = (char *) find_name_end (string); int deftype; int synonym = 0; register int i; @@ -1354,7 +1302,8 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, #endif default: - complain (&unrecognized_cplus_name_complaint, string); + complaint (&symfile_complaints, "Unknown C++ symbol name `%s'", + string); goto normal; /* Do *something* with it */ } } @@ -1584,9 +1533,13 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC) SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); - /* All functions in C++ have prototypes. */ - if (SYMBOL_LANGUAGE (sym) == language_cplus) - TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED; + /* All functions in C++ have prototypes. Stabs does not offer an + explicit way to identify prototyped or unprototyped functions, + but both GCC and Sun CC emit stabs for the "call-as" type rather + than the "declared-as" type for unprototyped functions, so + we treat all functions as if they were prototyped. This is used + primarily for promotion when calling the function from GDB. */ + TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED; /* fall into process_prototype_types */ @@ -1806,9 +1759,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), - NUM_REGS + NUM_PSEUDO_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_SOURCE_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -1822,9 +1775,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), - NUM_REGS + NUM_PSEUDO_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_SOURCE_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -1903,6 +1856,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, break; case 't': + /* Typedef */ SYMBOL_TYPE (sym) = read_type (&p, objfile); /* For a nameless type, we don't want a create a symbol, thus we @@ -1998,7 +1952,8 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, a typedef for "foo". Unfortunately, cfront never makes the typedef when translating C++ into C. We make the typedef here so that "ptype foo" works as expected for cfront translated code. */ - else if (current_subfile->language == language_cplus) + else if ((current_subfile->language == language_cplus) + || (current_subfile->language == language_objc)) synonym = 1; SYMBOL_TYPE (sym) = read_type (&p, objfile); @@ -2050,9 +2005,6 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, } #endif SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (os9k_stabs) - add_symbol_to_list (sym, &global_symbols); - else add_symbol_to_list (sym, &local_symbols); break; @@ -2072,9 +2024,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), - NUM_REGS + NUM_PSEUDO_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_SOURCE_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -2169,7 +2121,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, p = strchr (p, ')'); if (!*p || *p != ')') { - complain (&lrs_general_complaint, "live range format not recognized"); + lrs_general_complaint ("live range format not recognized"); return NULL; } p++; @@ -2190,14 +2142,14 @@ resolve_live_range (struct objfile *objfile, struct symbol *sym, char *p) /* Sanity check the beginning of the stabs string. */ if (!*p || *p != 'l') { - complain (&lrs_general_complaint, "live range string 1"); + lrs_general_complaint ("live range string 1"); return 0; } p++; if (!*p || *p != '(') { - complain (&lrs_general_complaint, "live range string 2"); + lrs_general_complaint ("live range string 2"); return 0; } p++; @@ -2210,13 +2162,13 @@ resolve_live_range (struct objfile *objfile, struct symbol *sym, char *p) start = ref_search_value (refnum); if (!start) { - complain (&lrs_general_complaint, "Live range symbol not found 1"); + lrs_general_complaint ("Live range symbol not found 1"); return 0; } if (!*p || *p != ',') { - complain (&lrs_general_complaint, "live range string 3"); + lrs_general_complaint ("live range string 3"); return 0; } p++; @@ -2229,13 +2181,13 @@ resolve_live_range (struct objfile *objfile, struct symbol *sym, char *p) end = ref_search_value (refnum); if (!end) { - complain (&lrs_general_complaint, "Live range symbol not found 2"); + lrs_general_complaint ("Live range symbol not found 2"); return 0; } if (!*p || *p != ')') { - complain (&lrs_general_complaint, "live range string 4"); + lrs_general_complaint ("live range string 4"); return 0; } @@ -2257,7 +2209,7 @@ add_live_range (struct objfile *objfile, struct symbol *sym, CORE_ADDR start, if (start >= end) { - complain (&lrs_general_complaint, "end of live range follows start"); + lrs_general_complaint ("end of live range follows start"); return; } @@ -2314,7 +2266,7 @@ add_live_range (struct objfile *objfile, struct symbol *sym, CORE_ADDR start, static struct type * error_type (char **pp, struct objfile *objfile) { - complain (&error_type_complaint); + complaint (&symfile_complaints, "couldn't parse type; debugger out of date?"); while (1) { /* Skip to end of symbol. */ @@ -2358,6 +2310,9 @@ read_type (register char **pp, struct objfile *objfile) /* Used to distinguish string and bitstring from char-array and set. */ int is_string = 0; + /* Used to distinguish vector from array. */ + int is_vector = 0; + /* Read type number if present. The type number may be omitted. for instance in a two-dimensional array declared with type "ar1;1;10;ar1;1;10;4". */ @@ -2421,9 +2376,8 @@ again: { /* Complain and keep going, so compilers can invent new cross-reference types. */ - static struct complaint msg = - {"Unrecognized cross-reference type `%c'", 0, 0}; - complain (&msg, (*pp)[0]); + complaint (&symfile_complaints, + "Unrecognized cross-reference type `%c'", (*pp)[0]); code = TYPE_CODE_STRUCT; break; } @@ -2536,7 +2490,24 @@ again: the related problems with unnecessarily stubbed types; someone motivated should attempt to clean up the issue here as well. Once a type pointed to has been created it - should not be modified. */ + should not be modified. + + Well, it's not *absolutely* wrong. Constructing recursive + types (trees, linked lists) necessarily entails modifying + types after creating them. Constructing any loop structure + entails side effects. The Dwarf 2 reader does handle this + more gracefully (it never constructs more than once + instance of a type object, so it doesn't have to copy type + objects wholesale), but it still mutates type objects after + other folks have references to them. + + Keep in mind that this circularity/mutation issue shows up + at the source language level, too: C's "incomplete types", + for example. So the proper cleanup, I think, would be to + limit GDB's type smashing to match exactly those required + by the source language. So GDB could have a + "complete_this_type" function, but never create unnecessary + copies of a type otherwise. */ replace_type (type, xtype); TYPE_NAME (type) = NULL; TYPE_TAG_NAME (type) = NULL; @@ -2556,7 +2527,7 @@ again: forward-referenced), and we must change it to a pointer, function, reference, or whatever, *in-place*. */ - case '*': + case '*': /* Pointer to another type */ type1 = read_type (pp, objfile); type = make_pointer_type (type1, dbx_lookup_type (typenums)); break; @@ -2567,21 +2538,6 @@ again: break; case 'f': /* Function returning another type */ - if (os9k_stabs && **pp == '(') - { - /* Function prototype; parse it. - We must conditionalize this on os9k_stabs because otherwise - it could be confused with a Sun-style (1,3) typenumber - (I think). */ - struct type *t; - ++*pp; - while (**pp != ')') - { - t = read_type (pp, objfile); - if (**pp == ',') - ++ * pp; - } - } type1 = read_type (pp, objfile); type = make_function_type (type1, dbx_lookup_type (typenums)); break; @@ -2626,11 +2582,9 @@ again: ++*pp; else { - static struct complaint msg = { - "Prototyped function type didn't end arguments with `#':\n%s", - 0, 0 - }; - complain (&msg, type_start); + complaint (&symfile_complaints, + "Prototyped function type didn't end arguments with `#':\n%s", + type_start); } /* If there is just one argument whose type is `void', then @@ -2662,22 +2616,12 @@ again: } case 'k': /* Const qualifier on some type (Sun) */ - case 'c': /* Const qualifier on some type (OS9000) */ - /* Because 'c' means other things to AIX and 'k' is perfectly good, - only accept 'c' in the os9k_stabs case. */ - if (type_descriptor == 'c' && !os9k_stabs) - return error_type (pp, objfile); type = read_type (pp, objfile); type = make_cv_type (1, TYPE_VOLATILE (type), type, dbx_lookup_type (typenums)); break; case 'B': /* Volatile qual on some type (Sun) */ - case 'i': /* Volatile qual on some type (OS9000) */ - /* Because 'i' means other things to AIX and 'B' is perfectly good, - only accept 'i' in the os9k_stabs case. */ - if (type_descriptor == 'i' && !os9k_stabs) - return error_type (pp, objfile); type = read_type (pp, objfile); type = make_cv_type (TYPE_CONST (type), 1, type, dbx_lookup_type (typenums)); @@ -2714,16 +2658,22 @@ again: switch (*attr) { - case 's': + case 's': /* Size attribute */ type_size = atoi (attr + 1); if (type_size <= 0) type_size = -1; break; - case 'S': + case 'S': /* String attribute */ + /* FIXME: check to see if following type is array? */ is_string = 1; break; + case 'V': /* Vector attribute */ + /* FIXME: check to see if following type is array? */ + is_vector = 1; + break; + default: /* Ignore unrecognized type attributes, so future compilers can invent new ones. */ @@ -2743,7 +2693,9 @@ again: (*pp)++; return_type = read_type (pp, objfile); if (*(*pp)++ != ';') - complain (&invalid_member_complaint, symnum); + complaint (&symfile_complaints, + "invalid (minimal) member type data format at symtab pos %d.", + symnum); type = allocate_stub_method (return_type); if (typenums[0] != -1) *dbx_lookup_type (typenums) = type; @@ -2752,7 +2704,8 @@ again: { struct type *domain = read_type (pp, objfile); struct type *return_type; - struct type **args; + struct field *args; + int nargs, varargs; if (**pp != ',') /* Invalid member type data format. */ @@ -2761,9 +2714,10 @@ again: ++(*pp); return_type = read_type (pp, objfile); - args = read_args (pp, ';', objfile); + args = read_args (pp, ';', objfile, &nargs, &varargs); type = dbx_alloc_type (typenums, objfile); - smash_to_method_type (type, domain, return_type, args); + smash_to_method_type (type, domain, return_type, args, + nargs, varargs); } break; @@ -2774,10 +2728,6 @@ again: break; case 'b': - if (os9k_stabs) - /* Const and volatile qualified type. */ - type = read_type (pp, objfile); - else { /* Sun ACC builtin int type */ type = read_sun_builtin_type (pp, typenums, objfile); @@ -2801,18 +2751,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') @@ -2823,9 +2776,11 @@ again: type = read_array_type (pp, type, objfile); if (is_string) TYPE_CODE (type) = TYPE_CODE_STRING; + if (is_vector) + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; break; - case 'S': + case 'S': /* Set or bitstring type */ type1 = read_type (pp, objfile); type = create_set_type ((struct type *) NULL, type1); if (is_string) @@ -2867,7 +2822,7 @@ rs6000_builtin_type (int typenum) if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED) { - complain (&rs6000_builtin_complaint, typenum); + complaint (&symfile_complaints, "Unknown builtin type %d", typenum); return builtin_type_error; } if (negative_types[-typenum] != NULL) @@ -2978,10 +2933,14 @@ rs6000_builtin_type (int typenum) case 25: /* Complex type consisting of two IEEE single precision values. */ rettype = init_type (TYPE_CODE_COMPLEX, 8, 0, "complex", NULL); + TYPE_TARGET_TYPE (rettype) = init_type (TYPE_CODE_FLT, 4, 0, "float", + NULL); break; case 26: /* Complex type consisting of two IEEE double precision values. */ rettype = init_type (TYPE_CODE_COMPLEX, 16, 0, "double complex", NULL); + TYPE_TARGET_TYPE (rettype) = init_type (TYPE_CODE_FLT, 8, 0, "double", + NULL); break; case 27: rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL); @@ -3016,6 +2975,27 @@ rs6000_builtin_type (int typenum) /* This page contains subroutines of read_type. */ +/* Replace *OLD_NAME with the method name portion of PHYSNAME. */ + +static void +update_method_name_from_physname (char **old_name, char *physname) +{ + char *method_name; + + method_name = method_name_from_physname (physname); + + if (method_name == NULL) + error ("bad physname %s\n", physname); + + if (strcmp (*old_name, method_name) != 0) + { + xfree (*old_name); + *old_name = method_name; + } + else + xfree (method_name); +} + /* Read member function stabs info for C++ classes. The form of each member function data is: @@ -3037,7 +3017,6 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, { int nfn_fields = 0; int length = 0; - int skip_method; /* Total number of member functions defined in this class. If the class defines two `f' functions, and one `g' function, then this will have the value 3. */ @@ -3077,36 +3056,6 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, look_ahead_type = NULL; length = 0; - skip_method = 0; - if (p - *pp == strlen ("__base_ctor") - && strncmp (*pp, "__base_ctor", strlen ("__base_ctor")) == 0) - skip_method = 1; - else if (p - *pp == strlen ("__base_dtor") - && strncmp (*pp, "__base_dtor", strlen ("__base_dtor")) == 0) - skip_method = 1; - else if (p - *pp == strlen ("__deleting_dtor") - && strncmp (*pp, "__deleting_dtor", - strlen ("__deleting_dtor")) == 0) - skip_method = 1; - - if (skip_method) - { - /* Skip past '::'. */ - *pp = p + 2; - /* Read the type. */ - read_type (pp, objfile); - /* Skip past the colon, mangled name, semicolon, flags, and final - semicolon. */ - while (**pp != ';') - (*pp) ++; - (*pp) ++; - while (**pp != ';') - (*pp) ++; - (*pp) ++; - - continue; - } - new_fnlist = (struct next_fnfieldlist *) xmalloc (sizeof (struct next_fnfieldlist)); make_cleanup (xfree, new_fnlist); @@ -3123,8 +3072,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, /* This lets the user type "break operator+". We could just put in "+" as the name, but that wouldn't work for "*". */ - static char opname[32] = - {'o', 'p', CPLUS_MARKER}; + static char opname[32] = "op$"; char *o = opname + 3; /* Skip past '::'. */ @@ -3232,7 +3180,8 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, case '.': break; default: - complain (&const_vol_complaint, **pp); + complaint (&symfile_complaints, + "const/volatile indicator missing, got '%c'", **pp); break; } @@ -3287,17 +3236,35 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, } case '?': /* static member function. */ - new_sublist->fn_field.voffset = VOFFSET_STATIC; - if (strncmp (new_sublist->fn_field.physname, - main_fn_name, strlen (main_fn_name))) - { - new_sublist->fn_field.is_stub = 1; - } - break; + { + int slen = strlen (main_fn_name); + + new_sublist->fn_field.voffset = VOFFSET_STATIC; + + /* For static member functions, we can't tell if they + are stubbed, as they are put out as functions, and not as + methods. + GCC v2 emits the fully mangled name if + dbxout.c:flag_minimal_debug is not set, so we have to + detect a fully mangled physname here and set is_stub + accordingly. Fully mangled physnames in v2 start with + the member function name, followed by two underscores. + GCC v3 currently always emits stubbed member functions, + but with fully mangled physnames, which start with _Z. */ + if (!(strncmp (new_sublist->fn_field.physname, + main_fn_name, slen) == 0 + && new_sublist->fn_field.physname[slen] == '_' + && new_sublist->fn_field.physname[slen + 1] == '_')) + { + new_sublist->fn_field.is_stub = 1; + } + break; + } default: /* error */ - complain (&member_fn_complaint, (*pp)[-1]); + complaint (&symfile_complaints, + "member function type missing, got '%c'", (*pp)[-1]); /* Fall through into normal member function. */ case '.': @@ -3315,23 +3282,192 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, while (**pp != ';' && **pp != '\0'); (*pp)++; + STABS_CONTINUE (pp, objfile); - new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct fn_field) * length); - memset (new_fnlist->fn_fieldlist.fn_fields, 0, - sizeof (struct fn_field) * length); - for (i = length; (i--, sublist); sublist = sublist->next) + /* Skip GCC 3.X member functions which are duplicates of the callable + constructor/destructor. */ + if (strcmp (main_fn_name, "__base_ctor") == 0 + || strcmp (main_fn_name, "__base_dtor") == 0 + || strcmp (main_fn_name, "__deleting_dtor") == 0) { - new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field; + xfree (main_fn_name); } + else + { + int has_stub = 0; + int has_destructor = 0, has_other = 0; + int is_v3 = 0; + struct next_fnfield *tmp_sublist; + + /* Various versions of GCC emit various mostly-useless + strings in the name field for special member functions. + + For stub methods, we need to defer correcting the name + until we are ready to unstub the method, because the current + name string is used by gdb_mangle_name. The only stub methods + of concern here are GNU v2 operators; other methods have their + names correct (see caveat below). + + For non-stub methods, in GNU v3, we have a complete physname. + Therefore we can safely correct the name now. This primarily + affects constructors and destructors, whose name will be + __comp_ctor or __comp_dtor instead of Foo or ~Foo. Cast + operators will also have incorrect names; for instance, + "operator int" will be named "operator i" (i.e. the type is + mangled). + + For non-stub methods in GNU v2, we have no easy way to + know if we have a complete physname or not. For most + methods the result depends on the platform (if CPLUS_MARKER + can be `$' or `.', it will use minimal debug information, or + otherwise the full physname will be included). + + Rather than dealing with this, we take a different approach. + For v3 mangled names, we can use the full physname; for v2, + we use cplus_demangle_opname (which is actually v2 specific), + because the only interesting names are all operators - once again + barring the caveat below. Skip this process if any method in the + group is a stub, to prevent our fouling up the workings of + gdb_mangle_name. + + The caveat: GCC 2.95.x (and earlier?) put constructors and + destructors in the same method group. We need to split this + into two groups, because they should have different names. + So for each method group we check whether it contains both + routines whose physname appears to be a destructor (the physnames + for and destructors are always provided, due to quirks in v2 + mangling) and routines whose physname does not appear to be a + destructor. If so then we break up the list into two halves. + Even if the constructors and destructors aren't in the same group + the destructor will still lack the leading tilde, so that also + needs to be fixed. + + So, to summarize what we expect and handle here: + + Given Given Real Real Action + method name physname physname method name + + __opi [none] __opi__3Foo operator int opname + [now or later] + Foo _._3Foo _._3Foo ~Foo separate and + rename + operator i _ZN3FoocviEv _ZN3FoocviEv operator int demangle + __comp_ctor _ZN3FooC1ERKS_ _ZN3FooC1ERKS_ Foo demangle + */ + + tmp_sublist = sublist; + while (tmp_sublist != NULL) + { + if (tmp_sublist->fn_field.is_stub) + has_stub = 1; + if (tmp_sublist->fn_field.physname[0] == '_' + && tmp_sublist->fn_field.physname[1] == 'Z') + is_v3 = 1; + + if (is_destructor_name (tmp_sublist->fn_field.physname)) + has_destructor++; + else + has_other++; - new_fnlist->fn_fieldlist.length = length; - new_fnlist->next = fip->fnlist; - fip->fnlist = new_fnlist; - nfn_fields++; - total_length += length; - STABS_CONTINUE (pp, objfile); + tmp_sublist = tmp_sublist->next; + } + + if (has_destructor && has_other) + { + struct next_fnfieldlist *destr_fnlist; + struct next_fnfield *last_sublist; + + /* Create a new fn_fieldlist for the destructors. */ + + destr_fnlist = (struct next_fnfieldlist *) + xmalloc (sizeof (struct next_fnfieldlist)); + make_cleanup (xfree, destr_fnlist); + memset (destr_fnlist, 0, sizeof (struct next_fnfieldlist)); + destr_fnlist->fn_fieldlist.name + = obconcat (&objfile->type_obstack, "", "~", + new_fnlist->fn_fieldlist.name); + + destr_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile->type_obstack, + sizeof (struct fn_field) * has_destructor); + memset (destr_fnlist->fn_fieldlist.fn_fields, 0, + sizeof (struct fn_field) * has_destructor); + tmp_sublist = sublist; + last_sublist = NULL; + i = 0; + while (tmp_sublist != NULL) + { + if (!is_destructor_name (tmp_sublist->fn_field.physname)) + { + tmp_sublist = tmp_sublist->next; + continue; + } + + destr_fnlist->fn_fieldlist.fn_fields[i++] + = tmp_sublist->fn_field; + if (last_sublist) + last_sublist->next = tmp_sublist->next; + else + sublist = tmp_sublist->next; + last_sublist = tmp_sublist; + tmp_sublist = tmp_sublist->next; + } + + destr_fnlist->fn_fieldlist.length = has_destructor; + destr_fnlist->next = fip->fnlist; + fip->fnlist = destr_fnlist; + nfn_fields++; + total_length += has_destructor; + length -= has_destructor; + } + else if (is_v3) + { + /* v3 mangling prevents the use of abbreviated physnames, + so we can do this here. There are stubbed methods in v3 + only: + - in -gstabs instead of -gstabs+ + - or for static methods, which are output as a function type + instead of a method type. */ + + update_method_name_from_physname (&new_fnlist->fn_fieldlist.name, + sublist->fn_field.physname); + } + else if (has_destructor && new_fnlist->fn_fieldlist.name[0] != '~') + { + new_fnlist->fn_fieldlist.name = concat ("~", main_fn_name, NULL); + xfree (main_fn_name); + } + else if (!has_stub) + { + char dem_opname[256]; + int ret; + ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name, + dem_opname, DMGL_ANSI); + if (!ret) + ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name, + dem_opname, 0); + if (ret) + new_fnlist->fn_fieldlist.name + = obsavestring (dem_opname, strlen (dem_opname), + &objfile->type_obstack); + } + + new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile->type_obstack, + sizeof (struct fn_field) * length); + memset (new_fnlist->fn_fieldlist.fn_fields, 0, + sizeof (struct fn_field) * length); + for (i = length; (i--, sublist); sublist = sublist->next) + { + new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field; + } + + new_fnlist->fn_fieldlist.length = length; + new_fnlist->next = fip->fnlist; + fip->fnlist = new_fnlist; + nfn_fields++; + total_length += length; + } } if (nfn_fields) @@ -3393,7 +3529,9 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, name = type_name_no_tag (context); if (name == NULL) { - complain (&invalid_cpp_type_complaint, symnum); + complaint (&symfile_complaints, + "C++ abbreviated type name unknown at symtab pos %d", + symnum); name = "FOO"; } fip->list->field.name = @@ -3401,7 +3539,7 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, break; default: - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); fip->list->field.name = obconcat (&objfile->type_obstack, "INVALID_CPLUSPLUS_ABBREV", "", ""); @@ -3414,7 +3552,7 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, p = ++(*pp); if (p[-1] != ':') { - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); return 0; } fip->list->field.type = read_type (pp, objfile); @@ -3435,7 +3573,7 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, } else { - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); /* We have no idea what syntax an unrecognized abbrev would have, so better return 0. If we returned 1, we would need to at least advance *pp to avoid an infinite loop. */ @@ -3519,7 +3657,7 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p, else if (**pp != ',') { /* Bad structure-type format. */ - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } @@ -3530,13 +3668,13 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p, FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits); if (nbits != 0) { - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits); if (nbits != 0) { - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } } @@ -3630,8 +3768,6 @@ read_struct_fields (struct field_info *fip, char **pp, struct type *type, while (**pp != ';' && **pp != '\0') { - if (os9k_stabs && **pp == ',') - break; STABS_CONTINUE (pp, objfile); /* Get space to record the next field's data. */ new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); @@ -3676,8 +3812,9 @@ read_struct_fields (struct field_info *fip, char **pp, struct type *type, } if (p[0] == ':' && p[1] == ':') { - /* chill the list of fields: the last entry (at the head) is a - partially constructed entry which we now scrub. */ + /* (the deleted) chill the list of fields: the last entry (at + the head) is a partially constructed entry which we now + scrub. */ fip->list = fip->list->next; } return 1; @@ -3773,10 +3910,8 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type, default: /* Unknown character. Complain and treat it as non-virtual. */ { - static struct complaint msg = - { - "Unknown virtual character `%c' for baseclass", 0, 0}; - complain (&msg, **pp); + complaint (&symfile_complaints, + "Unknown virtual character `%c' for baseclass", **pp); } } ++(*pp); @@ -3792,11 +3927,9 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type, /* Bad visibility format. Complain and treat it as public. */ { - static struct complaint msg = - { - "Unknown visibility `%c' for baseclass", 0, 0 - }; - complain (&msg, new->visibility); + complaint (&symfile_complaints, + "Unknown visibility `%c' for baseclass", + new->visibility); new->visibility = VISIBILITY_PUBLIC; } } @@ -3893,15 +4026,18 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, i >= TYPE_N_BASECLASSES (t); --i) { - if (!strncmp (TYPE_FIELD_NAME (t, i), vptr_name, - sizeof (vptr_name) - 1)) + char *name = TYPE_FIELD_NAME (t, i); + if (!strncmp (name, vptr_name, sizeof (vptr_name) - 2) + && is_cplus_marker (name[sizeof (vptr_name) - 2])) { TYPE_VPTR_FIELDNO (type) = i; goto gotit; } } /* Virtual function table field not found. */ - complain (&vtbl_notfound_complaint, TYPE_NAME (type)); + complaint (&symfile_complaints, + "virtual function table pointer not found when defining class `%s'", + TYPE_NAME (type)); return 0; } else @@ -3964,11 +4100,8 @@ read_cfront_static_fields (struct field_info *fip, char **pp, struct type *type, ref_static = lookup_symbol (sname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name */ if (!ref_static) { - static struct complaint msg = - {"\ - Unable to find symbol for static data field %s\n", - 0, 0}; - complain (&msg, sname); + complaint (&symfile_complaints, + "Unable to find symbol for static data field %s", sname); continue; } stype = SYMBOL_TYPE (ref_static); @@ -4143,10 +4276,8 @@ attach_fields_to_type (struct field_info *fip, register struct type *type, default: /* Unknown visibility. Complain and treat it as public. */ { - static struct complaint msg = - { - "Unknown visibility `%c' for field", 0, 0}; - complain (&msg, fip->list->visibility); + complaint (&symfile_complaints, "Unknown visibility `%c' for field", + fip->list->visibility); } break; } @@ -4155,6 +4286,42 @@ attach_fields_to_type (struct field_info *fip, register struct type *type, return 1; } + +/* 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 = ""; + kind = ""; + } + + complaint (&symfile_complaints, + "struct/union type gets multiply defined: %s%s", kind, name); +} + + /* Read the description of a structure (or union type) and return an object describing the type. @@ -4170,7 +4337,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; @@ -4178,9 +4346,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. */ @@ -4207,8 +4396,6 @@ read_struct_type (char **pp, struct type *type, struct objfile *objfile) type = error_type (pp, objfile); } - /* Fix up any cv-qualified versions of this type. */ - finish_cv_type (type); do_cleanups (back_to); return (type); } @@ -4234,9 +4421,6 @@ read_array_type (register char **pp, register struct type *type, Fortran adjustable arrays use Adigits or Tdigits for lower or upper; for these, produce a type like float[][]. */ - if (os9k_stabs) - index_type = builtin_type_int; - else { index_type = read_type (pp, objfile); if (**pp != ';') @@ -4250,7 +4434,8 @@ read_array_type (register char **pp, register struct type *type, (*pp)++; adjustable = 1; } - lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits); + lower = read_huge_number (pp, ';', &nbits); + if (nbits != 0) return error_type (pp, objfile); @@ -4310,16 +4495,6 @@ read_enum_type (register char **pp, register struct type *type, osyms = *symlist; o_nsyms = osyms ? osyms->nsyms : 0; - if (os9k_stabs) - { - /* Size. Perhaps this does not have to be conditionalized on - os9k_stabs (assuming the name of an enum constant can't start - with a digit). */ - read_huge_number (pp, 0, &nbits); - if (nbits != 0) - return error_type (pp, objfile); - } - /* The aix4 compiler emits an extra field before the enum members; my guess is it's a type of some sort. Just ignore it. */ if (**pp == '-') @@ -4494,6 +4669,7 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile) int nbits; int details; int nbytes; + struct type *rettype; /* The first number has more details about the type, for example FN_COMPLEX. */ @@ -4508,9 +4684,12 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile) if (details == NF_COMPLEX || details == NF_COMPLEX16 || details == NF_COMPLEX32) - /* This is a type we can't handle, but we do know the size. - We also will be able to give it a name. */ - return init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile); + { + rettype = init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile); + TYPE_TARGET_TYPE (rettype) + = init_type (TYPE_CODE_FLT, nbytes / 2, 0, NULL, objfile); + return rettype; + } return init_type (TYPE_CODE_FLT, nbytes, 0, NULL, objfile); } @@ -4553,10 +4732,7 @@ read_huge_number (char **pp, int end, int *bits) p++; } - if (os9k_stabs) - upper_limit = ULONG_MAX / radix; - else - upper_limit = LONG_MAX / radix; + upper_limit = LONG_MAX / radix; while ((c = *p++) >= '0' && c < ('0' + radix)) { @@ -4752,10 +4928,6 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile) else if (self_subrange && n2 == 0 && n3 == 127) return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile); - else if (current_symbol && SYMBOL_LANGUAGE (current_symbol) == language_chill - && !self_subrange) - goto handle_true_range; - /* We used to do this only for subrange of self or subrange of int. */ else if (n2 == 0) { @@ -4816,7 +4988,8 @@ handle_true_range: static struct type *range_type_index; - complain (&range_type_base_complaint, rangenums[1]); + complaint (&symfile_complaints, + "base type %d of range type is not defined", rangenums[1]); if (range_type_index == NULL) range_type_index = init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, @@ -4832,38 +5005,39 @@ handle_true_range: and terminated with END. Return the list of types read in, or (struct type **)-1 if there is an error. */ -static struct type ** -read_args (char **pp, int end, struct objfile *objfile) +static struct field * +read_args (char **pp, int end, struct objfile *objfile, int *nargsp, + int *varargsp) { /* FIXME! Remove this arbitrary limit! */ - struct type *types[1024], **rval; /* allow for fns of 1023 parameters */ - int n = 0; + struct type *types[1024]; /* allow for fns of 1023 parameters */ + int n = 0, i; + struct field *rval; while (**pp != end) { if (**pp != ',') /* Invalid argument list: no ','. */ - return (struct type **) -1; + return (struct field *) -1; (*pp)++; STABS_CONTINUE (pp, objfile); types[n++] = read_type (pp, objfile); } (*pp)++; /* get past `end' (the ':' character) */ - if (n == 1) - { - rval = (struct type **) xmalloc (2 * sizeof (struct type *)); - } - else if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID) - { - rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *)); - memset (rval + n, 0, sizeof (struct type *)); - } + if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID) + *varargsp = 1; else { - rval = (struct type **) xmalloc (n * sizeof (struct type *)); + n--; + *varargsp = 0; } - memcpy (rval, types, n * sizeof (struct type *)); + + rval = (struct field *) xmalloc (n * sizeof (struct field)); + memset (rval, 0, n * sizeof (struct field)); + for (i = 0; i < n; i++) + rval[i].type = types[i]; + *nargsp = n; return rval; } @@ -4891,11 +5065,8 @@ common_block_start (char *name, struct objfile *objfile) { if (common_block_name != NULL) { - static struct complaint msg = - { - "Invalid symbol data: common block within common block", - 0, 0}; - complain (&msg); + complaint (&symfile_complaints, + "Invalid symbol data: common block within common block"); } common_block = local_symbols; common_block_i = local_symbols ? local_symbols->nsyms : 0; @@ -4921,9 +5092,7 @@ common_block_end (struct objfile *objfile) if (common_block_name == NULL) { - static struct complaint msg = - {"ECOMM symbol unmatched by BCOMM", 0, 0}; - complain (&msg); + complaint (&symfile_complaints, "ECOMM symbol unmatched by BCOMM"); return; } @@ -5036,9 +5205,7 @@ cleanup_undefined_types (void) if (typename == NULL) { - static struct complaint msg = - {"need a type name", 0, 0}; - complain (&msg); + complaint (&symfile_complaints, "need a type name"); break; } for (ppt = file_symbols; ppt; ppt = ppt->next) @@ -5052,10 +5219,7 @@ cleanup_undefined_types (void) && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE (*type)) && STREQ (SYMBOL_NAME (sym), typename)) - { - memcpy (*type, SYMBOL_TYPE (sym), - sizeof (struct type)); - } + replace_type (*type, SYMBOL_TYPE (sym)); } } } @@ -5064,10 +5228,9 @@ cleanup_undefined_types (void) default: { - static struct complaint msg = - {"\ -GDB internal error. cleanup_undefined_types with bad type %d.", 0, 0}; - complain (&msg, TYPE_CODE (*type)); + complaint (&symfile_complaints, + "GDB internal error. cleanup_undefined_types with bad type %d.", + TYPE_CODE (*type)); } break; } @@ -5227,8 +5390,9 @@ scan_file_globals (struct objfile *objfile) if (SYMBOL_CLASS (prev) == LOC_STATIC) SYMBOL_CLASS (prev) = LOC_UNRESOLVED; else - complain (&unresolved_sym_chain_complaint, - objfile->name, SYMBOL_NAME (prev)); + complaint (&symfile_complaints, + "%s: common block `%s' from global_sym_chain unresolved", + objfile->name, SYMBOL_NAME (prev)); } } memset (global_sym_chain, 0, sizeof (global_sym_chain)); @@ -5268,8 +5432,6 @@ start_stabs (void) /* FIXME: If common_block_name is not already NULL, we should complain(). */ common_block_name = NULL; - - os9k_stabs = 0; } /* Call after end_symtab() */ @@ -5297,6 +5459,32 @@ finish_global_stabs (struct objfile *objfile) } } +/* Find the end of the name, delimited by a ':', but don't match + ObjC symbols which look like -[Foo bar::]:bla. */ +static char * +find_name_end (char *name) +{ + char *s = name; + if (s[0] == '-' || *s == '+') + { + /* Must be an ObjC method symbol. */ + if (s[1] != '[') + { + error ("invalid symbol name \"%s\"", name); + } + s = strchr (s, ']'); + if (s == NULL) + { + error ("invalid symbol name \"%s\"", name); + } + return strchr (s, ':'); + } + else + { + return strchr (s, ':'); + } +} + /* Initializer for this module */ void