/* Support routines for decoding "stabs" debugging information format.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000
- Free Software Foundation, Inc.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free
+ Software Foundation, Inc.
This file is part of GDB.
#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"
#include "complaints.h"
#include "demangle.h"
#include "language.h"
+#include "doublest.h"
+#include "cp-abi.h"
+#include "cp-support.h"
#include <ctype.h>
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 *);
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 *);
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
#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. */
*(pp) = next_symbol_text (objfile); \
} while (0)
\f
-/* 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.
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. */
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;
}
(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]);
}
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);
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)
{
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')
{
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;
}
#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 "#<num>" as the name; we'll fix the name later.
- We stored the original symbol name as "#<id>=<name>"
- so we can now search for "#<id>" to resolving the reference.
- We'll fix the names later by removing the "#<id>" or "#<id>=" */
-
-/*---------------------------------------------------------*/
- /* 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". */
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. */
}
}
-/* 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
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)
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 '_':
#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++;
{
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;
}
SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile,
FT_DBL_PREC_FLOAT);
dbl_valu = (char *)
- obstack_alloc (&objfile->symbol_obstack,
+ 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;
}
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;
/* 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;
/* 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. */
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 */
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;
/* 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;
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;
}
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;
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. */
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':
SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
{
- complain (®_value_complaint, SYMBOL_VALUE (sym),
- NUM_REGS + NUM_PSEUDO_REGS,
- SYMBOL_SOURCE_NAME (sym));
+ reg_value_complaint (SYMBOL_VALUE (sym),
+ NUM_REGS + NUM_PSEUDO_REGS,
+ SYMBOL_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;
SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
{
- complain (®_value_complaint, SYMBOL_VALUE (sym),
- NUM_REGS + NUM_PSEUDO_REGS,
- SYMBOL_SOURCE_NAME (sym));
+ reg_value_complaint (SYMBOL_VALUE (sym),
+ NUM_REGS + NUM_PSEUDO_REGS,
+ SYMBOL_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; }
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
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
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
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
/* 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);
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)
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;
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;
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;
SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
{
- complain (®_value_complaint, SYMBOL_VALUE (sym),
- NUM_REGS + NUM_PSEUDO_REGS,
- SYMBOL_SOURCE_NAME (sym));
- 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);
+ 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_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;
}
-\f
/* Skip rest of this symbol and return an error type.
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. */
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;
/* 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". */
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 '='.
{
/* 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;
}
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;
*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++)
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;
}
}
}
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;
}
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;
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 '@':
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. */
(*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;
{
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. */
++(*pp);
return_type = read_type (pp, objfile);
- args = read_args (pp, ';', objfile);
+ args = read_args (pp, ';', objfile, &nargs, &varargs);
type = dbx_alloc_type (typenums, objfile);
- smash_to_method_type (type, domain, return_type, args);
+ smash_to_method_type (type, domain, return_type, args,
+ nargs, varargs);
}
break;
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);
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')
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)
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);
}
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)
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);
\f
/* 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:
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. */
/* 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 '::'. */
/* 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;
case '.':
break;
default:
- complain (&const_vol_complaint, **pp);
+ complaint (&symfile_complaints,
+ _("const/volatile indicator missing, got '%c'"), **pp);
break;
}
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;
}
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 '.':
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, 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)
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;
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;
}
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);
{
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;
}
}
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. */
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. */
else if (**pp != ',')
{
/* Bad structure-type format. */
- complain (&stabs_general_complaint, "bad structure-type format");
+ stabs_general_complaint ("bad structure-type format");
return;
}
{
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;
}
}
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 "<no value>" for
+ union { int num; char str[0]; } foo. Printing _("<no value>" 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.
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... */
/* 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));
}
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;
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;
}
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);
/* 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;
}
}
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;
}
read_tilde_fields (struct field_info *fip, char **pp, struct type *type,
struct objfile *objfile)
{
- register char *p;
+ char *p;
STABS_CONTINUE (pp, objfile);
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
}
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;
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
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;
}
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 = "<unknown>";
+ 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.
*/
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;
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);
}
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;
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 != ';')
(*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);
(*pp)++;
adjustable = 1;
}
- upper = read_huge_number (pp, ';', &nbits);
+ upper = read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
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;
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 == '-')
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;
{
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;
}
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
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);
}
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 == '-')
{
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. */
{
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];
/* 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);
/* 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 <large number> 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;
/* 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)
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,
and terminated with END. Return the list of types read in, or (struct type
**)-1 if there is an error. */
-static struct type **
-read_args (char **pp, int end, struct objfile *objfile)
+static struct field *
+read_args (char **pp, int end, struct objfile *objfile, int *nargsp,
+ int *varargsp)
{
/* FIXME! Remove this arbitrary limit! */
- struct type *types[1024], **rval; /* allow for fns of 1023 parameters */
- int n = 0;
+ struct type *types[1024]; /* allow for fns of 1023 parameters */
+ int n = 0, i;
+ struct field *rval;
while (**pp != end)
{
if (**pp != ',')
/* Invalid argument list: no ','. */
- return (struct type **) -1;
+ return (struct field *) -1;
(*pp)++;
STABS_CONTINUE (pp, objfile);
types[n++] = read_type (pp, objfile);
}
(*pp)++; /* get past `end' (the ':' character) */
- if (n == 1)
- {
- rval = (struct type **) xmalloc (2 * sizeof (struct type *));
- }
- else if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
- {
- rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *));
- memset (rval + n, 0, sizeof (struct type *));
- }
+ if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
+ *varargsp = 1;
else
{
- rval = (struct type **) xmalloc (n * sizeof (struct type *));
+ n--;
+ *varargsp = 0;
}
- memcpy (rval, types, n * sizeof (struct type *));
+
+ rval = (struct field *) xmalloc (n * sizeof (struct field));
+ memset (rval, 0, n * sizeof (struct field));
+ for (i = 0; i < n; i++)
+ rval[i].type = types[i];
+ *nargsp = n;
return rval;
}
\f
{
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. */
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. */
/* 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;
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;
}
/* 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)
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;
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)
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));
}
}
}
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;
}
{
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
return;
for (msymbol = resolve_objfile->msymbols;
- msymbol && SYMBOL_NAME (msymbol) != NULL;
+ msymbol && DEPRECATED_SYMBOL_NAME (msymbol) != NULL;
msymbol++)
{
QUIT;
/* 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)
/* 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);
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));
/* FIXME: If common_block_name is not already NULL, we should complain(). */
common_block_name = NULL;
-
- os9k_stabs = 0;
}
/* Call after end_symtab() */
}
}
+/* 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