This file is part of GDB.
-GDB is free software; you can redistribute it and/or modify
+This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
-GDB is distributed in the hope that it will be useful,
+This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GDB; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-\f
-/* Symbol read-in occurs in two phases:
- 1. A scan (read_dbx_symtab()) of the entire executable, whose sole
- purpose is to make a list of symbols (partial symbol table)
- which will cause symbols
- to be read in if referenced. This scan happens when the
- "symbol-file" command is given (symbol_file_command()).
- 1a. The "add-file" command. Similar to #1.
- 2. Full read-in of symbols. (dbx_psymtab_to_symtab()). This happens
- when a symbol in a file for which symbols have not yet been
- read in is referenced. */
-
-/* There used to be some PROFILE_TYPES code in this file which counted
- the number of occurances of various symbols. I'd suggest instead:
- nm -ap foo | awk 'print $5' | sort | uniq -c
- to print how many of each n_type, or something like
- nm -ap foo | awk '$5 == "LSYM" {print $6 $7 $8 $9 $10 $11}' | \
- awk 'BEGIN {FS=":"}
- {print substr($2,1,1)}' | sort | uniq -c
- to print the number of each kind of symbol descriptor (i.e. the letter
- after ':'). */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This module provides three functions: dbx_symfile_init,
+ which initializes to read a symbol file; dbx_new_init, which
+ discards existing cached information when all symbols are being
+ discarded; and dbx_symfile_read, which reads a symbol table
+ from a file.
+
+ dbx_symfile_read only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real. dbx_psymtab_to_symtab() is the function that does this */
#include <stdio.h>
#include <string.h>
#include "command.h"
#include "target.h"
#include "gdbcore.h" /* for bfd stuff */
-#include "liba.out.h" /* FIXME Secret internal BFD stuff for a.out */
+#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
#include "symfile.h"
struct dbx_symfile_info {
static void add_undefined_type ();
static void cleanup_undefined_types ();
static void scan_file_globals ();
-static void read_ofile_symtab ();
+static struct symtab *read_ofile_symtab ();
static void dbx_psymtab_to_symtab ();
/* C++ */
static struct type **read_args ();
-static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER };
-static const char vb_name[] = { '_','v','b',CPLUS_MARKER };
+static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' };
+static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' };
/* Macro to determine which symbols to ignore when reading the first symbol
of a file. Some machines override this definition. */
int within_function;
+#if 0
+/* The type of the function we are currently reading in. This is
+ used by define_symbol to record the type of arguments to a function. */
+
+static struct type *in_function_type;
+#endif
+
/* List of blocks already made (lexical contexts already closed).
This is used at the end to make the blockvector. */
{"bad string table offset in symbol %d", 0, 0};
struct complaint unknown_symtype_complaint =
- {"unknown symbol type 0x%x", 0, 0};
+ {"unknown symbol type %s", 0, 0};
struct complaint lbrac_rbrac_complaint =
{"block start larger than block end", 0, 0};
bzero (type, sizeof (struct type));
TYPE_VPTR_FIELDNO (type) = -1;
+ TYPE_VPTR_BASETYPE (type) = 0;
return type;
}
int foo;
{
struct pending *next, *next1;
+#if 0
struct pending_block *bnext, *bnext1;
+#endif
for (next = free_pendings; next; next = next1)
{
END_ADDR is the address of the end of the file's text. */
-static void
+static struct symtab *
end_symtab (end_addr)
CORE_ADDR end_addr;
{
current_subfile->line_vector_index = line_vector_index;
/* Now create the symtab objects proper, one for each subfile. */
- /* (The main file is one of them.) */
+ /* (The main file is the last one on the chain.) */
for (subfile = subfiles; subfile; subfile = nextsub)
{
- symtab = (struct symtab *) xmalloc (sizeof (struct symtab));
+ symtab = allocate_symtab (subfile->name);
/* Fill in its components. */
symtab->blockvector = blockvector;
type_vector->length = type_vector_length;
symtab->typevector = type_vector;
- symtab->filename = subfile->name;
symtab->dirname = subfile->dirname;
symtab->free_code = free_linetable;
if (subfile->next == 0)
symtab->free_ptr = (char *) type_vector;
- symtab->nlines = 0;
- symtab->line_charpos = 0;
-
- symtab->language = language_unknown;
- symtab->fullname = NULL;
-
/* There should never already be a symtab for this name, since
any prev dups have been removed when the psymtab was read in.
FIXME, there ought to be a way to check this here. */
line_vector = 0;
line_vector_length = -1;
last_source_file = 0;
+
+ return symtab;
}
\f
/* Handle the N_BINCL and N_EINCL symbol types
CORE_ADDR address;
int type;
{
- enum misc_function_type misc_type =
- (type == (N_TEXT | N_EXT) ? mf_text :
- (type == (N_DATA | N_EXT)
- || type == (N_DATA)
- || type == (N_SETV | N_EXT)
- ) ? mf_data :
- type == (N_BSS | N_EXT) ? mf_bss :
- type == (N_ABS | N_EXT) ? mf_abs : mf_unknown);
+ enum misc_function_type misc_type;
+
+ switch (type &~ N_EXT) {
+ case N_TEXT: misc_type = mf_text; break;
+ case N_DATA: misc_type = mf_data; break;
+ case N_BSS: misc_type = mf_bss; break;
+ case N_ABS: misc_type = mf_abs; break;
+#ifdef N_SETV
+ case N_SETV: misc_type = mf_data; break;
+#endif
+ default: misc_type = mf_unknown; break;
+ }
prim_record_misc_function (obsavestring (name, strlen (name)),
address, misc_type);
}
\f
+/* The BFD for this file -- only good while we're actively reading
+ symbols into a psymtab or a symtab. */
+
+static bfd *symfile_bfd;
+
/* Scan and build partial symbols for a symbol file.
We have been initialized by a call to dbx_symfile_init, which
put all the relevant info into a "struct dbx_symfile_info"
free (info);
sf->sym_private = 0; /* Zap pointer to our (now gone) info struct */
- /* Call to select_source_symtab used to be here; it was using too
- much time. I'll make sure that list_sources can handle the lack
- of current_source_symtab */
-
- if (!partial_symtab_list)
- printf_filtered ("\n(no debugging symbols found)...");
+ if (!partial_symtab_list) {
+ wrap_here ("");
+ printf_filtered ("(no debugging symbols found)...");
+ wrap_here ("");
+ }
}
-/* Discard any information we have cached during the reading of a
- single symbol file. This should not toss global information
- from previous symbol files that have been read. E.g. we might
- be discarding info from reading a shared library, and should not
- throw away the info from the main file. */
+/* Initialize anything that needs initializing when a completely new
+ symbol file is specified (not just adding some symbols from another
+ file, e.g. a shared library). */
void
-dbx_symfile_discard ()
+dbx_new_init ()
{
-
/* Empty the hash table of global syms looking for values. */
bzero (global_sym_chain, sizeof global_sym_chain);
free_pendings = 0;
file_symbols = 0;
global_symbols = 0;
-}
-
-/* Initialize anything that needs initializing when a completely new
- symbol file is specified (not just adding some symbols from another
- file, e.g. a shared library). */
-void
-dbx_new_init ()
-{
- dbx_symfile_discard ();
/* Don't put these on the cleanup chain; they need to stick around
- until the next call to symbol_file_command. *Then* we'll free
- them. */
+ until the next call to dbx_new_init. *Then* we'll free them. */
if (symfile_string_table)
{
free (symfile_string_table);
info->text_sect = bfd_get_section_by_name (sym_bfd, ".text");
if (!info->text_sect)
abort();
- info->symcount = bfd_get_symcount_upper_bound(sym_bfd); /* It's exact for a.out */
+ info->symcount = bfd_get_symcount (sym_bfd);
/* Read the string table size and check it for bogosity. */
val = lseek (desc, STRING_TABLE_OFFSET, L_SET);
val = myread (desc, size_temp, sizeof (long));
if (val < 0)
perror_with_name (name);
- info->stringtab_size = bfd_h_getlong (sym_bfd, size_temp);
+ info->stringtab_size = bfd_h_get_32 (sym_bfd, size_temp);
if (info->stringtab_size >= 0 && info->stringtab_size < statbuf.st_size)
{
#define SWAP_SYMBOL(symp) \
{ \
- (symp)->n_un.n_strx = bfd_h_getlong(symfile_bfd, \
+ (symp)->n_un.n_strx = bfd_h_get_32(symfile_bfd, \
(unsigned char *)&(symp)->n_un.n_strx); \
- (symp)->n_desc = bfd_h_getshort (symfile_bfd, \
+ (symp)->n_desc = bfd_h_get_16 (symfile_bfd, \
(unsigned char *)&(symp)->n_desc); \
- (symp)->n_value = bfd_h_getlong (symfile_bfd, \
+ (symp)->n_value = bfd_h_get_32 (symfile_bfd, \
(unsigned char *)&(symp)->n_value); \
}
bufp->n_value += addr; /* Relocate */
SET_NAMESTRING ();
/* Check for __DYNAMIC, which is used by Sun shared libraries.
- Record it even if it's local, not global, so we can find it. */
- if (namestring[8] == 'C' && (strcmp ("__DYNAMIC", namestring) == 0))
+ Record it even if it's local, not global, so we can find it.
+ Same with virtual function tables, both global and static. */
+ if ((namestring[8] == 'C' && (strcmp ("__DYNAMIC", namestring) == 0))
+ || VTBL_PREFIX_P ((namestring+HASH_OFFSET)))
{
/* Not really a function here, but... */
record_misc_function (namestring, bufp->n_value,
namestring, valu,
first_symnum * sizeof (struct nlist),
global_psymbols.next, static_psymbols.next);
-
continue;
}
continue;
case 'G':
bufp->n_value += addr; /* Relocate */
+ /* The addresses in these entries are reported to be
+ wrong. See the code that reads 'G's for symtabs. */
ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring,
- VAR_NAMESPACE, LOC_EXTERNAL,
+ VAR_NAMESPACE, LOC_STATIC,
global_psymbols, bufp->n_value);
continue;
case N_LBRAC:
case N_RBRAC:
case N_NSYMS: /* Ultrix 4.0: symbol count */
+ case N_DEFD: /* GNU Modula-2 */
/* These symbols aren't interesting; don't worry about them */
continue;
default:
/* If we haven't found it yet, ignore it. It's probably some
new type we don't know about yet. */
- complain (&unknown_symtype_complaint, bufp->n_type);
+ complain (&unknown_symtype_complaint, local_hex_string(bufp->n_type));
continue;
}
}
/* If there's stuff to be cleaned up, clean it up. */
- if (entry_point < bufp->n_value
+ if (nlistlen > 0 /* We have some syms */
+ && entry_point < bufp->n_value
&& entry_point >= last_o_file_start)
{
startup_file_start = last_o_file_start;
*st1 = SYMBOL_NAME (s1),
*st2 = SYMBOL_NAME (s2);
- return (st1[0] - st2[0] ? st1[0] - st2[0] :
- strcmp (st1 + 1, st2 + 1));
+ if (st1[0] - st2[0])
+ return st1[0] - st2[0];
+ if (st1[1] - st2[1])
+ return st1[1] - st2[1];
+ return strcmp (st1 + 1, st2 + 1);
}
subpst->n_static_syms = 0;
subpst->readin = 0;
+ subpst->symtab = 0;
subpst->read_symtab = dbx_psymtab_to_symtab;
subpst->next = partial_symtab_list;
/* Read in this files symbols */
lseek (desc, sym_offset, L_SET);
- read_ofile_symtab (desc, stringtab, stringtab_size,
- pst->ldsymoff,
- pst->ldsymlen, pst->textlow,
- pst->texthigh - pst->textlow, pst->addr);
- sort_symtab_syms (symtab_list); /* At beginning since just added */
+ pst->symtab =
+ read_ofile_symtab (desc, stringtab, stringtab_size,
+ pst->ldsymoff,
+ pst->ldsymlen, pst->textlow,
+ pst->texthigh - pst->textlow, pst->addr);
+ sort_symtab_syms (pst->symtab);
do_cleanups (old_chain);
}
val = myread (desc, &st_temp, sizeof st_temp);
if (val < 0)
perror_with_name (pst->symfile_name);
- stsize = bfd_h_getlong (sym_bfd, (unsigned char *)&st_temp);
+ stsize = bfd_h_get_32 (sym_bfd, (unsigned char *)&st_temp);
if (fstat (desc, &statbuf) < 0)
perror_with_name (pst->symfile_name);
}
/* Process a pair of symbols. Currently they must both be N_SO's. */
+/* ARGSUSED */
static void
process_symbol_pair (type1, desc1, value1, name1,
type2, desc2, value2, name2)
/* No need to check PCC_SOL_BROKEN, on the assumption that such
broken PCC's don't put out N_SO pairs. */
if (last_source_file)
- end_symtab (value2);
+ (void)end_symtab (value2);
start_symtab (name2, name1, value2);
}
* OFFSET is a relocation offset which gets added to each symbol
*/
-static void
+static struct symtab *
read_ofile_symtab (desc, stringtab, stringtab_size, sym_offset,
sym_size, text_offset, text_size, offset)
int desc;
{
/* N_CATCH is not fixed up by the linker, and unfortunately,
there's no other place to put it in the .stab map. */
- /* FIXME, do we also have to add OFFSET or something? -- gnu@cygnus */
- bufp->n_value += text_offset;
+ bufp->n_value += text_offset + offset;
}
else if (type == N_TEXT || type == N_DATA || type == N_BSS)
bufp->n_value += offset;
if (type & N_STAB)
{
- short desc = bufp->n_desc;
+ short bufp_n_desc = bufp->n_desc;
unsigned long valu = bufp->n_value;
/* Check for a pair of N_SO symbols. */
bufp->n_un.n_strx);
namestring2 = bufp->n_un.n_strx + stringtab;
- process_symbol_pair (N_SO, desc, valu, namestring,
+ process_symbol_pair (N_SO, bufp_n_desc, valu, namestring,
N_SO, bufp->n_desc, bufp->n_value,
namestring2);
}
else
- process_one_symbol(type, desc, valu, namestring);
+ process_one_symbol(type, bufp_n_desc, valu, namestring);
}
else
- process_one_symbol (type, desc, valu, namestring);
+ process_one_symbol (type, bufp_n_desc, valu, namestring);
}
/* We skip checking for a new .o or -l file; that should never
happen in this routine. */
processing_gcc_compilation = 1;
else if (type & N_EXT || type == (unsigned char)N_TEXT
|| type == (unsigned char)N_NBTEXT
- )
+ ) {
/* Global symbol: see if we came across a dbx defintion for
a corresponding symbol. If so, store the value. Remove
syms from the chain when their values are stored, but
be satisfied in each file as it appears. So we skip this
section. */
;
+ }
}
- end_symtab (text_offset + text_size);
+
+ return end_symtab (text_offset + text_size);
}
\f
static int
}
#endif
if (last_source_file)
- end_symtab (valu);
+ (void)end_symtab (valu);
start_symtab (name, NULL, valu);
break;
case N_ECOML:
case N_LENG:
+ case N_DEFD: /* GNU Modula-2 symbol */
break;
default:
get this name). */
static char *type_synonym_name;
+/* ARGSUSED */
static struct symbol *
define_symbol (valu, string, desc, type)
unsigned int valu;
} else {
SYMBOL_LINE(sym) = 0; /* unknown */
}
-
+
if (string[0] == CPLUS_MARKER)
{
/* Special GNU C++ names. */
case 'r':
{
double d = atof (p);
- char *valu;
+ char *dbl_valu;
SYMBOL_TYPE (sym) = builtin_type_double;
- valu = (char *) obstack_alloc (symbol_obstack, sizeof (double));
- bcopy (&d, valu, sizeof (double));
- SWAP_TARGET_AND_HOST (valu, sizeof (double));
- SYMBOL_VALUE_BYTES (sym) = valu;
+ dbl_valu =
+ (char *) obstack_alloc (symbol_obstack, sizeof (double));
+ bcopy (&d, dbl_valu, sizeof (double));
+ SWAP_TARGET_AND_HOST (dbl_valu, sizeof (double));
+ SYMBOL_VALUE_BYTES (sym) = dbl_valu;
SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
}
break;
}
else
{
- struct type *type;
+ struct type *type_read;
synonym = *p == 't';
if (synonym)
strlen (SYMBOL_NAME (sym)));
}
- type = read_type (&p);
+ type_read = read_type (&p);
if ((deftype == 'F' || deftype == 'f')
- && TYPE_CODE (type) != TYPE_CODE_FUNC)
- SYMBOL_TYPE (sym) = lookup_function_type (type);
+ && TYPE_CODE (type_read) != TYPE_CODE_FUNC)
+ {
+#if 0
+/* This code doesn't work -- it needs to realloc and can't. */
+ struct type *new = (struct type *)
+ obstack_alloc (symbol_obstack, sizeof (struct type));
+
+ /* Generate a template for the type of this function. The
+ types of the arguments will be added as we read the symbol
+ table. */
+ *new = *lookup_function_type (type_read);
+ SYMBOL_TYPE(sym) = new;
+ in_function_type = new;
+#else
+ SYMBOL_TYPE (sym) = lookup_function_type (type_read);
+#endif
+ }
else
- SYMBOL_TYPE (sym) = type;
+ SYMBOL_TYPE (sym) = type_read;
}
switch (deftype)
SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type);
SYMBOL_VALUE (sym) = valu;
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+#if 0
+ /* This doesn't work yet. */
+ add_param_to_type (&in_function_type, sym);
+#endif
add_symbol_to_list (sym, &local_symbols);
/* If it's gcc-compiled, if it says `short', believe it. */
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)
&& TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)))
{
- int i;
- for (i = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)) - 1; i >= 0; i--)
- if (TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), i) == 0)
- TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), i) =
- type_name_no_tag (TYPE_BASECLASS (SYMBOL_TYPE (sym), i));
+ int j;
+ for (j = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)) - 1; j >= 0; j--)
+ if (TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) == 0)
+ TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) =
+ type_name_no_tag (TYPE_BASECLASS (SYMBOL_TYPE (sym), j));
}
add_symbol_to_list (sym, &file_symbols);
return_type = read_type (pp);
if (*(*pp)++ != ';')
complain (&invalid_member_complaint, symnum);
- type = lookup_function_type (return_type);
+ type = allocate_stub_method (return_type);
if (typenums[0] != -1)
*dbx_lookup_type (typenums) = type;
- TYPE_CODE (type) = TYPE_CODE_METHOD;
- TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
}
else
{
return TYPE_FN_FIELD_FCONTEXT (f, j);
}
}
- for (i = TYPE_N_BASECLASSES (type); i > 0; i--)
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
basetype = virtual_context (for_type, TYPE_BASECLASS (type, i), name,
fn_type, offset);
/* Special GNU C++ name. */
if (*++p == 'v')
{
- char *prefix, *name; /* FIXME: NAME never set! */
+ const char *prefix;
+ char *name = 0;
struct type *context;
switch (*++p)
{
if (name == 0)
error ("type name unknown at symtab pos %d.", symnum);
+ /* FIXME-tiemann: when is `name' ever non-0? */
TYPE_NAME (context) = obsavestring (name, p - name - 1);
}
list->field.name = obconcat (prefix, type_name_no_tag (context), "");
/* This field is unpacked. */
list->field.bitsize = 0;
}
+ /* GNU C++ anonymous type. */
+ else if (*p == '_')
+ break;
else
error ("invalid abbreviation at symtab pos %d.", symnum);
list->field.bitsize = read_number (pp, ';');
#if 0
- /* FIXME tiemann: what is the story here? What does the compiler
+ /* FIXME-tiemann: Can't the compiler put out something which
+ lets us distinguish these? (or maybe just not put out anything
+ for the field). What is the story here? What does the compiler
really do? Also, patch gdb.texinfo for this case; I document
it as a possible problem there. Search for "DBX-style". */
{
int i;
struct next_fnfield *sublist = 0;
+ struct type *look_ahead_type = NULL;
int length = 0;
struct next_fnfieldlist *new_mainlist =
(struct next_fnfieldlist *)alloca (sizeof (struct next_fnfieldlist));
/* 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] = "operator";
- char *o = opname + 8;
+ static char opname[32] = {'o', 'p', CPLUS_MARKER};
+ char *o = opname + 3;
/* Skip past '::'. */
p += 2;
(struct next_fnfield *)alloca (sizeof (struct next_fnfield));
/* Check for and handle cretinous dbx symbol name continuation! */
- if (**pp == '\\') *pp = next_symbol_text ();
+ if (look_ahead_type == NULL) /* Normal case. */
+ {
+ if (**pp == '\\') *pp = next_symbol_text ();
- new_sublist->fn_field.type = read_type (pp);
- if (**pp != ':')
- /* Invalid symtab info for method. */
- return error_type (pp);
+ new_sublist->fn_field.type = read_type (pp);
+ if (**pp != ':')
+ /* Invalid symtab info for method. */
+ return error_type (pp);
+ }
+ else
+ { /* g++ version 1 kludge */
+ new_sublist->fn_field.type = look_ahead_type;
+ look_ahead_type = NULL;
+ }
*pp += 1;
p = *pp;
*pp = p + 1;
new_sublist->visibility = *(*pp)++ - '0';
if (**pp == '\\') *pp = next_symbol_text ();
- /* FIXME: tiemann needs to add const/volatile info
+ /* FIXME-tiemann: need to add const/volatile info
to the methods. For now, just skip the char.
In future, here's what we need to implement:
D for `const volatile' member functions. */
if (**pp == 'A' || **pp == 'B' || **pp == 'C' || **pp == 'D')
(*pp)++;
+#if 0
+ /* This probably just means we're processing a file compiled
+ with g++ version 1. */
else
complain(&const_vol_complaint, **pp);
+#endif /* 0 */
switch (*(*pp)++)
{
new_sublist->fn_field.voffset =
(0x7fffffff & read_number (pp, ';')) + 1;
- /* Figure out from whence this virtual function came.
- It may belong to virtual function table of
- one of its baseclasses. */
- new_sublist->fn_field.fcontext = read_type (pp);
- if (**pp != ';')
- error_type (pp);
+ if (**pp == '\\') *pp = next_symbol_text ();
+
+ if (**pp == ';' || **pp == '\0')
+ /* Must be g++ version 1. */
+ new_sublist->fn_field.fcontext = 0;
else
- ++*pp;
+ {
+ /* Figure out from whence this virtual function came.
+ It may belong to virtual function table of
+ one of its baseclasses. */
+ look_ahead_type = read_type (pp);
+ if (**pp == ':')
+ { /* g++ version 1 overloaded methods. */ }
+ else
+ {
+ new_sublist->fn_field.fcontext = look_ahead_type;
+ if (**pp != ';')
+ return error_type (pp);
+ else
+ ++*pp;
+ look_ahead_type = NULL;
+ }
+ }
break;
case '?':
/* **pp == '.'. */
/* normal member function. */
new_sublist->fn_field.voffset = 0;
+ new_sublist->fn_field.fcontext = 0;
break;
}
sublist = new_sublist;
length++;
}
- while (**pp != ';' && *pp != '\0');
+ while (**pp != ';' && **pp != '\0');
*pp += 1;
if (type == t)
{
if (TYPE_FIELD_NAME (t, TYPE_N_BASECLASSES (t)) == 0)
- TYPE_VPTR_FIELDNO (type) = i = TYPE_N_BASECLASSES (t);
+ {
+ /* FIXME-tiemann: what's this? */
+#if 0
+ TYPE_VPTR_FIELDNO (type) = i = TYPE_N_BASECLASSES (t);
+#else
+ error_type (pp);
+#endif
+ }
else for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); --i)
if (! strncmp (TYPE_FIELD_NAME (t, i), vptr_name,
sizeof (vptr_name) -1))
TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
*pp = p + 1;
}
- else
- {
- TYPE_VPTR_BASETYPE (type) = 0;
- TYPE_VPTR_FIELDNO (type) = -1;
- }
- }
- else
- {
- TYPE_VPTR_BASETYPE (type) = 0;
- TYPE_VPTR_FIELDNO (type) = -1;
}
return type;
j = o_nsyms;
for (; j < syms->nsyms; j++,n++)
{
- struct symbol *sym = syms->symbol[j];
- SYMBOL_TYPE (sym) = type;
- TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (sym);
+ struct symbol *xsym = syms->symbol[j];
+ SYMBOL_TYPE (xsym) = type;
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
TYPE_FIELD_VALUE (type, n) = 0;
- TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (sym);
+ TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
TYPE_FIELD_BITSIZE (type, n) = 0;
}
if (syms == osyms)
break;
}
+ /* Is this Modula-2's BOOLEAN type? Flag it as such if so. */
+ if(TYPE_NFIELDS(type) == 2 &&
+ ((!strcmp(TYPE_FIELD_NAME(type,0),"TRUE") &&
+ !strcmp(TYPE_FIELD_NAME(type,1),"FALSE")) ||
+ (!strcmp(TYPE_FIELD_NAME(type,1),"TRUE") &&
+ !strcmp(TYPE_FIELD_NAME(type,0),"FALSE"))))
+ TYPE_CODE(type) = TYPE_CODE_BOOL;
+
return type;
}
char overflow = 0;
int nbits = 0;
int c;
+ long upper_limit;
if (*p == '-')
{
p++;
}
+ upper_limit = LONG_MAX / radix;
while ((c = *p++) >= '0' && c <= ('0' + radix))
{
- if (n <= LONG_MAX / radix)
+ if (n <= upper_limit)
{
n *= radix;
n += c - '0'; /* FIXME this overflows anyway */
}
}
-#define MAX_OF_TYPE(t) ((1 << (sizeof (t)*8 - 1)) - 1)
-#define MIN_OF_TYPE(t) (-(1 << (sizeof (t)*8 - 1)))
+#define MAX_OF_C_TYPE(t) ((1 << (sizeof (t)*8 - 1)) - 1)
+#define MIN_OF_C_TYPE(t) (-(1 << (sizeof (t)*8 - 1)))
static struct type *
read_range_type (pp, typenums)
nbits = n2bits;
}
+ /* Check for "long long". */
+ if (got_signed && nbits == TARGET_LONG_LONG_BIT)
+ return builtin_type_long_long;
+ if (got_unsigned && nbits == TARGET_LONG_LONG_BIT)
+ return builtin_type_unsigned_long_long;
+
if (got_signed || got_unsigned)
{
result_type = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (result_type, sizeof (struct type));
- TYPE_TARGET_TYPE (result_type) = (self_subrange ?
- builtin_type_int :
- *dbx_lookup_type(rangenums));
+ TYPE_CODE (result_type) = TYPE_CODE_RANGE;
+
+ TYPE_TARGET_TYPE (result_type) = *dbx_lookup_type(rangenums);
+
+ TYPE_NFIELDS (result_type) = 2;
+ TYPE_FIELDS (result_type) =
+ (struct field *) obstack_alloc (symbol_obstack,
+ 2 * sizeof (struct field));
+ bzero (TYPE_FIELDS (result_type), 2 * sizeof (struct field));
+ TYPE_FIELD_BITPOS (result_type, 0) = n2;
+ TYPE_FIELD_BITPOS (result_type, 1) = n3;
+#if 0
+/* Note that TYPE_LENGTH (result_type) is just overridden a few
+ statements down. What do we really need here? */
/* We have to figure out how many bytes it takes to hold this
range type. I'm going to assume that anything that is pushing
the bounds of a long was taken care of above. */
- if (n2 >= MIN_OF_TYPE(char) && n3 <= MAX_OF_TYPE(char))
+ if (n2 >= MIN_OF_C_TYPE(char) && n3 <= MAX_OF_C_TYPE(char))
TYPE_LENGTH (result_type) = 1;
- else if (n2 >= MIN_OF_TYPE(short) && n3 <= MAX_OF_TYPE(short))
+ else if (n2 >= MIN_OF_C_TYPE(short) && n3 <= MAX_OF_C_TYPE(short))
TYPE_LENGTH (result_type) = sizeof (short);
- else if (n2 >= MIN_OF_TYPE(int) && n3 <= MAX_OF_TYPE(int))
+ else if (n2 >= MIN_OF_C_TYPE(int) && n3 <= MAX_OF_C_TYPE(int))
TYPE_LENGTH (result_type) = sizeof (int);
- else if (n2 >= MIN_OF_TYPE(long) && n3 <= MAX_OF_TYPE(long))
+ else if (n2 >= MIN_OF_C_TYPE(long) && n3 <= MAX_OF_C_TYPE(long))
TYPE_LENGTH (result_type) = sizeof (long);
else
/* Ranged type doesn't fit within known sizes. */
+ /* FIXME -- use "long long" here. */
return error_type (pp);
+#endif
TYPE_LENGTH (result_type) = TYPE_LENGTH (TYPE_TARGET_TYPE (result_type));
- TYPE_CODE (result_type) = TYPE_CODE_RANGE;
- TYPE_NFIELDS (result_type) = 2;
- TYPE_FIELDS (result_type) =
- (struct field *) obstack_alloc (symbol_obstack,
- 2 * sizeof (struct field));
- bzero (TYPE_FIELDS (result_type), 2 * sizeof (struct field));
- TYPE_FIELD_BITPOS (result_type, 0) = n2;
- TYPE_FIELD_BITPOS (result_type, 1) = n3;
return result_type;
}
/* Register our willingness to decode symbols for SunOS and a.out and
b.out files handled by BFD... */
static struct sym_fns sunos_sym_fns = {"sunOs", 6,
- dbx_new_init, dbx_symfile_init,
- dbx_symfile_read, dbx_symfile_discard};
+ dbx_new_init, dbx_symfile_init, dbx_symfile_read};
static struct sym_fns aout_sym_fns = {"a.out", 5,
- dbx_new_init, dbx_symfile_init,
- dbx_symfile_read, dbx_symfile_discard};
+ dbx_new_init, dbx_symfile_init, dbx_symfile_read};
static struct sym_fns bout_sym_fns = {"b.out", 5,
- dbx_new_init, dbx_symfile_init,
- dbx_symfile_read, dbx_symfile_discard};
+ dbx_new_init, dbx_symfile_init, dbx_symfile_read};
void
_initialize_dbxread ()
undef_types_length = 0;
undef_types = (struct type **) xmalloc (undef_types_allocated *
sizeof (struct type *));
-
- dbx_new_init ();
}