static char *
operator_chars PARAMS ((char *, char **));
-static int
-find_line_common PARAMS ((struct linetable *, int, int *));
+static int find_line_common PARAMS ((struct linetable *, int, int *));
static struct partial_symbol *
lookup_partial_symbol PARAMS ((struct partial_symtab *, const char *,
char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
char *newname = type_name_no_tag (type);
- int is_constructor = STREQ (field_name, newname);
- int is_destructor = is_constructor && DESTRUCTOR_PREFIX_P (physname);
+ int is_constructor = (physname[0]=='_' && physname[1]=='_');
+ int is_destructor = DESTRUCTOR_PREFIX_P (physname);
/* Need a new type prefix. */
char *const_prefix = method->is_const ? "C" : "";
char *volatile_prefix = method->is_volatile ? "V" : "";
char buf[20];
-#ifndef GCC_MANGLE_BUG
- int len = strlen (newname);
+#ifdef GCC_MANGLE_BUG
+ int len = newname == NULL ? 0 : strlen (newname);
if (is_destructor)
{
strcpy (mangled_name, field_name);
}
strcat (mangled_name, buf);
- strcat (mangled_name, newname);
+ /* If the class doesn't have a name, i.e. newname NULL, then we just
+ mangle it using 0 for the length of the class. Thus it gets mangled
+ as something starting with `::' rather than `classname::'. */
+ if (newname != NULL)
+ strcat (mangled_name, newname);
+
#else
char *opname;
struct partial_symtab *psymtab;
CORE_ADDR pc;
{
- struct partial_symbol *best, *p;
+ struct partial_symbol *best = NULL, *p;
CORE_ADDR best_pc;
if (!psymtab)
struct symtab **symtab;
{
register struct symbol *sym;
- register struct symtab *s;
+ register struct symtab *s = NULL;
register struct partial_symtab *ps;
struct blockvector *bv;
register struct objfile *objfile;
register struct block *b;
register struct minimal_symbol *msymbol;
- char *temp;
- extern char *gdb_completer_word_break_characters;
/* Search specified block and its superiors. */
SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
SYMBOL_CLASS (sym) != LOC_REF_ARG &&
SYMBOL_CLASS (sym) != LOC_REGPARM &&
- SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR)
+ SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
+ SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
{
break;
}
register struct symtab *best_s = NULL;
register struct partial_symtab *ps;
register struct objfile *objfile;
- int distance = 0;;
+ int distance = 0;
-
- /* Search all symtabs for one whose file contains our pc */
+ /* Search all symtabs for the one whose file contains our address, and which
+ is the smallest of all the ones containing the address. This is designed
+ to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000
+ and symtab b is at 0x2000-0x3000. So the GLOBAL_BLOCK for a is from
+ 0x1000-0x4000, but for address 0x2345 we want to return symtab b.
+ This is said to happen for the mips; it might be swifter to create
+ several symtabs with the same name like xcoff does (I'm not sure). */
ALL_SYMTABS (objfile, s)
{
will cause a core dump), but maybe we can successfully
continue, so let's not. */
warning ("\
-(Internal error: pc 0x%x in read in psymtab, but not in symtab.)\n", pc);
+(Internal error: pc 0x%lx in read in psymtab, but not in symtab.)\n",
+ (unsigned long) pc);
s = PSYMTAB_TO_SYMTAB (ps);
}
return (s);
code in the middle of a subroutine. To properly find the end of a line's PC
range, we must search all symtabs associated with this compilation unit, and
find the one whose first PC is closer than that of the next line in this
- symtab.
-
- FIXME: We used to complain here about zero length or negative length line
- tables, but there are two problems with this: (1) some symtabs may not have
- any line numbers due to gcc -g1 compilation, and (2) this function is called
- during single stepping, when we don't own the terminal and thus can't
- produce any output. One solution might be to implement a mechanism whereby
- complaints can be queued until we regain control of the terminal. -fnf
- */
+ symtab. */
+
+/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
find_pc_line (pc, notcurrent)
if (!l)
continue;
len = l->nitems;
- if (len <= 0) /* See FIXME above. */
+ if (len <= 0)
{
+ /* I think len can be zero if the symtab lacks line numbers
+ (e.g. gcc -g1). (Either that or the LINETABLE is NULL;
+ I'm not sure which, and maybe it depends on the symbol
+ reader). */
continue;
}
return val;
}
\f
+static int find_line_symtab PARAMS ((struct symtab *, int, struct linetable **,
+ int *, int *));
+
+/* Find line number LINE in any symtab whose name is the same as
+ SYMTAB.
+
+ If found, return 1, set *LINETABLE to the linetable in which it was
+ found, set *INDEX to the index in the linetable of the best entry
+ found, and set *EXACT_MATCH nonzero if the value returned is an
+ exact match.
+
+ If not found, return 0. */
+
+static int
+find_line_symtab (symtab, line, linetable, index, exact_match)
+ struct symtab *symtab;
+ int line;
+ struct linetable **linetable;
+ int *index;
+ int *exact_match;
+{
+ int exact;
+
+ /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
+ so far seen. */
+
+ int best_index;
+ struct linetable *best_linetable;
+
+ /* First try looking it up in the given symtab. */
+ best_linetable = LINETABLE (symtab);
+ best_index = find_line_common (best_linetable, line, &exact);
+ if (best_index < 0 || !exact)
+ {
+ /* Didn't find an exact match. So we better keep looking for
+ another symtab with the same name. In the case of xcoff,
+ multiple csects for one source file (produced by IBM's FORTRAN
+ compiler) produce multiple symtabs (this is unavoidable
+ assuming csects can be at arbitrary places in memory and that
+ the GLOBAL_BLOCK of a symtab has a begin and end address). */
+
+ /* BEST is the smallest linenumber > LINE so far seen,
+ or 0 if none has been seen so far.
+ BEST_INDEX and BEST_LINETABLE identify the item for it. */
+ int best;
+
+ struct objfile *objfile;
+ struct symtab *s;
+
+ if (best_index >= 0)
+ best = best_linetable->item[best_index].line;
+ else
+ best = 0;
+
+ ALL_SYMTABS (objfile, s)
+ {
+ struct linetable *l;
+ int ind;
+
+ if (!STREQ (symtab->filename, s->filename))
+ continue;
+ l = LINETABLE (s);
+ ind = find_line_common (l, line, &exact);
+ if (ind >= 0)
+ {
+ if (exact)
+ {
+ best_index = ind;
+ best_linetable = l;
+ goto done;
+ }
+ if (best == 0 || l->item[ind].line < best)
+ {
+ best = l->item[ind].line;
+ best_index = ind;
+ best_linetable = l;
+ }
+ }
+ }
+ }
+ done:
+ if (best_index < 0)
+ return 0;
+
+ if (index)
+ *index = best_index;
+ if (linetable)
+ *linetable = best_linetable;
+ if (exact_match)
+ *exact_match = exact;
+ return 1;
+}
+\f
/* Find the PC value for a given source file and line number.
Returns zero for invalid line number.
The source file is specified with a struct symtab. */
struct symtab *symtab;
int line;
{
- register struct linetable *l;
- register int ind;
- int dummy;
+ struct linetable *l;
+ int ind;
if (symtab == 0)
return 0;
- l = LINETABLE (symtab);
- ind = find_line_common(l, line, &dummy);
- return (ind >= 0) ? l->item[ind].pc : 0;
+ if (find_line_symtab (symtab, line, &l, &ind, NULL))
+ return l->item[ind].pc;
+ else
+ return 0;
}
/* Find the range of pc values in a line.
int thisline;
CORE_ADDR *startptr, *endptr;
{
- register struct linetable *l;
- register int ind;
+ struct linetable *l;
+ int ind;
int exact_match; /* did we get an exact linenumber match */
if (symtab == 0)
return 0;
- l = LINETABLE (symtab);
- ind = find_line_common (l, thisline, &exact_match);
- if (ind >= 0)
+ if (find_line_symtab (symtab, thisline, &l, &ind, &exact_match))
{
*startptr = l->item[ind].pc;
/* If we have not seen an entry for the specified line,
if (item->line == lineno)
{
+ /* Return the first (lowest address) entry which matches. */
*exact_match = 1;
return i;
}
int ibase;
struct symbol *sym_class;
char *class_name = type_name_no_tag (t);
- /* Ignore this class if it doesn't have a name.
- This prevents core dumps, but is just a workaround
- because we might not find the function in
- certain cases, such as
- struct D {virtual int f();}
- struct C : D {virtual int g();}
- (in this case g++ 1.35.1- does not put out a name
- for D as such, it defines type 19 (for example) in
- the same stab as C, and then does a
- .stabs "D:T19" and a .stabs "D:t19".
- Thus
- "break C::f" should not be looking for field f in
- the class named D,
- but just for the field f in the baseclasses of C
- (no matter what their names).
-
- However, I don't know how to replace the code below
- that depends on knowing the name of D. */
+ /* Ignore this class if it doesn't have a name. This is ugly, but
+ unless we figure out how to get the physname without the name of
+ the class, then the loop can't do any good. */
if (class_name
&& (sym_class = lookup_symbol (class_name,
(struct block *)NULL,
(struct symtab **)NULL)))
{
int method_counter;
+ /* FIXME: Shouldn't this just be check_stub_type (t)? */
t = SYMBOL_TYPE (sym_class);
for (method_counter = TYPE_NFN_FIELDS (t) - 1;
method_counter >= 0;
/* Destructor is handled by caller, dont add it to the list */
if (DESTRUCTOR_PREFIX_P (phys_name))
continue;
+
+ /* FIXME: Why are we looking this up in the
+ SYMBOL_BLOCK_VALUE (sym_class)? It is intended as a hook
+ for nested types? If so, it should probably hook to the
+ type, not the symbol. mipsread.c is the only symbol
+ reader which sets the SYMBOL_BLOCK_VALUE for types, and
+ this is not documented in symtab.h. -26Aug93. */
+
sym_arr[i1] = lookup_symbol (phys_name,
SYMBOL_BLOCK_VALUE (sym_class),
VAR_NAMESPACE,
}
}
}
- /* Only search baseclasses if there is no match yet,
- * since names in derived classes override those in baseclasses.
- */
+
+ /* Only search baseclasses if there is no match yet, since names in
+ derived classes override those in baseclasses.
+
+ FIXME: The above is not true; it is only true of member functions
+ if they have the same number of arguments (??? - section 13.1 of the
+ ARM says the function members are not in the same scope but doesn't
+ really spell out the rules in a way I understand. In any case, if
+ the number of arguments differ this is a case in which we can overload
+ rather than hiding without any problem, and gcc 2.4.5 does overload
+ rather than hiding in this case). */
+
if (i1)
return i1;
for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
t = SYMBOL_TYPE (sym_class);
sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*));
- if (destructor_name_p (copy, t))
+ /* Cfront objects don't have fieldlists. */
+ if (destructor_name_p (copy, t) && TYPE_FN_FIELDLISTS (t) != NULL)
{
/* destructors are a special case. */
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, 0);
Find the next token (everything up to end or next whitespace). */
p = skip_quoted (*argptr);
+ if (is_quoted && p[-1] != '\'')
+ error ("Unmatched single quote.");
copy = (char *) alloca (p - *argptr + 1);
memcpy (copy, *argptr, p - *argptr);
copy[p - *argptr] = '\0';
if ((copy[0] == copy [p - *argptr - 1])
&& strchr (gdb_completer_quote_characters, copy[0]) != NULL)
{
- char *temp;
copy [p - *argptr - 1] = '\0';
copy++;
}
printf_filtered ("\nNon-debugging symbols:\n");
found_in_file = 1;
}
- printf_filtered (" %08x %s\n",
- SYMBOL_VALUE_ADDRESS (msymbol),
+ printf_filtered (" %08lx %s\n",
+ (unsigned long) SYMBOL_VALUE_ADDRESS (msymbol),
SYMBOL_SOURCE_NAME (msymbol));
}
}
#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
do { \
- completion_list_add_name (SYMBOL_NAME (symbol), (sym_text), (len), \
- (text), (word)); \
if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
+ /* Put only the mangled name on the list. */ \
+ /* Advantage: "b foo<TAB>" completes to "b foo(int, int)" */ \
+ /* Disadvantage: "b foo__i<TAB>" doesn't complete. */ \
completion_list_add_name \
(SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
+ else \
+ completion_list_add_name \
+ (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \
} while (0)
/* Test to see if the symbol specified by SYMNAME (which is already
{
char *p;
char quote_found;
- char *quote_pos;
+ char *quote_pos = NULL;
/* First see if this is a quoted string. */
quote_found = '\0';