aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 0e77e7f..98b6ca1 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -49,6 +49,8 @@ extern void select_source_symtab ();
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. */
@@ -867,6 +869,37 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
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)
@@ -1005,11 +1038,114 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, 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 */