X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fstabsread.c;h=428cbc2e8bfb0516a43fa00529e9bd66a2cc67a1;hb=745818a50b0318ea46aaca2facedb0a32f62e7f9;hp=ae3802bb6a4864da60332c435e9f14bb5be332ea;hpb=b8c9b27d1e133d46199734ca1f047af8bb2d3314;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/stabsread.c b/gdb/stabsread.c index ae3802bb6a..428cbc2e8b 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -1,5 +1,7 @@ /* Support routines for decoding "stabs" debugging information format. - Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + + Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GDB. @@ -16,8 +18,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* Support routines for reading and decoding debugging information in the "stabs" format. This format is used with many systems that use @@ -28,7 +30,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" @@ -42,6 +44,9 @@ #include "complaints.h" #include "demangle.h" #include "language.h" +#include "doublest.h" +#include "cp-abi.h" +#include "cp-support.h" #include @@ -85,11 +90,9 @@ static void read_one_struct_field (struct field_info *, char **, char *, struct type *, struct objfile *); -static char *get_substring (char **, int); - static struct type *dbx_alloc_type (int[2], struct objfile *); -static long read_huge_number (char **, int, int *); +static long read_huge_number (char **, int, int *, int); static struct type *error_type (char **, struct objfile *); @@ -101,7 +104,9 @@ static void fix_common_block (struct symbol *, int); static int read_type_number (char **, int *); -static struct type *read_range_type (char **, int[2], struct objfile *); +static struct type *read_type (char **, struct objfile *); + +static struct type *read_range_type (char **, int[2], int, struct objfile *); static struct type *read_sun_builtin_type (char **, int[2], struct objfile *); @@ -130,60 +135,32 @@ read_tilde_fields (struct field_info *, char **, struct type *, static int attach_fn_fields_to_type (struct field_info *, struct type *); -static int -attach_fields_to_type (struct field_info *, struct type *, struct objfile *); +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 void add_undefined_type (struct type *); static int read_cpp_abbrev (struct field_info *, char **, struct type *, struct objfile *); -/* new functions added for cfront support */ - -static int -copy_cfront_struct_fields (struct field_info *, struct type *, - struct objfile *); - -static char *get_cfront_method_physname (char *); - -static int -read_cfront_baseclasses (struct field_info *, char **, - struct type *, struct objfile *); - -static int -read_cfront_static_fields (struct field_info *, char **, - struct type *, struct objfile *); -static int -read_cfront_member_functions (struct field_info *, char **, - struct type *, struct objfile *); - -/* end new functions added for cfront support */ - -static void -add_live_range (struct objfile *, struct symbol *, CORE_ADDR, CORE_ADDR); - -static int resolve_live_range (struct objfile *, struct symbol *, char *); +static char *find_name_end (char *name); static int process_reference (char **string); -static CORE_ADDR ref_search_value (int refnum); - -static int -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 @@ -193,51 +170,26 @@ static const char vb_name[] = #if !defined (BELIEVE_PCC_PROMOTION) #define BELIEVE_PCC_PROMOTION 0 #endif -#if !defined (BELIEVE_PCC_PROMOTION_TYPE) -#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 = -{"debug info mismatch between compiler and debugger", 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 struct complaint unresolved_sym_chain_complaint = -{"%s: common block `%s' from global_sym_chain unresolved", 0, 0}; +static void +invalid_cpp_abbrev_complaint (const char *arg1) +{ + complaint (&symfile_complaints, _("invalid C++ abbreviation `%s'"), arg1); +} -static struct complaint stabs_general_complaint = -{"%s", 0, 0}; +static void +reg_value_complaint (int regnum, int num_regs, const char *sym) +{ + complaint (&symfile_complaints, + _("register number %d too large (max %d) in symbol %s"), + regnum, num_regs - 1, sym); +} -static struct complaint lrs_general_complaint = -{"%s", 0, 0}; +static void +stabs_general_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "%s", arg1); +} /* Make a list of forward references which haven't been defined. */ @@ -253,34 +205,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. @@ -289,14 +213,14 @@ os9k_init_type_vector (struct type **tv) This can be used for finding the type associated with that pair or for associating a new type with the pair. */ -struct type ** +static struct type ** dbx_lookup_type (int typenums[2]) { - register int filenum = typenums[0]; - register int index = typenums[1]; + int filenum = typenums[0]; + int index = typenums[1]; unsigned old_len; - register int real_filenum; - register struct header_file *f; + int real_filenum; + struct header_file *f; int f_orig_length; if (filenum == -1) /* -1,-1 is for temporary types. */ @@ -304,11 +228,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; } @@ -347,10 +269,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]); } @@ -363,7 +281,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", struct type *temp_type; struct type **temp_type_p; - warning ("GDB internal error: bad real_filenum"); + warning (_("GDB internal error: bad real_filenum")); error_return: temp_type = init_type (TYPE_CODE_ERROR, 0, 0, NULL, NULL); @@ -399,7 +317,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", static struct type * dbx_alloc_type (int typenums[2], struct objfile *objfile) { - register struct type **type_addr; + struct type **type_addr; if (typenums[0] == -1) { @@ -461,14 +379,14 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs, ld will remove it from the executable. There is then a N_GSYM stab for it, but no regular (C_EXT) symbol. */ sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - SYMBOL_NAME (sym) = - obsavestring (name, pp - name, &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = + obsavestring (name, pp - name, &objfile->objfile_obstack); pp += 2; if (*(pp - 1) == 'F' || *(pp - 1) == 'f') { @@ -511,23 +429,23 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs, Returns 0 for success, -1 for error. */ static int -read_type_number (register char **pp, register int *typenums) +read_type_number (char **pp, int *typenums) { int nbits; if (**pp == '(') { (*pp)++; - typenums[0] = read_huge_number (pp, ',', &nbits); + typenums[0] = read_huge_number (pp, ',', &nbits, 0); if (nbits != 0) return -1; - typenums[1] = read_huge_number (pp, ')', &nbits); + typenums[1] = read_huge_number (pp, ')', &nbits, 0); if (nbits != 0) return -1; } else { typenums[0] = 0; - typenums[1] = read_huge_number (pp, 0, &nbits); + typenums[1] = read_huge_number (pp, 0, &nbits, 0); if (nbits != 0) return -1; } @@ -540,596 +458,6 @@ read_type_number (register char **pp, register int *typenums) #define VISIBILITY_PUBLIC '2' /* Stabs character for public field */ #define VISIBILITY_IGNORE '9' /* Optimized out or zero length */ -#define CFRONT_VISIBILITY_PRIVATE '2' /* Stabs character for private field */ -#define CFRONT_VISIBILITY_PUBLIC '1' /* Stabs character for public field */ - -/* This code added to support parsing of ARM/Cfront stabs strings */ - -/* Get substring from string up to char c, advance string pointer past - suibstring. */ - -static char * -get_substring (char **p, int c) -{ - char *str; - str = *p; - *p = strchr (*p, c); - if (*p) - { - **p = 0; - (*p)++; - } - else - str = 0; - return str; -} - -/* Physname gets strcat'd onto sname in order to recreate the mangled - name (see funtion gdb_mangle_name in gdbtypes.c). For cfront, make - the physname look like that of g++ - take out the initial mangling - eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */ - -static char * -get_cfront_method_physname (char *fname) -{ - int len = 0; - /* FIXME would like to make this generic for g++ too, but - that is already handled in read_member_funcctions */ - char *p = fname; - - /* search ahead to find the start of the mangled suffix */ - if (*p == '_' && *(p + 1) == '_') /* compiler generated; probably a ctor/dtor */ - p += 2; - while (p && (unsigned) ((p + 1) - fname) < strlen (fname) && *(p + 1) != '_') - p = strchr (p, '_'); - if (!(p && *p == '_' && *(p + 1) == '_')) - error ("Invalid mangled function name %s", fname); - p += 2; /* advance past '__' */ - - /* struct name length and name of type should come next; advance past it */ - while (isdigit (*p)) - { - len = len * 10 + (*p - '0'); - p++; - } - p += len; - - return p; -} - -/* Read base classes within cfront class definition. - eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; - ^^^^^^^^^^^^^^^^^^ - - A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; - ^ - */ - -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; - struct nextfield *new; - - if (**pp == ';') /* no base classes; return */ - { - ++(*pp); - return 1; - } - - /* first count base classes so we can allocate space before parsing */ - for (p = *pp; p && *p && *p != ';'; p++) - { - if (*p == ' ') - bnum++; - } - bnum++; /* add one more for last one */ - - /* now parse the base classes until we get to the start of the methods - (code extracted and munged from read_baseclasses) */ - ALLOCATE_CPLUS_STRUCT_TYPE (type); - TYPE_N_BASECLASSES (type) = bnum; - - /* allocate space */ - { - int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type)); - char *pointer; - - pointer = (char *) TYPE_ALLOC (type, num_bytes); - TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer; - } - B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type)); - - for (i = 0; i < TYPE_N_BASECLASSES (type); i++) - { - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (xfree, new); - memset (new, 0, sizeof (struct nextfield)); - new->next = fip->list; - fip->list = new; - FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */ - - STABS_CONTINUE (pp, objfile); - - /* virtual? eg: v2@Bvir */ - if (**pp == 'v') - { - SET_TYPE_FIELD_VIRTUAL (type, i); - ++(*pp); - } - - /* access? eg: 2@Bvir */ - /* Note: protected inheritance not supported in cfront */ - switch (*(*pp)++) - { - case CFRONT_VISIBILITY_PRIVATE: - new->visibility = VISIBILITY_PRIVATE; - break; - case CFRONT_VISIBILITY_PUBLIC: - new->visibility = VISIBILITY_PUBLIC; - break; - default: - /* Bad visibility format. Complain and treat it as - public. */ - { - static struct complaint msg = - { - "Unknown visibility `%c' for baseclass", 0, 0}; - complain (&msg, new->visibility); - new->visibility = VISIBILITY_PUBLIC; - } - } - - /* "@" comes next - eg: @Bvir */ - if (**pp != '@') - { - complain (&msg_unknown, *pp); - return 1; - } - ++(*pp); - - - /* Set the bit offset of the portion of the object corresponding - to this baseclass. Always zero in the absence of - multiple inheritance. */ - /* Unable to read bit position from stabs; - Assuming no multiple inheritance for now FIXME! */ - /* We may have read this in the structure definition; - now we should fixup the members to be the actual base classes */ - FIELD_BITPOS (new->field) = 0; - - /* Get the base class name and type */ - { - char *bname; /* base class name */ - struct symbol *bsym; /* base class */ - char *p1, *p2; - p1 = strchr (*pp, ' '); - p2 = strchr (*pp, ';'); - if (p1 < p2) - bname = get_substring (pp, ' '); - else - bname = get_substring (pp, ';'); - if (!bname || !*bname) - { - complain (&msg_unknown, *pp); - return 1; - } - /* FIXME! attach base info to type */ - bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name */ - if (bsym) - { - new->field.type = SYMBOL_TYPE (bsym); - new->field.name = type_name_no_tag (new->field.type); - } - else - { - complain (&msg_notfound, *pp); - return 1; - } - } - - /* If more base classes to parse, loop again. - We ate the last ' ' or ';' in get_substring, - so on exit we will have skipped the trailing ';' */ - /* if invalid, return 0; add code to detect - FIXME! */ - } - return 1; -} - -/* read cfront member functions. - pp points to string starting with list of functions - eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ - -static int -read_cfront_member_functions (struct field_info *fip, char **pp, - struct type *type, struct objfile *objfile) -{ - /* This code extracted from read_member_functions - so as to do the similar thing for our funcs */ - - int nfn_fields = 0; - int length = 0; - /* 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. */ - int total_length = 0; - int i; - struct next_fnfield - { - struct next_fnfield *next; - struct fn_field fn_field; - } - *sublist; - struct type *look_ahead_type; - struct next_fnfieldlist *new_fnlist; - struct next_fnfield *new_sublist; - char *main_fn_name; - char *fname; - struct symbol *ref_func = 0; - - /* Process each list until we find the end of the member functions. - eg: p = "__ct__1AFv foo__1AFv ;;;" */ - - STABS_CONTINUE (pp, objfile); /* handle \\ */ - - while (**pp != ';' && (fname = get_substring (pp, ' '), fname)) - { - int is_static = 0; - int sublist_count = 0; - char *pname; - if (fname[0] == '*') /* static member */ - { - is_static = 1; - sublist_count++; - fname++; - } - 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); - continue; - } - sublist = NULL; - look_ahead_type = NULL; - length = 0; - - new_fnlist = (struct next_fnfieldlist *) - xmalloc (sizeof (struct next_fnfieldlist)); - make_cleanup (xfree, new_fnlist); - memset (new_fnlist, 0, sizeof (struct next_fnfieldlist)); - - /* The following is code to work around cfront generated stabs. - The stabs contains full mangled name for each field. - We try to demangle the name and extract the field name out of it. */ - { - char *dem, *dem_p, *dem_args; - int dem_len; - dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS); - if (dem != NULL) - { - dem_p = strrchr (dem, ':'); - if (dem_p != 0 && *(dem_p - 1) == ':') - dem_p++; - /* get rid of args */ - dem_args = strchr (dem_p, '('); - if (dem_args == NULL) - dem_len = strlen (dem_p); - else - dem_len = dem_args - dem_p; - main_fn_name = - obsavestring (dem_p, dem_len, &objfile->type_obstack); - } - else - { - main_fn_name = - obsavestring (fname, strlen (fname), &objfile->type_obstack); - } - } /* end of code for cfront work around */ - - new_fnlist->fn_fieldlist.name = main_fn_name; - -/*-------------------------------------------------*/ - /* Set up the sublists - Sublists are stuff like args, static, visibility, etc. - so in ARM, we have to set that info some other way. - Multiple sublists happen if overloading - eg: foo::26=##1;:;2A.; - In g++, we'd loop here thru all the sublists... */ - - new_sublist = - (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield)); - make_cleanup (xfree, new_sublist); - memset (new_sublist, 0, sizeof (struct next_fnfield)); - - /* eat 1; from :;2A.; */ - new_sublist->fn_field.type = SYMBOL_TYPE (ref_func); /* normally takes a read_type */ - /* Make this type look like a method stub for gdb */ - TYPE_FLAGS (new_sublist->fn_field.type) |= TYPE_FLAG_STUB; - TYPE_CODE (new_sublist->fn_field.type) = TYPE_CODE_METHOD; - - /* If this is just a stub, then we don't have the real name here. */ - if (TYPE_FLAGS (new_sublist->fn_field.type) & TYPE_FLAG_STUB) - { - if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type)) - TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type; - new_sublist->fn_field.is_stub = 1; - } - - /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i - physname gets strcat'd in order to recreate the onto mangled name */ - pname = get_cfront_method_physname (fname); - new_sublist->fn_field.physname = savestring (pname, strlen (pname)); - - - /* Set this member function's visibility fields. - Unable to distinguish access from stabs definition! - Assuming public for now. FIXME! - (for private, set new_sublist->fn_field.is_private = 1, - for public, set new_sublist->fn_field.is_protected = 1) */ - - /* Unable to distinguish const/volatile from stabs definition! - Assuming normal for now. FIXME! */ - - new_sublist->fn_field.is_const = 0; - new_sublist->fn_field.is_volatile = 0; /* volatile not implemented in cfront */ - - /* Set virtual/static function info - How to get vtable offsets ? - Assuming normal for now FIXME!! - For vtables, figure out from whence this virtual function came. - It may belong to virtual function table of - one of its baseclasses. - set: - new_sublist -> fn_field.voffset = vtable offset, - new_sublist -> fn_field.fcontext = look_ahead_type; - where look_ahead_type is type of baseclass */ - if (is_static) - new_sublist->fn_field.voffset = VOFFSET_STATIC; - else /* normal member function. */ - new_sublist->fn_field.voffset = 0; - new_sublist->fn_field.fcontext = 0; - - - /* Prepare new sublist */ - new_sublist->next = sublist; - sublist = new_sublist; - length++; - - /* In g++, we loop thu sublists - now we set from functions. */ - 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; - STABS_CONTINUE (pp, objfile); /* handle \\ */ - } /* end of loop */ - - if (nfn_fields) - { - /* type should already have space */ - TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) - TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields); - memset (TYPE_FN_FIELDLISTS (type), 0, - sizeof (struct fn_fieldlist) * nfn_fields); - TYPE_NFN_FIELDS (type) = nfn_fields; - TYPE_NFN_FIELDS_TOTAL (type) = total_length; - } - - /* end of scope for reading member func */ - - /* eg: ";;" */ - - /* Skip trailing ';' and bump count of number of fields seen */ - if (**pp == ';') - (*pp)++; - else - return 0; - return 1; -} - -/* This routine fixes up partial cfront types that were created - while parsing the stabs. The main need for this function is - to add information such as methods to classes. - Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */ -int -resolve_cfront_continuation (struct objfile *objfile, struct symbol *sym, - char *p) -{ - struct symbol *ref_sym = 0; - char *sname; - /* snarfed from read_struct_type */ - struct field_info fi; - struct type *type; - struct cleanup *back_to; - - /* Need to make sure that fi isn't gunna conflict with struct - in case struct already had some fnfs */ - fi.list = NULL; - fi.fnlist = NULL; - back_to = make_cleanup (null_cleanup, 0); - - /* We only accept structs, classes and unions at the moment. - Other continuation types include t (typedef), r (long dbl), ... - We may want to add support for them as well; - right now they are handled by duplicating the symbol information - into the type information (see define_symbol) */ - if (*p != 's' /* structs */ - && *p != 'c' /* class */ - && *p != 'u') /* union */ - return 0; /* only handle C++ types */ - p++; - - /* Get symbol typs name and validate - eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */ - sname = get_substring (&p, ';'); - if (!sname || strcmp (sname, SYMBOL_NAME (sym))) - error ("Internal error: base symbol type name does not match\n"); - - /* Find symbol's internal gdb reference using demangled_name. - This is the real sym that we want; - sym was a temp hack to make debugger happy */ - ref_sym = lookup_symbol (SYMBOL_NAME (sym), 0, STRUCT_NAMESPACE, 0, 0); - type = SYMBOL_TYPE (ref_sym); - - - /* Now read the baseclasses, if any, read the regular C struct or C++ - class member fields, attach the fields to the type, read the C++ - member functions, attach them to the type, and then read any tilde - field (baseclass specifier for the class holding the main vtable). */ - - if (!read_cfront_baseclasses (&fi, &p, type, objfile) - /* g++ does this next, but cfront already did this: - || !read_struct_fields (&fi, &p, type, objfile) */ - || !copy_cfront_struct_fields (&fi, type, objfile) - || !read_cfront_member_functions (&fi, &p, type, objfile) - || !read_cfront_static_fields (&fi, &p, type, objfile) - || !attach_fields_to_type (&fi, type, objfile) - || !attach_fn_fields_to_type (&fi, type) - /* g++ does this next, but cfront doesn't seem to have this: - || !read_tilde_fields (&fi, &p, type, objfile) */ - ) - { - type = error_type (&p, objfile); - } - - do_cleanups (back_to); - return 0; -} -/* End of code added to support parsing of ARM/Cfront stabs strings */ - - -/* This routine fixes up symbol references/aliases to point to the original - symbol definition. Returns 0 on failure, non-zero on success. */ - -static int -resolve_symbol_reference (struct objfile *objfile, struct symbol *sym, char *p) -{ - int refnum; - struct symbol *ref_sym = 0; - struct alias_list *alias; - - /* If this is not a symbol reference return now. */ - if (*p != '#') - return 0; - - /* Use "#" as the name; we'll fix the name later. - We stored the original symbol name as "#=" - so we can now search for "#" to resolving the reference. - We'll fix the names later by removing the "#" or "#=" */ - -/*---------------------------------------------------------*/ - /* Get the reference id number, and - advance p past the names so we can parse the rest. - eg: id=2 for p : "2=", "2=z:r(0,1)" "2:r(0,1);l(#5,#6),l(#7,#4)" */ -/*---------------------------------------------------------*/ - - /* This gets reference name from string. sym may not have a name. */ - - /* Get the reference number associated with the reference id in the - gdb stab string. From that reference number, get the main/primary - symbol for this alias. */ - refnum = process_reference (&p); - ref_sym = ref_search (refnum); - if (!ref_sym) - { - complain (&lrs_general_complaint, "symbol for reference not found"); - return 0; - } - - /* Parse the stab of the referencing symbol - now that we have the referenced symbol. - Add it as a new symbol and a link back to the referenced symbol. - eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */ - - - /* If the stab symbol table and string contain: - RSYM 0 5 00000000 868 #15=z:r(0,1) - LBRAC 0 0 00000000 899 #5= - SLINE 0 16 00000003 923 #6= - Then the same symbols can be later referenced by: - RSYM 0 5 00000000 927 #15:r(0,1);l(#5,#6) - This is used in live range splitting to: - 1) specify that a symbol (#15) is actually just a new storage - class for a symbol (#15=z) which was previously defined. - 2) specify that the beginning and ending ranges for a symbol - (#15) are the values of the beginning (#5) and ending (#6) - symbols. */ - - /* Read number as reference id. - eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */ - /* FIXME! Might I want to use SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - in case of "l(0,0)"? */ - -/*--------------------------------------------------*/ - /* Add this symbol to the reference list. */ -/*--------------------------------------------------*/ - - alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack, - sizeof (struct alias_list)); - if (!alias) - { - complain (&lrs_general_complaint, "Unable to allocate alias list memory"); - return 0; - } - - alias->next = 0; - alias->sym = sym; - - if (!SYMBOL_ALIASES (ref_sym)) - { - SYMBOL_ALIASES (ref_sym) = alias; - } - else - { - struct alias_list *temp; - - /* Get to the end of the list. */ - for (temp = SYMBOL_ALIASES (ref_sym); - temp->next; - temp = temp->next) - ; - temp->next = alias; - } - - /* Want to fix up name so that other functions (eg. valops) - will correctly print the name. - Don't add_symbol_to_list so that lookup_symbol won't find it. - nope... needed for fixups. */ - SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym); - - /* Done! */ - return 1; -} - /* Structure for storing pointers to reference definitions for fast lookup during "process_later". */ @@ -1196,16 +524,6 @@ ref_search (int refnum) return ref_map[refnum].sym; } -/* Return value for the reference REFNUM. */ - -static CORE_ADDR -ref_search_value (int refnum) -{ - if (refnum < 0 || refnum > ref_count) - return 0; - return ref_map[refnum].value; -} - /* Parse a reference id in STRING and return the resulting reference number. Move STRING beyond the reference id. */ @@ -1258,16 +576,15 @@ symbol_reference_defined (char **string) } } -/* ARGSUSED */ struct symbol * define_symbol (CORE_ADDR valu, char *string, int desc, int type, struct objfile *objfile) { - register struct symbol *sym; - char *p = (char *) strchr (string, ':'); + struct symbol *sym; + char *p = (char *) find_name_end (string); int deftype; int synonym = 0; - register int i; + int i; /* We would like to eliminate nameless symbols, but keep their types. E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer @@ -1295,7 +612,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, nameless = (p == string || ((string[0] == ' ') && (string[1] == ':'))); current_symbol = sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); switch (type & N_TYPE) @@ -1328,17 +645,17 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, switch (string[1]) { case 't': - SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"), - &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"), + &objfile->objfile_obstack); break; case 'v': /* $vtbl_ptr_type */ - /* Was: SYMBOL_NAME (sym) = "vptr"; */ + /* Was: DEPRECATED_SYMBOL_NAME (sym) = "vptr"; */ goto normal; case 'e': - SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"), - &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"), + &objfile->objfile_obstack); break; case '_': @@ -1352,82 +669,16 @@ 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 */ } } - else if (string[0] == '#') - { - /* Special GNU C extension for referencing symbols. */ - char *s; - int refnum, nlen; - - /* If STRING defines a new reference id, then add it to the - reference map. Else it must be referring to a previously - defined symbol, so add it to the alias list of the previously - defined symbol. */ - s = string; - refnum = symbol_reference_defined (&s); - if (refnum >= 0) - ref_add (refnum, sym, string, SYMBOL_VALUE (sym)); - else if (!resolve_symbol_reference (objfile, sym, string)) - return NULL; - - /* S..P contains the name of the symbol. We need to store - the correct name into SYMBOL_NAME. */ - nlen = p - s; - if (refnum >= 0) - { - if (nlen > 0) - { - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, nlen); - strncpy (SYMBOL_NAME (sym), s, nlen); - SYMBOL_NAME (sym)[nlen] = '\0'; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - } - else - /* FIXME! Want SYMBOL_NAME (sym) = 0; - Get error if leave name 0. So give it something. */ - { - nlen = p - string; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, nlen); - strncpy (SYMBOL_NAME (sym), string, nlen); - SYMBOL_NAME (sym)[nlen] = '\0'; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - } - } - /* Advance STRING beyond the reference id. */ - string = s; - } else { normal: SYMBOL_LANGUAGE (sym) = current_subfile->language; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, ((p - string) + 1)); - /* Open-coded memcpy--saves function call time. */ - /* FIXME: Does it really? Try replacing with simple strcpy and - try it on an executable with a large symbol table. */ - /* FIXME: considering that gcc can open code memcpy anyway, I - doubt it. xoxorich. */ - { - register char *p1 = string; - register char *p2 = SYMBOL_NAME (sym); - while (p1 != p) - { - *p2++ = *p1++; - } - *p2++ = '\0'; - } - - /* If this symbol is from a C++ compilation, then attempt to cache the - demangled form for future reference. This is a typical time versus - space tradeoff, that was decided in favor of time because it sped up - C++ symbol lookups by a factor of about 20. */ - - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, string, p - string, objfile); } p++; @@ -1461,7 +712,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, { SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_TYPE (sym) = error_type (&p, objfile); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); return sym; } @@ -1471,7 +722,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, case 'r': { double d = atof (p); - char *dbl_valu; + gdb_byte *dbl_valu; /* FIXME-if-picky-about-floating-accuracy: Should be using target arithmetic to get the value. real.c in GCC @@ -1486,10 +737,10 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile, FT_DBL_PREC_FLOAT); - dbl_valu = (char *) - obstack_alloc (&objfile->symbol_obstack, + dbl_valu = + obstack_alloc (&objfile->objfile_obstack, TYPE_LENGTH (SYMBOL_TYPE (sym))); - store_floating (dbl_valu, TYPE_LENGTH (SYMBOL_TYPE (sym)), d); + store_typed_floating (dbl_valu, SYMBOL_TYPE (sym), d); SYMBOL_VALUE_BYTES (sym) = dbl_valu; SYMBOL_CLASS (sym) = LOC_CONST_BYTES; } @@ -1554,7 +805,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = error_type (&p, objfile); } } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); return sym; @@ -1562,7 +813,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* The name of a caught exception. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_LABEL; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE_ADDRESS (sym) = valu; add_symbol_to_list (sym, &local_symbols); break; @@ -1571,7 +822,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* A static function definition. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); /* fall into process_function_types. */ @@ -1582,9 +833,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 */ @@ -1626,7 +881,8 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, FIXME: Do we need a new builtin_type_promoted_int_arg ? */ if (TYPE_CODE (ptype) == TYPE_CODE_VOID) ptype = builtin_type_int; - TYPE_FIELD_TYPE (ftype, nparams++) = ptype; + TYPE_FIELD_TYPE (ftype, nparams) = ptype; + TYPE_FIELD_ARTIFICIAL (ftype, nparams++) = 0; } TYPE_NFIELDS (ftype) = nparams; TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED; @@ -1637,7 +893,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* A global function definition. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &global_symbols); goto process_function_types; @@ -1648,14 +904,14 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, These definitions appear at the end of the namelist. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; /* Don't add symbol references to global_sym_chain. Symbol references don't have valid names and wont't match up with minimal symbols when the global_sym_chain is relocated. We'll fixup symbol references when we fixup the defining symbol. */ - if (SYMBOL_NAME (sym) && SYMBOL_NAME (sym)[0] != '#') + if (DEPRECATED_SYMBOL_NAME (sym) && DEPRECATED_SYMBOL_NAME (sym)[0] != '#') { - i = hashname (SYMBOL_NAME (sym)); + i = hashname (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; global_sym_chain[i] = sym; } @@ -1670,7 +926,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_LOCAL; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -1688,18 +944,12 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, else SYMBOL_TYPE (sym) = read_type (&p, objfile); - /* Normally this is a parameter, a LOC_ARG. On the i960, it - can also be a LOC_LOCAL_ARG depending on symbol type. */ -#ifndef DBX_PARM_SYMBOL_CLASS -#define DBX_PARM_SYMBOL_CLASS(type) LOC_ARG -#endif - - SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type); + SYMBOL_CLASS (sym) = LOC_ARG; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); - if (TARGET_BYTE_ORDER != BIG_ENDIAN) + if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG) { /* On little-endian machines, this crud is never necessary, and, if the extra bytes contain garbage, is harmful. */ @@ -1728,61 +978,17 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, TYPE_FLAG_UNSIGNED, "unsigned int", NULL); - if (BELIEVE_PCC_PROMOTION_TYPE) + /* If PCC says a parameter is a short or a char, it is + really an int. */ + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type) + && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) { - /* This is defined on machines (e.g. sparc) where we - should believe the type of a PCC 'short' argument, - but shouldn't believe the address (the address is the - address of the corresponding int). - - My guess is that this correction, as opposed to - changing the parameter to an 'int' (as done below, - for PCC on most machines), is the right thing to do - on all machines, but I don't want to risk breaking - something that already works. On most PCC machines, - the sparc problem doesn't come up because the calling - function has to zero the top bytes (not knowing - whether the called function wants an int or a short), - so there is little practical difference between an - int and a short (except perhaps what happens when the - GDB user types "print short_arg = 0x10000;"). - - Hacked for SunOS 4.1 by gnu@cygnus.com. In 4.1, the - compiler actually produces the correct address (we - don't need to fix it up). I made this code adapt so - that it will offset the symbol if it was pointing at - an int-aligned location and not otherwise. This way - you can use the same gdb for 4.0.x and 4.1 systems. - - If the parameter is shorter than an int, and is - integral (e.g. char, short, or unsigned equivalent), - and is claimed to be passed on an integer boundary, - don't believe it! Offset the parameter's address to - the tail-end of that integer. */ - - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT - && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (pcc_promotion_type)) - { - SYMBOL_VALUE (sym) += TYPE_LENGTH (pcc_promotion_type) - - TYPE_LENGTH (SYMBOL_TYPE (sym)); - } - break; - } - else - { - /* If PCC says a parameter is a short or a char, - it is really an int. */ - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) - { - SYMBOL_TYPE (sym) = - TYPE_UNSIGNED (SYMBOL_TYPE (sym)) - ? pcc_unsigned_promotion_type - : pcc_promotion_type; - } - break; + SYMBOL_TYPE (sym) = + TYPE_UNSIGNED (SYMBOL_TYPE (sym)) + ? pcc_unsigned_promotion_type + : pcc_promotion_type; } + break; } case 'P': @@ -1801,13 +1007,14 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_REGPARM; SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); - if (SYMBOL_VALUE (sym) >= NUM_REGS) + if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), NUM_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_PRINT_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -1816,26 +1023,30 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_REGISTER; SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); - if (SYMBOL_VALUE (sym) >= NUM_REGS) + if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), NUM_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_PRINT_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; if (within_function) { - /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same - name to represent an argument passed in a register. - GCC uses 'P' for the same case. So if we find such a symbol pair - we combine it into one 'P' symbol. For Sun cc we need to do this - regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out - the 'p' symbol even if it never saves the argument onto the stack. - - On most machines, we want to preserve both symbols, so that - we can still get information about what is going on with the - stack (VAX for computing args_printed, using stack slots instead - of saved registers in backtraces, etc.). + /* Sun cc uses a pair of symbols, one 'p' and one 'r', with + the same name to represent an argument passed in a + register. GCC uses 'P' for the same case. So if we find + such a symbol pair we combine it into one 'P' symbol. + For Sun cc we need to do this regardless of + stabs_argument_has_addr, because the compiler puts out + the 'p' symbol even if it never saves the argument onto + the stack. + + On most machines, we want to preserve both symbols, so + that we can still get information about what is going on + with the stack (VAX for computing args_printed, using + stack slots instead of saved registers in backtraces, + etc.). Note that this code illegally combines main(argc) struct foo argc; { register struct foo argc; } @@ -1844,22 +1055,15 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (local_symbols && local_symbols->nsyms > 0 -#ifndef USE_REGISTER_NOT_ARG - && REG_STRUCT_HAS_ADDR_P () - && REG_STRUCT_HAS_ADDR (processing_gcc_compilation, - SYMBOL_TYPE (sym)) - && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING) -#endif - ) + && gdbarch_stabs_argument_has_addr (current_gdbarch, + SYMBOL_TYPE (sym))) { struct symbol *prev_sym; prev_sym = local_symbols->symbol[local_symbols->nsyms - 1]; if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG || SYMBOL_CLASS (prev_sym) == LOC_ARG) - && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME (sym))) + && strcmp (DEPRECATED_SYMBOL_NAME (prev_sym), + DEPRECATED_SYMBOL_NAME (sym)) == 0) { SYMBOL_CLASS (prev_sym) = LOC_REGPARM; /* Use the type from the LOC_REGISTER; that is the type @@ -1882,22 +1086,23 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; #ifdef STATIC_TRANSFORM_NAME - if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym))) + if (IS_STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym))) { struct minimal_symbol *msym; - msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, objfile); if (msym != NULL) { - SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym); } } #endif - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); 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 @@ -1907,7 +1112,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; /* C++ vagaries: we may have a type which is derived from a base type which did not have its name defined when the derived class was output. We fill in the derived class's @@ -1932,7 +1137,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, extern const char vtbl_ptr_name[]; if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR - && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name)) + && strcmp (DEPRECATED_SYMBOL_NAME (sym), vtbl_ptr_name)) || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC) { /* If we are giving a name to a type such as "pointer to @@ -1972,11 +1177,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* Pascal accepts names for pointer types. */ if (current_subfile->language == language_pascal) { - TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym); + TYPE_NAME (SYMBOL_TYPE (sym)) = DEPRECATED_SYMBOL_NAME (sym); } } else - TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym); + TYPE_NAME (SYMBOL_TYPE (sym)) = DEPRECATED_SYMBOL_NAME (sym); } add_symbol_to_list (sym, &file_symbols); @@ -1989,15 +1194,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (synonym) p++; - /* The semantics of C++ state that "struct foo { ... }" also defines - 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) - synonym = 1; SYMBOL_TYPE (sym) = read_type (&p, objfile); - + /* For a nameless type, we don't want a create a symbol, thus we did not use `sym'. Return without further processing. */ if (nameless) @@ -2005,24 +1204,24 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_TAG_NAME (SYMBOL_TYPE (sym)) - = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym)); + = obconcat (&objfile->objfile_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym)); add_symbol_to_list (sym, &file_symbols); if (synonym) { /* Clone the sym and then modify it. */ - register struct symbol *typedef_sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + struct symbol *typedef_sym = (struct symbol *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); *typedef_sym = *sym; SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF; SYMBOL_VALUE (typedef_sym) = valu; - SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) - = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym)); + = obconcat (&objfile->objfile_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym)); add_symbol_to_list (typedef_sym, &file_symbols); } break; @@ -2033,21 +1232,18 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; #ifdef STATIC_TRANSFORM_NAME - if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym))) + if (IS_STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym))) { struct minimal_symbol *msym; - msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, objfile); if (msym != NULL) { - SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym); } } #endif - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (os9k_stabs) - add_symbol_to_list (sym, &global_symbols); - else + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -2056,7 +1252,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_REF_ARG; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -2065,216 +1261,57 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); - if (SYMBOL_VALUE (sym) >= NUM_REGS) + if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), NUM_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_PRINT_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); - break; - - case 'X': - /* This is used by Sun FORTRAN for "function result value". - Sun claims ("dbx and dbxtool interfaces", 2nd ed) - that Pascal uses it too, but when I tried it Pascal used - "x:3" (local symbol) instead. */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_LOCAL; - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); - break; - - /* New code added to support cfront stabs strings. - Note: case 'P' already handled above */ - case 'Z': - /* Cfront type continuation coming up! - Find the original definition and add to it. - We'll have to do this for the typedef too, - since we cloned the symbol to define a type in read_type. - Stabs info examples: - __1C :Ztl - foo__1CFv :ZtF (first def foo__1CFv:F(0,3);(0,24)) - C:ZsC;;__ct__1CFv func1__1CFv func2__1CFv ... ;;; - where C is the name of the class. - Unfortunately, we can't lookup the original symbol yet 'cuz - we haven't finished reading all the symbols. - Instead, we save it for processing later */ - process_later (sym, p, resolve_cfront_continuation); - SYMBOL_TYPE (sym) = error_type (&p, objfile); /* FIXME! change later */ - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_VALUE (sym) = 0; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - /* Don't add to list - we'll delete it later when - we add the continuation to the real sym */ - return sym; - /* End of new code added to support cfront stabs strings */ - - default: - SYMBOL_TYPE (sym) = error_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_VALUE (sym) = 0; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &file_symbols); - break; - } - - /* When passing structures to a function, some systems sometimes pass - the address in a register, not the structure itself. */ - - if (REG_STRUCT_HAS_ADDR_P () - && REG_STRUCT_HAS_ADDR (processing_gcc_compilation, SYMBOL_TYPE (sym)) - && (SYMBOL_CLASS (sym) == LOC_REGPARM || SYMBOL_CLASS (sym) == LOC_ARG)) - { - struct type *symbol_type = check_typedef (SYMBOL_TYPE (sym)); - - if ((TYPE_CODE (symbol_type) == TYPE_CODE_STRUCT) - || (TYPE_CODE (symbol_type) == TYPE_CODE_UNION) - || (TYPE_CODE (symbol_type) == TYPE_CODE_BITSTRING) - || (TYPE_CODE (symbol_type) == TYPE_CODE_SET)) - { - /* If REG_STRUCT_HAS_ADDR yields non-zero we have to convert - LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */ - if (SYMBOL_CLASS (sym) == LOC_REGPARM) - SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; - /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th - and subsequent arguments on the sparc, for example). */ - else if (SYMBOL_CLASS (sym) == LOC_ARG) - SYMBOL_CLASS (sym) = LOC_REF_ARG; - } - } - - /* Is there more to parse? For example LRS/alias information? */ - while (*p && *p == ';') - { - p++; - if (*p && p[0] == 'l' && p[1] == '(') - { - /* GNU extensions for live range splitting may be appended to - the end of the stab string. eg. "l(#1,#2);l(#3,#5)" */ - - /* Resolve the live range and add it to SYM's live range list. */ - if (!resolve_live_range (objfile, sym, p)) - return NULL; - - /* Find end of live range info. */ - p = strchr (p, ')'); - if (!*p || *p != ')') - { - complain (&lrs_general_complaint, "live range format not recognized"); - return NULL; - } - p++; - } - } - return sym; -} - -/* Add the live range found in P to the symbol SYM in objfile OBJFILE. Returns - non-zero on success, zero otherwise. */ - -static int -resolve_live_range (struct objfile *objfile, struct symbol *sym, char *p) -{ - int refnum; - CORE_ADDR start, end; - - /* Sanity check the beginning of the stabs string. */ - if (!*p || *p != 'l') - { - complain (&lrs_general_complaint, "live range string 1"); - return 0; - } - p++; - - if (!*p || *p != '(') - { - complain (&lrs_general_complaint, "live range string 2"); - return 0; - } - p++; - - /* Get starting value of range and advance P past the reference id. - - ?!? In theory, the process_reference should never fail, but we should - catch that case just in case the compiler scrogged the stabs. */ - refnum = process_reference (&p); - start = ref_search_value (refnum); - if (!start) - { - complain (&lrs_general_complaint, "Live range symbol not found 1"); - return 0; - } - - if (!*p || *p != ',') - { - complain (&lrs_general_complaint, "live range string 3"); - return 0; - } - p++; - - /* Get ending value of range and advance P past the reference id. - - ?!? In theory, the process_reference should never fail, but we should - catch that case just in case the compiler scrogged the stabs. */ - refnum = process_reference (&p); - end = ref_search_value (refnum); - if (!end) - { - complain (&lrs_general_complaint, "Live range symbol not found 2"); - return 0; - } - - if (!*p || *p != ')') - { - complain (&lrs_general_complaint, "live range string 4"); - return 0; - } - - /* Now that we know the bounds of the range, add it to the - symbol. */ - add_live_range (objfile, sym, start, end); + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + add_symbol_to_list (sym, &local_symbols); + break; - return 1; -} + case 'X': + /* This is used by Sun FORTRAN for "function result value". + Sun claims ("dbx and dbxtool interfaces", 2nd ed) + that Pascal uses it too, but when I tried it Pascal used + "x:3" (local symbol) instead. */ + SYMBOL_TYPE (sym) = read_type (&p, objfile); + SYMBOL_CLASS (sym) = LOC_LOCAL; + SYMBOL_VALUE (sym) = valu; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + add_symbol_to_list (sym, &local_symbols); + break; -/* Add a new live range defined by START and END to the symbol SYM - in objfile OBJFILE. */ + default: + SYMBOL_TYPE (sym) = error_type (&p, objfile); + SYMBOL_CLASS (sym) = LOC_CONST; + SYMBOL_VALUE (sym) = 0; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + add_symbol_to_list (sym, &file_symbols); + break; + } -static void -add_live_range (struct objfile *objfile, struct symbol *sym, CORE_ADDR start, - CORE_ADDR end) -{ - struct range_list *r, *rs; + /* Some systems pass variables of certain types by reference instead + of by value, i.e. they will pass the address of a structure (in a + register or on the stack) instead of the structure itself. */ - if (start >= end) + if (gdbarch_stabs_argument_has_addr (current_gdbarch, SYMBOL_TYPE (sym)) + && (SYMBOL_CLASS (sym) == LOC_REGPARM || SYMBOL_CLASS (sym) == LOC_ARG)) { - complain (&lrs_general_complaint, "end of live range follows start"); - return; + /* We have to convert LOC_REGPARM to LOC_REGPARM_ADDR (for + variables passed in a register). */ + if (SYMBOL_CLASS (sym) == LOC_REGPARM) + SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; + /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th + and subsequent arguments on SPARC, for example). */ + else if (SYMBOL_CLASS (sym) == LOC_ARG) + SYMBOL_CLASS (sym) = LOC_REF_ARG; } - /* Alloc new live range structure. */ - r = (struct range_list *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct range_list)); - r->start = start; - r->end = end; - r->next = 0; - - /* Append this range to the symbol's range list. */ - if (!SYMBOL_RANGES (sym)) - SYMBOL_RANGES (sym) = r; - else - { - /* Get the last range for the symbol. */ - for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next) - ; - rs->next = r; - } + return sym; } - /* Skip rest of this symbol and return an error type. @@ -2308,7 +1345,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. */ @@ -2337,10 +1374,10 @@ error_type (char **pp, struct objfile *objfile) assume that type information starts with a digit, '-', or '(' in deciding whether to call read_type. */ -struct type * -read_type (register char **pp, struct objfile *objfile) +static struct type * +read_type (char **pp, struct objfile *objfile) { - register struct type *type = 0; + struct type *type = 0; struct type *type1; int typenums[2]; char type_descriptor; @@ -2352,6 +1389,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". */ @@ -2362,11 +1402,21 @@ read_type (register char **pp, struct objfile *objfile) if (read_type_number (pp, typenums) != 0) return error_type (pp, objfile); - /* Type is not being defined here. Either it already exists, - or this is a forward reference to it. dbx_alloc_type handles - both cases. */ if (**pp != '=') - return dbx_alloc_type (typenums, objfile); + { + /* Type is not being defined here. Either it already + exists, or this is a forward reference to it. + dbx_alloc_type handles both cases. */ + type = dbx_alloc_type (typenums, objfile); + + /* If this is a forward reference, arrange to complain if it + doesn't get patched up by the time we're done + reading. */ + if (TYPE_CODE (type) == TYPE_CODE_UNDEF) + add_undefined_type (type); + + return type; + } /* Type is being defined here. */ /* Skip the '='. @@ -2415,9 +1465,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; } @@ -2444,7 +1493,7 @@ again: return error_type (pp, objfile); } to = type_name = - (char *) obstack_alloc (&objfile->type_obstack, p - *pp + 1); + (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1); /* Copy the name. */ from = *pp + 1; @@ -2457,11 +1506,9 @@ again: *pp = from + 1; } - /* Now check to see whether the type has already been - declared. This was written for arrays of cross-referenced - types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty - sure it is not necessary anymore. But it might be a good - idea, to save a little memory. */ + /* If this type has already been declared, then reuse the same + type, rather than allocating a new one. This saves some + memory. */ for (ppt = file_symbols; ppt; ppt = ppt->next) for (i = 0; i < ppt->nsyms; i++) @@ -2469,12 +1516,14 @@ again: struct symbol *sym = ppt->symbol[i]; if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE + && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && (TYPE_CODE (SYMBOL_TYPE (sym)) == code) - && STREQ (SYMBOL_NAME (sym), type_name)) + && strcmp (DEPRECATED_SYMBOL_NAME (sym), type_name) == 0) { - obstack_free (&objfile->type_obstack, type_name); + obstack_free (&objfile->objfile_obstack, type_name); type = SYMBOL_TYPE (sym); + if (typenums[0] != -1) + *dbx_lookup_type (typenums) = type; return type; } } @@ -2525,7 +1574,30 @@ again: } else if (type_size >= 0 || is_string) { - *type = *xtype; + /* This is the absolute wrong way to construct types. Every + other debug format has found a way around this problem and + 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. + + 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; } @@ -2544,7 +1616,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; @@ -2555,43 +1627,93 @@ 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; + case 'g': /* Prototyped function. (Sun) */ + { + /* Unresolved questions: + + - According to Sun's ``STABS Interface Manual'', for 'f' + and 'F' symbol descriptors, a `0' in the argument type list + indicates a varargs function. But it doesn't say how 'g' + type descriptors represent that info. Someone with access + to Sun's toolchain should try it out. + + - According to the comment in define_symbol (search for + `process_prototype_types:'), Sun emits integer arguments as + types which ref themselves --- like `void' types. Do we + have to deal with that here, too? Again, someone with + access to Sun's toolchain should try it out and let us + know. */ + + const char *type_start = (*pp) - 1; + struct type *return_type = read_type (pp, objfile); + struct type *func_type + = make_function_type (return_type, dbx_lookup_type (typenums)); + struct type_list { + struct type *type; + struct type_list *next; + } *arg_types = 0; + int num_args = 0; + + while (**pp && **pp != '#') + { + struct type *arg_type = read_type (pp, objfile); + struct type_list *new = alloca (sizeof (*new)); + new->type = arg_type; + new->next = arg_types; + arg_types = new; + num_args++; + } + if (**pp == '#') + ++*pp; + else + { + 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 + that's just an empty argument list. */ + if (arg_types + && ! arg_types->next + && TYPE_CODE (arg_types->type) == TYPE_CODE_VOID) + num_args = 0; + + TYPE_FIELDS (func_type) + = (struct field *) TYPE_ALLOC (func_type, + num_args * sizeof (struct field)); + memset (TYPE_FIELDS (func_type), 0, num_args * sizeof (struct field)); + { + int i; + struct type_list *t; + + /* We stuck each argument type onto the front of the list + when we read it, so the list is reversed. Build the + fields array right-to-left. */ + for (t = arg_types, i = num_args - 1; t; t = t->next, i--) + TYPE_FIELD_TYPE (func_type, i) = t->type; + } + TYPE_NFIELDS (func_type) = num_args; + TYPE_FLAGS (func_type) |= TYPE_FLAG_PROTOTYPED; + + type = func_type; + break; + } + 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); - /* FIXME! For now, we ignore const and volatile qualifiers. */ + 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); - /* FIXME! For now, we ignore const and volatile qualifiers. */ + type = make_cv_type (TYPE_CONST (type), 1, type, + dbx_lookup_type (typenums)); break; case '@': @@ -2625,16 +1747,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. */ @@ -2654,7 +1782,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; @@ -2663,7 +1793,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. */ @@ -2672,23 +1803,22 @@ again: ++(*pp); return_type = read_type (pp, objfile); - args = read_args (pp, ';', objfile); + args = read_args (pp, ';', objfile, &nargs, &varargs); + if (args == NULL) + return error_type (pp, objfile); 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; case 'r': /* Range type */ - type = read_range_type (pp, typenums, objfile); + type = read_range_type (pp, typenums, type_size, objfile); if (typenums[0] != -1) *dbx_lookup_type (typenums) = type; 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); @@ -2712,18 +1842,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') @@ -2734,9 +1867,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) @@ -2753,7 +1888,7 @@ again: if (type == 0) { - warning ("GDB internal error, type is NULL in stabsread.c\n"); + warning (_("GDB internal error, type is NULL in stabsread.c.")); return error_type (pp, objfile); } @@ -2778,7 +1913,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) @@ -2889,10 +2024,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); @@ -2927,6 +2066,31 @@ 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) + { + complaint (&symfile_complaints, + _("Method has bad physname %s\n"), physname); + return; + } + + 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: @@ -2963,7 +2127,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, struct next_fnfieldlist *new_fnlist; struct next_fnfield *new_sublist; char *main_fn_name; - register char *p; + char *p; /* Process each list until we find something that is not a member function or find the end of the functions. */ @@ -3003,8 +2167,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 '::'. */ @@ -3064,7 +2227,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, /* If this is just a stub, then we don't have the real name here. */ - if (TYPE_FLAGS (new_sublist->fn_field.type) & TYPE_FLAG_STUB) + if (TYPE_STUB (new_sublist->fn_field.type)) { if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type)) TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type; @@ -3112,7 +2275,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; } @@ -3129,7 +2293,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, the sign bit out, and usable as a valid index into the array. Remove the sign bit here. */ new_sublist->fn_field.voffset = - (0x7fffffff & read_huge_number (pp, ';', &nbits)) + 2; + (0x7fffffff & read_huge_number (pp, ';', &nbits, 0)) + 2; if (nbits != 0) return 0; @@ -3167,17 +2331,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 '.': @@ -3195,23 +2377,193 @@ 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->objfile_obstack, "", "~", + new_fnlist->fn_fieldlist.name); + + destr_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile->objfile_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, (char *)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->objfile_obstack); + } + + new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile->objfile_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) @@ -3237,7 +2589,7 @@ static int read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; char *name; char cpp_abbrev; struct type *context; @@ -3260,25 +2612,32 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, switch (cpp_abbrev) { case 'f': /* $vf -- a virtual function table pointer */ + name = type_name_no_tag (context); + if (name == NULL) + { + name = ""; + } fip->list->field.name = - obconcat (&objfile->type_obstack, vptr_name, "", ""); + obconcat (&objfile->objfile_obstack, vptr_name, name, ""); break; case 'b': /* $vb -- a virtual bsomethingorother */ 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 = - obconcat (&objfile->type_obstack, vb_name, name, ""); + obconcat (&objfile->objfile_obstack, vb_name, name, ""); break; default: - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); fip->list->field.name = - obconcat (&objfile->type_obstack, + obconcat (&objfile->objfile_obstack, "INVALID_CPLUSPLUS_ABBREV", "", ""); break; } @@ -3289,7 +2648,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); @@ -3300,7 +2659,8 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, { int nbits; - FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits); + FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits, + 0); if (nbits != 0) return 0; } @@ -3310,7 +2670,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. */ @@ -3323,37 +2683,8 @@ static void read_one_struct_field (struct field_info *fip, char **pp, char *p, struct type *type, struct objfile *objfile) { - /* The following is code to work around cfront generated stabs. - The stabs contains full mangled name for each field. - We try to demangle the name and extract the field name out of it. - */ - if (ARM_DEMANGLING && current_subfile->language == language_cplus) - { - char save_p; - char *dem, *dem_p; - save_p = *p; - *p = '\0'; - dem = cplus_demangle (*pp, DMGL_ANSI | DMGL_PARAMS); - if (dem != NULL) - { - dem_p = strrchr (dem, ':'); - if (dem_p != 0 && *(dem_p - 1) == ':') - dem_p++; - FIELD_NAME (fip->list->field) = - obsavestring (dem_p, strlen (dem_p), &objfile->type_obstack); - } - else - { - FIELD_NAME (fip->list->field) = - obsavestring (*pp, p - *pp, &objfile->type_obstack); - } - *p = save_p; - } - /* end of code for cfront work around */ - - else - fip->list->field.name = - obsavestring (*pp, p - *pp, &objfile->type_obstack); + fip->list->field.name = + obsavestring (*pp, p - *pp, &objfile->objfile_obstack); *pp = p + 1; /* This means we have a visibility for a field coming. */ @@ -3394,7 +2725,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; } @@ -3402,16 +2733,16 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p, { int nbits; - FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits); + FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits, 0); 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); + FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits, 0); if (nbits != 0) { - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } } @@ -3423,7 +2754,7 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p, it is a field which has been optimized out. The correct stab for this case is to use VISIBILITY_IGNORE, but that is a recent invention. (2) It is a 0-size array. For example - union { int num; char str[0]; } foo. Printing "" for + union { int num; char str[0]; } foo. Printing _("" for str in "p foo" is OK, since foo.str (and thus foo.str[3]) will continue to work, and a 0-size array as a whole doesn't have any contents to print. @@ -3490,7 +2821,7 @@ static int read_struct_fields (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; struct nextfield *new; /* We better set p right now, in case there are no fields at all... */ @@ -3500,11 +2831,11 @@ read_struct_fields (struct field_info *fip, char **pp, struct type *type, /* Read each data member type until we find the terminating ';' at the end of the data member list, or break for some other reason such as finding the start of the member function list. */ + /* Stab string for structure/union does not end with two ';' in + SUN C compiler 5.3 i.e. F6U2, hence check for end of string. */ - while (**pp != ';') + 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)); @@ -3549,8 +2880,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; @@ -3603,7 +2935,7 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type, ALLOCATE_CPLUS_STRUCT_TYPE (type); { int nbits; - TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits); + TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits, 0); if (nbits != 0) return 0; } @@ -3646,10 +2978,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); @@ -3665,11 +2995,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; } } @@ -3681,7 +3009,7 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type, corresponding to this baseclass. Always zero in the absence of multiple inheritance. */ - FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits); + FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits, 0); if (nbits != 0) return 0; } @@ -3714,7 +3042,7 @@ static int read_tilde_fields (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; STABS_CONTINUE (pp, objfile); @@ -3766,15 +3094,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 @@ -3790,9 +3121,9 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, } static int -attach_fn_fields_to_type (struct field_info *fip, register struct type *type) +attach_fn_fields_to_type (struct field_info *fip, struct type *type) { - register int n; + int n; for (n = TYPE_NFN_FIELDS (type); fip->fnlist != NULL; @@ -3804,150 +3135,17 @@ attach_fn_fields_to_type (struct field_info *fip, register struct type *type) return 1; } -/* read cfront class static data. - pp points to string starting with the list of static data - eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; - ^^^^^^^^ - - A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; - ^ - */ - -static int -read_cfront_static_fields (struct field_info *fip, char **pp, struct type *type, - struct objfile *objfile) -{ - struct nextfield *new; - struct type *stype; - char *sname; - struct symbol *ref_static = 0; - - if (**pp == ';') /* no static data; return */ - { - ++(*pp); - return 1; - } - - /* Process each field in the list until we find the terminating ";" */ - - /* eg: p = "as__1A ;;;" */ - STABS_CONTINUE (pp, objfile); /* handle \\ */ - while (**pp != ';' && (sname = get_substring (pp, ' '), sname)) - { - 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); - continue; - } - stype = SYMBOL_TYPE (ref_static); - - /* allocate a new fip */ - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (xfree, new); - memset (new, 0, sizeof (struct nextfield)); - new->next = fip->list; - fip->list = new; - - /* set visibility */ - /* FIXME! no way to tell visibility from stabs??? */ - new->visibility = VISIBILITY_PUBLIC; - - /* set field info into fip */ - fip->list->field.type = stype; - - /* set bitpos & bitsize */ - SET_FIELD_PHYSNAME (fip->list->field, savestring (sname, strlen (sname))); - - /* set name field */ - /* The following is code to work around cfront generated stabs. - The stabs contains full mangled name for each field. - We try to demangle the name and extract the field name out of it. - */ - if (ARM_DEMANGLING) - { - char *dem, *dem_p; - dem = cplus_demangle (sname, DMGL_ANSI | DMGL_PARAMS); - if (dem != NULL) - { - dem_p = strrchr (dem, ':'); - if (dem_p != 0 && *(dem_p - 1) == ':') - dem_p++; - fip->list->field.name = - obsavestring (dem_p, strlen (dem_p), &objfile->type_obstack); - } - else - { - fip->list->field.name = - obsavestring (sname, strlen (sname), &objfile->type_obstack); - } - } /* end of code for cfront work around */ - } /* loop again for next static field */ - return 1; -} - -/* Copy structure fields to fip so attach_fields_to_type will work. - type has already been created with the initial instance data fields. - Now we want to be able to add the other members to the class, - so we want to add them back to the fip and reattach them again - once we have collected all the class members. */ - -static int -copy_cfront_struct_fields (struct field_info *fip, struct type *type, - struct objfile *objfile) -{ - int nfields = TYPE_NFIELDS (type); - int i; - struct nextfield *new; - - /* Copy the fields into the list of fips and reset the types - to remove the old fields */ - - for (i = 0; i < nfields; i++) - { - /* allocate a new fip */ - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (xfree, new); - memset (new, 0, sizeof (struct nextfield)); - new->next = fip->list; - fip->list = new; - - /* copy field info into fip */ - new->field = TYPE_FIELD (type, i); - /* set visibility */ - if (TYPE_FIELD_PROTECTED (type, i)) - new->visibility = VISIBILITY_PROTECTED; - else if (TYPE_FIELD_PRIVATE (type, i)) - new->visibility = VISIBILITY_PRIVATE; - else - new->visibility = VISIBILITY_PUBLIC; - } - /* Now delete the fields from the type since we will be - allocing new space once we get the rest of the fields - in attach_fields_to_type. - The pointer TYPE_FIELDS(type) is left dangling but should - be freed later by objstack_free */ - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS (type) = 0; - - return 1; -} - /* Create the vector of fields, and record how big it is. We need this info to record proper virtual function table information for this class's virtual functions. */ static int -attach_fields_to_type (struct field_info *fip, register struct type *type, +attach_fields_to_type (struct field_info *fip, struct type *type, struct objfile *objfile) { - register int nfields = 0; - register int non_public_fields = 0; - register struct nextfield *scan; + int nfields = 0; + int non_public_fields = 0; + struct nextfield *scan; /* Count up the number of fields that we have, as well as taking note of whether or not there are any non-public fields, which requires us to @@ -4016,10 +3214,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; } @@ -4028,6 +3224,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. @@ -4043,7 +3275,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; @@ -4051,16 +3284,37 @@ 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. */ { int nbits; - TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits); + TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits, 0); if (nbits != 0) return error_type (pp, objfile); } @@ -4090,7 +3344,7 @@ read_struct_type (char **pp, struct type *type, struct objfile *objfile) array. */ static struct type * -read_array_type (register char **pp, register struct type *type, +read_array_type (char **pp, struct type *type, struct objfile *objfile) { struct type *index_type, *element_type, *range_type; @@ -4105,9 +3359,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 != ';') @@ -4121,7 +3372,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, 0); + if (nbits != 0) return error_type (pp, objfile); @@ -4130,7 +3382,7 @@ read_array_type (register char **pp, register struct type *type, (*pp)++; adjustable = 1; } - upper = read_huge_number (pp, ';', &nbits); + upper = read_huge_number (pp, ';', &nbits, 0); if (nbits != 0) return error_type (pp, objfile); @@ -4155,13 +3407,13 @@ read_array_type (register char **pp, register struct type *type, Also defines the symbols that represent the values of the type. */ static struct type * -read_enum_type (register char **pp, register struct type *type, +read_enum_type (char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; char *name; - register long n; - register struct symbol *sym; + long n; + struct symbol *sym; int nsyms = 0; struct pending **symlist; struct pending *osyms, *syms; @@ -4181,16 +3433,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 == '-') @@ -4212,19 +3454,19 @@ read_enum_type (register char **pp, register struct type *type, p = *pp; while (*p != ':') p++; - name = obsavestring (*pp, p - *pp, &objfile->symbol_obstack); + name = obsavestring (*pp, p - *pp, &objfile->objfile_obstack); *pp = p + 1; - n = read_huge_number (pp, ',', &nbits); + n = read_huge_number (pp, ',', &nbits, 0); if (nbits != 0) return error_type (pp, objfile); sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = name; + DEPRECATED_SYMBOL_NAME (sym) = name; SYMBOL_LANGUAGE (sym) = current_subfile->language; SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE (sym) = n; if (n < 0) unsigned_enum = 0; @@ -4263,7 +3505,7 @@ read_enum_type (register char **pp, register struct type *type, { struct symbol *xsym = syms->symbol[j]; SYMBOL_TYPE (xsym) = type; - TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); + TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym); TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); TYPE_FIELD_BITSIZE (type, n) = 0; } @@ -4326,17 +3568,17 @@ read_sun_builtin_type (char **pp, int typenums[2], struct objfile *objfile) by this type, except that unsigned short is 4 instead of 2. Since this information is redundant with the third number, we will ignore it. */ - read_huge_number (pp, ';', &nbits); + read_huge_number (pp, ';', &nbits, 0); if (nbits != 0) return error_type (pp, objfile); /* The second number is always 0, so ignore it too. */ - read_huge_number (pp, ';', &nbits); + read_huge_number (pp, ';', &nbits, 0); if (nbits != 0) return error_type (pp, objfile); /* The third number is the number of bits for this type. */ - type_bits = read_huge_number (pp, 0, &nbits); + type_bits = read_huge_number (pp, 0, &nbits, 0); if (nbits != 0) return error_type (pp, objfile); /* The type *should* end with a semicolon. If it are embedded @@ -4365,23 +3607,27 @@ 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. */ - details = read_huge_number (pp, ';', &nbits); + details = read_huge_number (pp, ';', &nbits, 0); if (nbits != 0) return error_type (pp, objfile); /* The second number is the number of bytes occupied by this type */ - nbytes = read_huge_number (pp, ';', &nbits); + nbytes = read_huge_number (pp, ';', &nbits, 0); if (nbits != 0) return error_type (pp, 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); } @@ -4393,22 +3639,30 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile) and that character is skipped if it does match. If END is zero, *PP is left pointing to that character. + If TWOS_COMPLEMENT_BITS is set to a strictly positive value and if + the number is represented in an octal representation, assume that + it is represented in a 2's complement representation with a size of + TWOS_COMPLEMENT_BITS. + If the number fits in a long, set *BITS to 0 and return the value. If not, set *BITS to be the number of bits in the number and return 0. If encounter garbage, set *BITS to -1 and return 0. */ static long -read_huge_number (char **pp, int end, int *bits) +read_huge_number (char **pp, int end, int *bits, int twos_complement_bits) { char *p = *pp; int sign = 1; + int sign_bit; long n = 0; + long sn = 0; int radix = 10; char overflow = 0; int nbits = 0; int c; long upper_limit; + int twos_complement_representation = radix == 8 && twos_complement_bits > 0; if (*p == '-') { @@ -4424,20 +3678,41 @@ 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)) { if (n <= upper_limit) - { - n *= radix; - n += c - '0'; /* FIXME this overflows anyway */ - } + { + if (twos_complement_representation) + { + /* Octal, signed, twos complement representation. In this case, + sn is the signed value, n is the corresponding absolute + value. signed_bit is the position of the sign bit in the + first three bits. */ + if (sn == 0) + { + sign_bit = (twos_complement_bits % 3 + 2) % 3; + sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit)); + } + else + { + sn *= radix; + sn += c - '0'; + } + + if (sn < 0) + n = -sn; + } + else + { + /* unsigned representation */ + n *= radix; + n += c - '0'; /* FIXME this overflows anyway */ + } + } else - overflow = 1; + overflow = 1; /* This depends on large values being output in octal, which is what GCC does. */ @@ -4494,14 +3769,18 @@ read_huge_number (char **pp, int end, int *bits) { if (bits) *bits = 0; - return n * sign; + if (twos_complement_representation) + return sn; + else + return n * sign; } /* It's *BITS which has the interesting information. */ return 0; } static struct type * -read_range_type (char **pp, int typenums[2], struct objfile *objfile) +read_range_type (char **pp, int typenums[2], int type_size, + struct objfile *objfile) { char *orig_pp = *pp; int rangenums[2]; @@ -4530,8 +3809,8 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile) /* The remaining two operands are usually lower and upper bounds of the range. But in some special cases they mean something else. */ - n2 = read_huge_number (pp, ';', &n2bits); - n3 = read_huge_number (pp, ';', &n3bits); + n2 = read_huge_number (pp, ';', &n2bits, type_size); + n3 = read_huge_number (pp, ';', &n3bits, type_size); if (n2bits == -1 || n3bits == -1) return error_type (pp, objfile); @@ -4547,8 +3826,19 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile) /* Number of bits in the type. */ int nbits = 0; + /* If a type size attribute has been specified, the bounds of + the range should fit in this size. If the lower bounds needs + more bits than the upper bound, then the type is signed. */ + if (n2bits <= type_size && n3bits <= type_size) + { + if (n2bits == type_size && n2bits > n3bits) + got_signed = 1; + else + got_unsigned = 1; + nbits = type_size; + } /* Range from 0 to is an unsigned large integral type. */ - if ((n2bits == 0 && n2 == 0) && n3bits != 0) + else if ((n2bits == 0 && n2 == 0) && n3bits != 0) { got_unsigned = 1; nbits = n3bits; @@ -4621,11 +3911,7 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile) /* Special case: char is defined (Who knows why) as a subrange of itself with range 0-127. */ 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; + return init_type (TYPE_CODE_INT, 1, TYPE_FLAG_NOSIGN, NULL, objfile); /* We used to do this only for subrange of self or subrange of int. */ else if (n2 == 0) @@ -4687,7 +3973,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, @@ -4700,41 +3987,42 @@ handle_true_range: } /* Read in an argument list. This is a list of types, separated by commas - and terminated with END. Return the list of types read in, or (struct type - **)-1 if there is an error. */ + and terminated with END. Return the list of types read in, or NULL + 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 NULL; (*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; } @@ -4762,16 +4050,13 @@ 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; common_block_name = obsavestring (name, strlen (name), - &objfile->symbol_obstack); + &objfile->objfile_obstack); } /* Process a N_ECOMM symbol. */ @@ -4792,17 +4077,15 @@ 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; } sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - /* Note: common_block_name already saved on symbol_obstack */ - SYMBOL_NAME (sym) = common_block_name; + /* Note: common_block_name already saved on objfile_obstack */ + DEPRECATED_SYMBOL_NAME (sym) = common_block_name; SYMBOL_CLASS (sym) = LOC_BLOCK; /* Now we copy all the symbols which have been defined since the BCOMM. */ @@ -4829,7 +4112,7 @@ common_block_end (struct objfile *objfile) /* Should we be putting local_symbols back to what it was? Does it matter? */ - i = hashname (SYMBOL_NAME (sym)); + i = hashname (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; global_sym_chain[i] = sym; common_block_name = NULL; @@ -4845,7 +4128,7 @@ fix_common_block (struct symbol *sym, int valu) struct pending *next = (struct pending *) SYMBOL_TYPE (sym); for (; next; next = next->next) { - register int j; + int j; for (j = next->nsyms - 1; j >= 0; j--) SYMBOL_VALUE_ADDRESS (next->symbol[j]) += valu; } @@ -4858,7 +4141,7 @@ fix_common_block (struct symbol *sym, int valu) /* Add a type to the list of undefined types to be checked through once this file has been read in. */ -void +static void add_undefined_type (struct type *type) { if (undef_types_length == undef_types_allocated) @@ -4898,7 +4181,7 @@ cleanup_undefined_types (void) as well as in check_typedef to deal with the (legitimate in C though not C++) case of several types with the same name in different source files. */ - if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB) + if (TYPE_STUB (*type)) { struct pending *ppt; int i; @@ -4907,9 +4190,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) @@ -4919,14 +4200,11 @@ cleanup_undefined_types (void) struct symbol *sym = ppt->symbol[i]; if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE + && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE (*type)) - && STREQ (SYMBOL_NAME (sym), typename)) - { - memcpy (*type, SYMBOL_TYPE (sym), - sizeof (struct type)); - } + && strcmp (DEPRECATED_SYMBOL_NAME (sym), typename) == 0) + replace_type (*type, SYMBOL_TYPE (sym)); } } } @@ -4935,10 +4213,10 @@ 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, + _("forward-referenced types left unresolved, " + "type code %d."), + TYPE_CODE (*type)); } break; } @@ -4956,7 +4234,7 @@ scan_file_globals (struct objfile *objfile) { int hash; struct minimal_symbol *msymbol; - struct symbol *sym, *prev, *rsym; + struct symbol *sym, *prev; struct objfile *resolve_objfile; /* SVR4 based linkers copy referenced global symbols from shared @@ -4982,7 +4260,7 @@ scan_file_globals (struct objfile *objfile) return; for (msymbol = resolve_objfile->msymbols; - msymbol && SYMBOL_NAME (msymbol) != NULL; + msymbol && DEPRECATED_SYMBOL_NAME (msymbol) != NULL; msymbol++) { QUIT; @@ -5003,16 +4281,13 @@ scan_file_globals (struct objfile *objfile) /* Get the hash index and check all the symbols under that hash index. */ - hash = hashname (SYMBOL_NAME (msymbol)); + hash = hashname (DEPRECATED_SYMBOL_NAME (msymbol)); for (sym = global_sym_chain[hash]; sym;) { - if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] && - STREQ (SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1)) + if (DEPRECATED_SYMBOL_NAME (msymbol)[0] == DEPRECATED_SYMBOL_NAME (sym)[0] && + strcmp (DEPRECATED_SYMBOL_NAME (msymbol) + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0) { - - struct alias_list *aliases; - /* Splice this symbol out of the hash chain and assign the value we have to it. */ if (prev) @@ -5027,38 +4302,21 @@ scan_file_globals (struct objfile *objfile) /* Check to see whether we need to fix up a common block. */ /* Note: this code might be executed several times for the same symbol if there are multiple references. */ - - /* If symbol has aliases, do minimal symbol fixups for each. - These live aliases/references weren't added to - global_sym_chain hash but may also need to be fixed up. */ - /* FIXME: Maybe should have added aliases to the global chain, resolved symbol name, then treated aliases as normal - symbols? Still, we wouldn't want to add_to_list. */ - /* Now do the same for each alias of this symbol */ - rsym = sym; - aliases = SYMBOL_ALIASES (sym); - while (rsym) + if (sym) { - if (SYMBOL_CLASS (rsym) == LOC_BLOCK) + if (SYMBOL_CLASS (sym) == LOC_BLOCK) { - fix_common_block (rsym, + fix_common_block (sym, SYMBOL_VALUE_ADDRESS (msymbol)); } else { - SYMBOL_VALUE_ADDRESS (rsym) + SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol); } - SYMBOL_SECTION (rsym) = SYMBOL_SECTION (msymbol); - if (aliases) - { - rsym = aliases->sym; - aliases = aliases->next; - } - else - rsym = NULL; + SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol); } - if (prev) { sym = SYMBOL_VALUE_CHAIN (prev); @@ -5098,8 +4356,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, DEPRECATED_SYMBOL_NAME (prev)); } } memset (global_sym_chain, 0, sizeof (global_sym_chain)); @@ -5139,8 +4398,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() */ @@ -5168,6 +4425,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