#include "symtab.h"
#include "symfile.h" /* Needed for "struct complaint" */
#include "objfiles.h"
+#include "gdbtypes.h"
#include "complaints.h"
#include <string.h>
#include "buildsym.h" /* Our own declarations */
#undef EXTERN
+/* For cleanup_undefined_types and finish_global_stabs (somewhat
+ questionable--see comment where we call them). */
+#include "stabsread.h"
+
static int
compare_line_numbers PARAMS ((const void *, const void *));
{"inner block not inside outer block", 0, 0};
struct complaint blockvector_complaint =
- {"block at 0x%x out of order", 0, 0};
+ {"block at 0x%lx out of order", 0, 0};
\f
/* maintain the lists of symbols and blocks */
(*listhead)->symbol[(*listhead)->nsyms++] = symbol;
}
-/* Find a symbol on a pending list. */
+/* Find a symbol named NAME on a LIST. NAME need not be '\0'-terminated;
+ LENGTH is the length of the name. */
struct symbol *
find_symbol_in_list (list, name, length)
if (symbol)
{
+ struct type *ftype = SYMBOL_TYPE (symbol);
SYMBOL_BLOCK_VALUE (symbol) = block;
BLOCK_FUNCTION (block) = symbol;
+
+ if (TYPE_NFIELDS (ftype) <= 0)
+ {
+ /* No parameter type information is recorded with the function's
+ type. Set that from the type of the parameter symbols. */
+ int nparams = 0, iparams;
+ struct symbol *sym;
+ for (i = 0; i < BLOCK_NSYMS (block); i++)
+ {
+ sym = BLOCK_SYM (block, i);
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ nparams++;
+ }
+ }
+ if (nparams > 0)
+ {
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+ for (i = iparams = 0; iparams < nparams; i++)
+ {
+ sym = BLOCK_SYM (block, i);
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+ iparams++;
+ }
+ }
+ }
+ }
}
else
{
static struct blockvector *
make_blockvector (objfile)
- struct objfile *objfile;
+ struct objfile *objfile;
{
register struct pending_block *next;
register struct blockvector *blockvector;
if (BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i-1))
> BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)))
{
+
+ /* FIXME-32x64: loses if CORE_ADDR doesn't fit in a
+ long. Possible solutions include a version of
+ complain which takes a callback, a
+ sprintf_address_numeric to match
+ print_address_numeric, or a way to set up a GDB_FILE
+ * which causes sprintf rather than fprintf to be
+ called. */
+
complain (&blockvector_complaint,
- BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
+ (unsigned long) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
}
}
}
\f
/* Start recording information about source code that came from an included
- (or otherwise merged-in) source file with a different name. */
+ (or otherwise merged-in) source file with a different name. NAME is
+ the name of the file (cannot be NULL), DIRNAME is the directory in which
+ it resides (or NULL if not known). */
void
start_subfile (name, dirname)
current_subfile = subfile;
/* Save its name and compilation directory name */
- subfile->name = (name == NULL)? NULL : strdup (name);
- subfile->dirname = (dirname == NULL) ? NULL : strdup (dirname);
+ subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name));
+ subfile->dirname =
+ (dirname == NULL) ? NULL : savestring (dirname, strlen (dirname));
/* Initialize line-number recording for this subfile. */
subfile->line_vector = NULL;
directives which specify a file name ending in .C.
So if the filename of this subfile ends in .C, then change the language
- of any pending subfiles from C to C++. .cc is also accepted, even
- though I don't think cfront allows it. */
+ of any pending subfiles from C to C++. We also accept any other C++
+ suffixes accepted by deduce_language_from_filename (in particular,
+ some people use .cxx with cfront). */
+ /* Likewise for f2c. */
if (subfile->name)
{
- char *p;
struct subfile *s;
+ enum language sublang = deduce_language_from_filename (subfile->name);
- p = strrchr (subfile->name, '.');
- if (p != NULL
- && (p[1] == 'C' && p[2] == '\0'
- || p[1] == 'c' && p[2] == 'c' && p[3] == '\0'))
+ if (sublang == language_cplus || sublang == language_fortran)
for (s = subfiles; s != NULL; s = s->next)
if (s->language == language_c)
- s->language = language_cplus;
+ s->language = sublang;
}
/* And patch up this file if necessary. */
if (subfile->language == language_c
&& subfile->next != NULL
- && subfile->next->language == language_cplus)
+ && (subfile->next->language == language_cplus
+ || subfile->next->language == language_fortran))
{
- subfile->language = language_cplus;
+ subfile->language = subfile->next->language;
}
}
&& subfile->name[strlen(subfile->name)-1] == '/')
{
subfile->dirname = subfile->name;
- subfile->name = strdup (name);
+ subfile->name = savestring (name, strlen (name));
/* Default the source language to whatever can be deduced from
the filename. If nothing can be deduced (such as for a C/C++
}
\f
-/* Manage the vector of line numbers for each subfile. */
+/* Add a linetable entry for line number LINE and address PC to the line
+ vector for SUBFILE. */
void
record_line (subfile, line, pc)
const PTR ln1p;
const PTR ln2p;
{
- return (((struct linetable_entry *) ln1p) -> line -
- ((struct linetable_entry *) ln2p) -> line);
+ struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
+ struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
+
+ /* Note: this code does not assume that CORE_ADDRs can fit in ints.
+ Please keep it that way. */
+ if (ln1->pc < ln2->pc)
+ return -1;
+
+ if (ln1->pc > ln2->pc)
+ return 1;
+
+ /* If pc equal, sort by line. I'm not sure whether this is optimum
+ behavior (see comment at struct linetable in symtab.h). */
+ return ln1->line - ln2->line;
}
\f
struct objfile *objfile;
int section;
{
- register struct symtab *symtab;
+ register struct symtab *symtab = NULL;
register struct blockvector *blockvector;
register struct subfile *subfile;
register struct context_stack *cstk;
finish_block (cstk->name, &local_symbols, cstk->old_blocks,
cstk->start_addr, end_addr, objfile);
- /* Debug: if context stack still has something in it,
- we are in trouble. */
if (context_stack_depth > 0)
{
- abort ();
+ /* This is said to happen with SCO. The old coffread.c code
+ simply emptied the context stack, so we do the same. FIXME:
+ Find out why it is happening. This is not believed to happen
+ in most cases (even for coffread.c); it used to be an abort(). */
+ static struct complaint msg =
+ {"Context stack not empty in end_symtab", 0, 0};
+ complain (&msg);
+ context_stack_depth = 0;
}
}
/* Cleanup any undefined types that have been left hanging around
(this needs to be done before the finish_blocks so that
file_symbols is still good).
- FIXME: Stabs specific. */
+
+ Both cleanup_undefined_types and finish_global_stabs are stabs
+ specific, but harmless for other symbol readers, since on gdb
+ startup or when finished reading stabs, the state is set so these
+ are no-ops. FIXME: Is this handled right in case of QUIT? Can
+ we make this cleaner? */
+
cleanup_undefined_types ();
finish_global_stabs (objfile);
for (subfile = subfiles; subfile; subfile = nextsub)
{
- int linetablesize;
+ int linetablesize = 0;
/* If we have blocks of symbols, make a symtab.
Otherwise, just ignore this file and any line number info in it. */
symtab = NULL;
{
if (subfile->line_vector)
{
- /* First, shrink the linetable to make more memory. */
linetablesize = sizeof (struct linetable) +
subfile->line_vector->nitems * sizeof (struct linetable_entry);
+#if 0
+ /* I think this is artifact from before it went on the obstack.
+ I doubt we'll need the memory between now and when we
+ free it later in this function. */
+ /* First, shrink the linetable to make more memory. */
subfile->line_vector = (struct linetable *)
xrealloc ((char *) subfile->line_vector, linetablesize);
+#endif
+ /* If sort_linevec is false, we might want just check to make
+ sure they are sorted and complain() if not, as a way of
+ tracking down compilers/symbol readers which don't get
+ them sorted right. */
if (sort_linevec)
qsort (subfile->line_vector->item,