/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
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. */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "defs.h"
#include "value.h"
#include "symfile.h"
#include "gdbcmd.h"
+#include "regex.h"
+#include "language.h"
#include <obstack.h>
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
-extern int close ();
-extern void qsort ();
extern char *getenv ();
extern char *cplus_demangle ();
static int find_line_common ();
struct partial_symtab *lookup_partial_symtab ();
static struct partial_symbol *lookup_partial_symbol ();
+static struct partial_symbol *lookup_demangled_partial_symbol ();
+static struct symbol *lookup_demangled_block_symbol ();
-/* These variables point to the objects
- representing the predefined C data types. */
-
-struct type *builtin_type_void;
-struct type *builtin_type_char;
-struct type *builtin_type_short;
-struct type *builtin_type_int;
-struct type *builtin_type_long;
-#ifdef LONG_LONG
-struct type *builtin_type_long_long;
-#endif
-struct type *builtin_type_unsigned_char;
-struct type *builtin_type_unsigned_short;
-struct type *builtin_type_unsigned_int;
-struct type *builtin_type_unsigned_long;
-#ifdef LONG_LONG
-struct type *builtin_type_unsigned_long_long;
-#endif
-struct type *builtin_type_float;
-struct type *builtin_type_double;
+/* The single non-language-specific builtin type */
struct type *builtin_type_error;
/* Block in which the most recently searched-for symbol was found.
If this is a stubbed struct (i.e. declared as struct foo *), see if
we can find a full definition in some other file. If so, copy this
definition, so we can use it in future. If not, set a flag so we
- don't waste too much time in future.
+ don't waste too much time in future. (FIXME, this doesn't seem
+ to be happening...)
This used to be coded as a macro, but I don't think it is called
often enough to merit such treatment.
struct symbol *sym;
if (name == 0)
{
- complain (&stub_noname_complaint, 0, 0);
+ complain (&stub_noname_complaint, 0);
return;
}
- if (sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
- (struct symtab **)NULL) )
+ sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
+ (struct symtab **)NULL);
+ if (sym)
bcopy (SYMBOL_TYPE(sym), type, sizeof (struct type));
}
}
lookup_primitive_typename (name)
char *name;
{
- if (!strcmp (name, "int"))
- return builtin_type_int;
- if (!strcmp (name, "long"))
- return builtin_type_long;
- if (!strcmp (name, "short"))
- return builtin_type_short;
- if (!strcmp (name, "char"))
- return builtin_type_char;
- if (!strcmp (name, "float"))
- return builtin_type_float;
- if (!strcmp (name, "double"))
- return builtin_type_double;
- if (!strcmp (name, "void"))
- return builtin_type_void;
- return 0;
+ struct type ** const *p;
+
+ for (p = current_language->la_builtin_type_vector; *p; p++)
+ if(!strcmp((**p)->name, name))
+ return **p;
+ return 0;
}
/* Lookup a typedef or primitive type named NAME,
{
struct type *tmp;
tmp = lookup_primitive_typename (name);
- if (!tmp && noerr)
+ if(tmp)
+ return tmp;
+ else if (!tmp && noerr)
return 0;
- error ("No type named %s.", name);
+ else
+ error ("No type named %s.", name);
}
return SYMBOL_TYPE (sym);
}
lookup_unsigned_typename (name)
char *name;
{
- if (!strcmp (name, "int"))
- return builtin_type_unsigned_int;
- if (!strcmp (name, "long"))
- return builtin_type_unsigned_long;
- if (!strcmp (name, "short"))
- return builtin_type_unsigned_short;
- if (!strcmp (name, "char"))
- return builtin_type_unsigned_char;
- error ("No type named unsigned %s.", name);
- return (struct type *)-1; /* for lint */
+ char *uns = alloca (strlen(name) + 10);
+
+ strcpy (uns, "unsigned ");
+ strcpy (uns+9, name);
+ return lookup_typename (uns, (struct block *)0, 0);
}
/* Lookup a structure type named "struct NAME",
}
/* Given a type TYPE, lookup the type of the component of type named
- NAME. */
+ NAME.
+ If NOERR is nonzero, return zero if NAME is not suitably defined. */
struct type *
-lookup_struct_elt_type (type, name)
+lookup_struct_elt_type (type, name, noerr)
struct type *type;
char *name;
+ int noerr;
{
int i;
error (" is not a structure or union type.");
}
+ check_stub_type (type);
+
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
- if (!strcmp (TYPE_FIELD_NAME (type, i), name))
- return TYPE_FIELD_TYPE (type, i);
+ {
+ char *t_field_name = TYPE_FIELD_NAME (type, i);
+ if (t_field_name && !strcmp (t_field_name, name))
+ return TYPE_FIELD_TYPE (type, i);
+ }
+ /* OK, it's not in this class. Recursively check the baseclasses. */
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ {
+ struct type *t = lookup_struct_elt_type (TYPE_BASECLASS (type, i),
+ name, 0);
+ if (t != NULL)
+ return t;
+ }
+
+ if (noerr)
+ return NULL;
+
target_terminal_ours ();
fflush (stdout);
fprintf (stderr, "Type ");
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM;
/* We assume the machine has only one representation for pointers! */
+ /* FIXME: This confuses host<->target data representations, and is a
+ poor assumption besides. */
TYPE_LENGTH (ptype) = sizeof (char *);
TYPE_CODE (ptype) = TYPE_CODE_PTR;
return ptype;
return mtype;
}
+/* Allocate a stub method whose return type is
+ TYPE. We will fill in arguments later. This always
+ returns a fresh type. If we unify this type with
+ an existing type later, the storage allocated
+ here can be freed. */
struct type *
-lookup_method_type (type, domain, args)
- struct type *type, *domain, **args;
+allocate_stub_method (type)
+ struct type *type;
+{
+ struct type *mtype = (struct type *)xmalloc (sizeof (struct type));
+ bzero (mtype, sizeof (struct type));
+ TYPE_MAIN_VARIANT (mtype) = mtype;
+ TYPE_TARGET_TYPE (mtype) = type;
+ TYPE_FLAGS (mtype) = TYPE_FLAG_STUB;
+ TYPE_CODE (mtype) = TYPE_CODE_METHOD;
+ TYPE_LENGTH (mtype) = 1;
+ return mtype;
+}
+
+/* Lookup a method type belonging to class DOMAIN, returning type TYPE,
+ and taking a list of arguments ARGS.
+ If one is not found, allocate a new one. */
+
+struct type *
+lookup_method_type (domain, type, args)
+ struct type *domain, *type, **args;
{
register struct type *mtype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
{
struct type *result_type = (struct type *)
obstack_alloc (symbol_obstack, sizeof (struct type));
+ struct type *range_type;
bzero (result_type, sizeof (struct type));
TYPE_NFIELDS (result_type) = 1;
TYPE_FIELDS (result_type) =
(struct field *) obstack_alloc (symbol_obstack, sizeof (struct field));
- TYPE_FIELD_TYPE (result_type, 0) = builtin_type_int;
+
+ {
+ /* Create range type. */
+ range_type = (struct type *) obstack_alloc (symbol_obstack,
+ sizeof (struct type));
+ TYPE_CODE (range_type) = TYPE_CODE_RANGE;
+ TYPE_TARGET_TYPE (range_type) = builtin_type_int; /* FIXME */
+
+ /* This should never be needed. */
+ TYPE_LENGTH (range_type) = sizeof (int);
+
+ TYPE_NFIELDS (range_type) = 2;
+ TYPE_FIELDS (range_type) =
+ (struct field *) obstack_alloc (symbol_obstack,
+ 2 * sizeof (struct field));
+ TYPE_FIELD_BITPOS (range_type, 0) = 0; /* FIXME */
+ TYPE_FIELD_BITPOS (range_type, 1) = number-1; /* FIXME */
+ TYPE_FIELD_TYPE (range_type, 0) = builtin_type_int; /* FIXME */
+ TYPE_FIELD_TYPE (range_type, 1) = builtin_type_int; /* FIXME */
+ }
+ TYPE_FIELD_TYPE(result_type,0)=range_type;
TYPE_VPTR_FIELDNO (result_type) = -1;
return result_type;
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, 0);
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
if (BLOCK_START (b) <= BLOCK_START (block)
&& BLOCK_END (b) > BLOCK_START (block))
break;
block = BLOCK_SUPERBLOCK (block);
}
+ /* But that doesn't do any demangling for the STATIC_BLOCK.
+ I'm not sure whether demangling is needed in the case of
+ nested function in inner blocks; if so this needs to be changed.
+
+ Don't need to mess with the psymtabs; if we have a block,
+ that file is read in. If we don't, then we deal later with
+ all the psymtab stuff that needs checking. */
+ if (namespace == VAR_NAMESPACE && block != NULL)
+ {
+ struct block *b;
+ /* Find the right symtab. */
+ for (s = symtab_list; s; s = s->next)
+ {
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ if (BLOCK_START (b) <= BLOCK_START (block)
+ && BLOCK_END (b) > BLOCK_START (block))
+ {
+ sym = lookup_demangled_block_symbol (b, name);
+ if (sym)
+ {
+ block_found = b;
+ if (symtab != NULL)
+ *symtab = s;
+ return sym;
+ }
+ }
+ }
+ }
+
+
/* C++: If requested to do so by the caller,
check to see if NAME is a field of `this'. */
if (is_a_field_of_this)
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 0);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, namespace);
if (sym)
{
if (ind != -1)
{
s = find_pc_symtab (misc_function_vector[ind].address);
+ /* If S is zero, there are no debug symbols for this file.
+ Skip this stuff and check for matching static symbols below. */
if (s)
{
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 0);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, misc_function_vector[ind].name,
namespace);
/* sym == 0 if symbol was found in the misc_function_vector
{
s = PSYMTAB_TO_SYMTAB(ps);
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 0);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, namespace);
if (!sym)
fatal ("Internal: global symbol found in psymtab but not in symtab");
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 1);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, name, namespace);
if (sym)
{
{
s = PSYMTAB_TO_SYMTAB(ps);
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 1);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, name, namespace);
if (!sym)
fatal ("Internal: static symbol found in psymtab but not in symtab");
return sym;
}
+ /* Now search all per-file blocks for static mangled symbols.
+ Do the symtabs first, then check the psymtabs. */
+
+ if (namespace == VAR_NAMESPACE)
+ {
+ for (s = symtab_list; s; s = s->next)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_demangled_block_symbol (block, name);
+ if (sym)
+ {
+ block_found = block;
+ if (symtab != NULL)
+ *symtab = s;
+ return sym;
+ }
+ }
+
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ if (!ps->readin && lookup_demangled_partial_symbol (ps, name))
+ {
+ s = PSYMTAB_TO_SYMTAB(ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_demangled_block_symbol (block, name);
+ if (!sym)
+ fatal ("Internal: static symbol found in psymtab but not in symtab");
+ if (symtab != NULL)
+ *symtab = s;
+ return sym;
+ }
+ }
+
if (symtab != NULL)
*symtab = NULL;
return 0;
}
+/* Look for a static demangled symbol in block BLOCK. */
+
+static struct symbol *
+lookup_demangled_block_symbol (block, name)
+ register struct block *block;
+ char *name;
+{
+ register int bot, top, inc;
+ register struct symbol *sym;
+
+ bot = 0;
+ top = BLOCK_NSYMS (block);
+ inc = name[0];
+
+ while (bot < top)
+ {
+ sym = BLOCK_SYM (block, bot);
+ if (SYMBOL_NAME (sym)[0] == inc
+ && SYMBOL_NAMESPACE (sym) == VAR_NAMESPACE)
+ {
+ char *demangled = cplus_demangle(SYMBOL_NAME (sym), -1);
+ if (demangled != NULL)
+ {
+ int cond = strcmp (demangled, name);
+ free (demangled);
+ if (!cond)
+ return sym;
+ }
+ }
+ bot++;
+ }
+
+ return 0;
+}
+
+/* Look, in partial_symtab PST, for static mangled symbol NAME. */
+
+static struct partial_symbol *
+lookup_demangled_partial_symbol (pst, name)
+ struct partial_symtab *pst;
+ char *name;
+{
+ struct partial_symbol *start, *psym;
+ int length = pst->n_static_syms;
+ register int inc = name[0];
+
+ if (!length)
+ return (struct partial_symbol *) 0;
+
+ start = static_psymbols.list + pst->statics_offset;
+ for (psym = start; psym < start + length; psym++)
+ {
+ if (SYMBOL_NAME (psym)[0] == inc
+ && SYMBOL_NAMESPACE (psym) == VAR_NAMESPACE)
+ {
+ char *demangled = cplus_demangle(SYMBOL_NAME (psym), -1);
+ if (demangled != NULL)
+ {
+ int cond = strcmp (demangled, name);
+ free (demangled);
+ if (!cond)
+ return psym;
+ }
+ }
+ }
+
+ return (struct partial_symbol *) 0;
+}
+
/* Look, in partial_symtab PST, for symbol NAME. Check the global
symbols if GLOBAL, the static symbols if not */
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, 0);
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
if (BLOCK_START (b) <= pc
&& BLOCK_END (b) > pc)
break;
{
ps = find_pc_psymtab (pc);
if (ps && ps->readin)
- fatal ("Internal error: pc in read in psymtab, but not in symtab.");
+ printf_filtered (
+ "(Internal error: pc in read in psymtab, but not in symtab.)\n");
if (ps)
s = PSYMTAB_TO_SYMTAB (ps);
{
val.symtab = alt_symtab;
val.line = alt_line - 1;
- val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, 0));
+ val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
val.end = alt_pc;
}
else
val.pc = best_pc;
val.end = (best_end ? best_end
: (alt_pc ? alt_pc
- : BLOCK_END (BLOCKVECTOR_BLOCK (bv, 0))));
+ : BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))));
}
return val;
}
return 0;
l = LINETABLE (symtab);
ind = find_line_common(l, line, &dummy);
- return ind ? l->item[ind].pc : 0;
+ return (ind >= 0) ? l->item[ind].pc : 0;
}
/* Find the range of pc values in a line.
l = LINETABLE (symtab);
ind = find_line_common (l, thisline, &exact_match);
- if (ind)
+ if (ind >= 0)
{
*startptr = l->item[ind].pc;
/* If we have not seen an entry for the specified line,
/* Given a line table and a line number, return the index into the line
table for the pc of the nearest line whose number is >= the specified one.
- Return 0 if none is found. The value is never zero is it is an index.
+ Return -1 if none is found. The value is >= 0 if it is an index.
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
or 0 if none has been seen so far.
BEST_INDEX identifies the item for it. */
- int best_index = 0;
+ int best_index = -1;
int best = 0;
if (lineno <= 0)
- return 0;
+ return -1;
len = l->nitems;
for (i = 0; i < len; i++)
return sal.symtab != 0;
}
\f
+/* If P is of the form "operator[ \t]+..." where `...' is
+ some legitimate operator text, return a pointer to the
+ beginning of the substring of the operator text.
+ Otherwise, return "". */
+static char *
+operator_chars (p, end)
+ char *p;
+ char **end;
+{
+ *end = "";
+ if (strncmp (p, "operator", 8))
+ return *end;
+ p += 8;
+
+ /* Don't get faked out by `operator' being part of a longer
+ identifier. */
+ if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')
+ || *p == '_' || *p == '$' || *p == '\0')
+ return *end;
+
+ /* Allow some whitespace between `operator' and the operator symbol. */
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ switch (*p)
+ {
+ case '!':
+ case '=':
+ case '*':
+ case '/':
+ case '%':
+ case '^':
+ if (p[1] == '=')
+ *end = p+2;
+ else
+ *end = p+1;
+ return p;
+ case '<':
+ case '>':
+ case '+':
+ case '-':
+ case '&':
+ case '|':
+ if (p[1] == '=' || p[1] == p[0])
+ *end = p+2;
+ else
+ *end = p+1;
+ return p;
+ case '~':
+ case ',':
+ *end = p+1;
+ return p;
+ case '(':
+ if (p[1] != ')')
+ error ("`operator ()' must be specified without whitespace in `()'");
+ *end = p+2;
+ return p;
+ case '?':
+ if (p[1] != ':')
+ error ("`operator ?:' must be specified without whitespace in `?:'");
+ *end = p+2;
+ return p;
+ case '[':
+ if (p[1] != ']')
+ error ("`operator []' must be specified without whitespace in `[]'");
+ *end = p+2;
+ return p;
+ default:
+ error ("`operator %s' not supported", p);
+ break;
+ }
+ *end = "";
+ return *end;
+}
+
/* Recursive helper function for decode_line_1.
* Look for methods named NAME in type T.
* Return number of matches.
struct symtabs_and_lines values;
struct symtab_and_line val;
register char *p, *p1;
+ char *q, *q1;
register struct symtab *s;
register struct symbol *sym;
}
while (p[0] == ' ' || p[0] == '\t') p++;
+ q = operator_chars (*argptr, &q1);
if (p[0] == ':')
{
Find the next token (everything up to end or next whitespace). */
p = *argptr;
while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;
- copy = (char *) alloca (p - *argptr + 1);
- bcopy (*argptr, copy, p - *argptr);
- copy[p - *argptr] = '\0';
+ q = operator_chars (*argptr, &q1);
+
+ copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
+ if (q1 - q)
+ {
+ copy[0] = 'o';
+ copy[1] = 'p';
+ copy[2] = CPLUS_MARKER;
+ bcopy (q, copy + 3, q1 - q);
+ copy[3 + (q1 - q)] = '\0';
+ p = q1;
+ }
+ else
+ {
+ bcopy (*argptr, copy, p - *argptr);
+ copy[p - *argptr] = '\0';
+ }
/* no line number may be specified */
while (*p == ' ' || *p == '\t') p++;
return decode_line_2 (sym_arr, i1, funfirstline);
}
else
- error ("that class does not have any method named %s",copy);
+ {
+ char *tmp;
+
+ if (OPNAME_PREFIX_P (copy))
+ {
+ tmp = (char *)alloca (strlen (copy+3) + 9);
+ strcpy (tmp, "operator ");
+ strcat (tmp, copy+3);
+ }
+ else
+ tmp = copy;
+ error ("that class does not have any method named %s", tmp);
+ }
}
else
/* The quotes are important if copy is empty. */
/* Extract the file name. */
p1 = p;
while (p != *argptr && p[-1] == ' ') --p;
- copy = (char *) alloca (p - *argptr + 1);
- bcopy (*argptr, copy, p - *argptr);
- copy[p - *argptr] = 0;
+ copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
+ if (q1 - q)
+ {
+ copy[0] = 'o';
+ copy[1] = 'p';
+ copy[2] = CPLUS_MARKER;
+ bcopy (q, copy + 3, q1-q);
+ copy[3 + (q1-q)] = 0;
+ p = q1;
+ }
+ else
+ {
+ bcopy (*argptr, copy, p - *argptr);
+ copy[p - *argptr] = 0;
+ }
/* Find that file's data. */
s = lookup_symtab (copy);
if (s == 0 && default_symtab == 0)
{
- if (symtab_list == 0 && partial_symtab_list == 0)
- error (no_symtab_msg);
select_source_symtab (0);
default_symtab = current_source_symtab;
default_line = current_source_line;
If file specified, use that file's per-file block to start with. */
sym = lookup_symbol (copy,
- (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1)
+ (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
: get_selected_block ()),
VAR_NAMESPACE, 0, &sym_symtab);
error ("Line number not known for symbol \"%s\"", copy);
}
- if (symtab_list == 0 && partial_symtab_list == 0)
- error (no_symtab_msg);
-
if ((i = lookup_misc_func (copy)) >= 0)
{
val.symtab = 0;
return values;
}
+ if (symtab_list == 0 && partial_symtab_list == 0 && misc_function_count == 0)
+ error (no_symtab_msg);
+
error ("Function %s not defined.", copy);
return values; /* for lint */
}
int nelts;
int funfirstline;
{
- char *getenv();
struct symtabs_and_lines values, return_values;
register CORE_ADDR pc;
char *args, *arg1, *command_line_input ();
If CLASS is zero, list all symbols except functions and type names.
If CLASS is 1, list only functions.
If CLASS is 2, list only type names.
+ If CLASS is 3, list only method names.
BPT is non-zero if we should set a breakpoint at the functions
we find. */
static char *classnames[]
= {"variable", "function", "type", "method"};
int found_in_file = 0;
+ int found_misc = 0;
+ static enum misc_function_type types[]
+ = {mf_data, mf_text, mf_abs, mf_unknown};
+ static enum misc_function_type types2[]
+ = {mf_bss, mf_text, mf_abs, mf_unknown};
+ enum misc_function_type ourtype = types[class];
+ enum misc_function_type ourtype2 = types2[class];
if (regexp)
- if (0 != (val = (char *) re_comp (regexp)))
+ if (0 != (val = re_comp (regexp)))
error ("Invalid regexp (%s): %s", val, regexp);
/* Search through the partial_symtab_list *first* for all symbols
}
else
keep_going = 0;
+ continue;
}
else
{
load the file and go on to the next one */
if ((regexp == 0 || re_exec (SYMBOL_NAME (psym)))
&& ((class == 0 && SYMBOL_CLASS (psym) != LOC_TYPEDEF
- && SYMBOL_CLASS (psym) != LOC_BLOCK)
+ && SYMBOL_CLASS (psym) != LOC_BLOCK)
|| (class == 1 && SYMBOL_CLASS (psym) == LOC_BLOCK)
|| (class == 2 && SYMBOL_CLASS (psym) == LOC_TYPEDEF)
|| (class == 3 && SYMBOL_CLASS (psym) == LOC_BLOCK)))
}
}
- /* Here, *if* the class is correct (function only, right now), we
- search through the misc function vector for symbols that
+ /* Here, we search through the misc function vector for functions that
match, and call find_pc_symtab on them to force their symbols to
be read. The symbol will then be found during the scan of symtabs
- below. */
-
- if (class == 1)
- {
- for (i = 0; i < misc_function_count; i++)
- if (regexp == 0 || re_exec (misc_function_vector[i].name))
- {
- (void) find_pc_symtab (misc_function_vector[i].address);
- }
+ below. If find_pc_symtab fails, set found_misc so that we will
+ rescan to print any matching symbols without debug info. */
+
+ if (class == 1) {
+ for (i = 0; i < misc_function_count; i++) {
+ if (misc_function_vector[i].type != ourtype
+ && misc_function_vector[i].type != ourtype2)
+ continue;
+ if (regexp == 0 || re_exec (misc_function_vector[i].name)) {
+ if (0 == find_pc_symtab (misc_function_vector[i].address))
+ found_misc = 1;
+ }
}
+ }
/* Printout here so as to get after the "Reading in symbols"
messages which will be generated above. */
It happens that the first symtab in the list
for any given blockvector is the main file. */
if (bv != prev_bv)
- for (i = 0; i < 2; i++)
+ for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
{
b = BLOCKVECTOR_BLOCK (bv, i);
/* Skip the sort if this block is always sorted. */
sym = BLOCK_SYM (b, j);
if ((regexp == 0 || re_exec (SYMBOL_NAME (sym)))
&& ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
- && SYMBOL_CLASS (sym) != LOC_BLOCK)
+ && SYMBOL_CLASS (sym) != LOC_BLOCK)
|| (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|| (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
}
found_in_file = 1;
- if (class != 2 && i == 1)
+ if (class != 2 && i == STATIC_BLOCK)
printf_filtered ("static ");
+
+ /* Typedef that is not a C++ class */
if (class == 2
&& SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
- printf_filtered ("typedef ");
-
- if (class < 3)
+ typedef_print (SYMBOL_TYPE(sym), sym, stdout);
+ /* variable, func, or typedef-that-is-c++-class */
+ else if (class < 2 ||
+ (class == 2 &&
+ SYMBOL_NAMESPACE(sym) == STRUCT_NAMESPACE))
{
- type_print (SYMBOL_TYPE (sym),
- (SYMBOL_CLASS (sym) == LOC_TYPEDEF
- ? "" : SYMBOL_NAME (sym)),
- stdout, 0);
-
- if (class == 2
- && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE
- && (TYPE_NAME ((SYMBOL_TYPE (sym))) == 0
- || 0 != strcmp (TYPE_NAME ((SYMBOL_TYPE (sym))),
- SYMBOL_NAME (sym))))
- {
- fputs_filtered (" ", stdout);
- fprint_symbol (stdout, SYMBOL_NAME (sym));
- }
-
- printf_filtered (";\n");
+ type_print (SYMBOL_TYPE (sym),
+ (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+ ? "" : SYMBOL_NAME (sym)),
+ stdout, 0);
+
+ printf_filtered (";\n");
}
else
{
}
prev_bv = bv;
}
+
+
+ /* If there are no eyes, avoid all contact. I mean, if there are
+ no debug symbols, then print directly from the misc_function_vector. */
+
+ if (found_misc || class != 1) {
+ found_in_file = 0;
+ for (i = 0; i < misc_function_count; i++) {
+ if (misc_function_vector[i].type != ourtype
+ && misc_function_vector[i].type != ourtype2)
+ continue;
+ if (regexp == 0 || re_exec (misc_function_vector[i].name)) {
+ /* Functions: Look up by address. */
+ if (class == 1)
+ if (0 != find_pc_symtab (misc_function_vector[i].address))
+ continue;
+ /* Variables/Absolutes: Look up by name */
+ if (0 != lookup_symbol (misc_function_vector[i].name,
+ (struct block *)0, VAR_NAMESPACE, 0, (struct symtab **)0))
+ continue;
+ if (!found_in_file) {
+ printf_filtered ("\nNon-debugging symbols:\n");
+ found_in_file = 1;
+ }
+ printf_filtered (" %08x %s\n",
+ misc_function_vector[i].address,
+ misc_function_vector[i].name);
+ }
+ }
+ }
}
static void
list_symbols (regexp, 1, 0);
}
-#if 0
static void
types_info (regexp)
char *regexp;
{
list_symbols (regexp, 2, 0);
}
-#endif
#if 0
/* Tiemann says: "info methods was never implemented." */
list_symbols (regexp, 1, 1);
}
\f
-/* Initialize the standard C scalar types. */
+/* Helper function to initialize the standard scalar types. */
-static
struct type *
init_type (code, length, uns, name)
enum type_code code;
for (s = symtab_list; s; s = s->next)
{
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 0);
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
for (i = 0; i < BLOCK_NSYMS (b); i++)
if (!strncmp (SYMBOL_NAME (BLOCK_SYM (b, i)), text, text_len))
for (s = symtab_list; s; s = s->next)
{
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1);
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
/* Don't do this block twice. */
if (b == surrounding_static_block) continue;
return (return_val);
}
\f
+#if 0
+/* Add the type of the symbol sym to the type of the current
+ function whose block we are in (assumed). The type of
+ this current function is contained in *TYPE.
+
+ This basically works as follows: When we find a function
+ symbol (N_FUNC with a 'f' or 'F' in the symbol name), we record
+ a pointer to its type in the global in_function_type. Every
+ time we come across a parameter symbol ('p' in its name), then
+ this procedure adds the name and type of that parameter
+ to the function type pointed to by *TYPE. (Which should correspond
+ to in_function_type if it was called correctly).
+
+ Note that since we are modifying a type, the result of
+ lookup_function_type() should be bcopy()ed before calling
+ this. When not in strict typing mode, the expression
+ evaluator can choose to ignore this.
+
+ Assumption: All of a function's parameter symbols will
+ appear before another function symbol is found. The parameters
+ appear in the same order in the argument list as they do in the
+ symbol table. */
+
+void
+add_param_to_type (type,sym)
+ struct type **type;
+ struct symbol *sym;
+{
+ int num = ++(TYPE_NFIELDS(*type));
+
+ if(TYPE_NFIELDS(*type)-1)
+ TYPE_FIELDS(*type) =
+ (struct field *)xrealloc((char *)(TYPE_FIELDS(*type)),
+ num*sizeof(struct field));
+ else
+ TYPE_FIELDS(*type) =
+ (struct field *)xmalloc(num*sizeof(struct field));
+
+ TYPE_FIELD_BITPOS(*type,num-1) = num-1;
+ TYPE_FIELD_BITSIZE(*type,num-1) = 0;
+ TYPE_FIELD_TYPE(*type,num-1) = SYMBOL_TYPE(sym);
+ TYPE_FIELD_NAME(*type,num-1) = SYMBOL_NAME(sym);
+}
+#endif
+\f
void
_initialize_symtab ()
{
"All global and static variable names, or those matching REGEXP.");
add_info ("functions", functions_info,
"All function names, or those matching REGEXP.");
-#if 0
- /* This command has at least the following problems:
+
+ /* FIXME: This command has at least the following problems:
1. It prints builtin types (in a very strange and confusing fashion).
2. It doesn't print right, e.g. with
typedef struct foo *FOO
there is much disagreement "info types" can be fixed). */
add_info ("types", types_info,
"All types names, or those matching REGEXP.");
-#endif
+
#if 0
add_info ("methods", methods_info,
"All method names, or those matching REGEXP::REGEXP.\n\
add_com ("rbreak", no_class, rbreak_command,
"Set a breakpoint for all functions matching REGEXP.");
- /* FIXME: The code below assumes that the sizes of the basic data
- types are the same on the host and target machines!!! */
-
- builtin_type_void = init_type (TYPE_CODE_VOID, 1, 0, "void");
-
- builtin_type_float = init_type (TYPE_CODE_FLT, sizeof (float), 0, "float");
- builtin_type_double = init_type (TYPE_CODE_FLT, sizeof (double), 0, "double");
-
- builtin_type_char = init_type (TYPE_CODE_INT, sizeof (char), 0, "char");
- builtin_type_short = init_type (TYPE_CODE_INT, sizeof (short), 0, "short");
- builtin_type_long = init_type (TYPE_CODE_INT, sizeof (long), 0, "long");
- builtin_type_int = init_type (TYPE_CODE_INT, sizeof (int), 0, "int");
-
- builtin_type_unsigned_char = init_type (TYPE_CODE_INT, sizeof (char), 1, "unsigned char");
- builtin_type_unsigned_short = init_type (TYPE_CODE_INT, sizeof (short), 1, "unsigned short");
- builtin_type_unsigned_long = init_type (TYPE_CODE_INT, sizeof (long), 1, "unsigned long");
- builtin_type_unsigned_int = init_type (TYPE_CODE_INT, sizeof (int), 1, "unsigned int");
-#ifdef LONG_LONG
- builtin_type_long_long =
- init_type (TYPE_CODE_INT, sizeof (long long), 0, "long long");
- builtin_type_unsigned_long_long =
- init_type (TYPE_CODE_INT, sizeof (long long), 1, "unsigned long long");
-#endif
+ /* Initialize the one built-in type that isn't language dependent... */
builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0, "<unknown type>");
}
-