/* Block-related functions for the GNU debugger, GDB.
- Copyright (C) 2003-2019 Free Software Foundation, Inc.
+ Copyright (C) 2003-2020 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-
-/* Local non-gdb includes. */
-#include "addrmap.h"
#include "block.h"
-#include "cp-support.h"
+#include "symtab.h"
+#include "symfile.h"
#include "gdb_obstack.h"
+#include "cp-support.h"
+#include "addrmap.h"
#include "gdbtypes.h"
#include "objfiles.h"
-#include "symfile.h"
-#include "symtab.h"
/* This is used by struct block to store namespace-related info for
C++ files, namely using declarations and the current namespace in
return get_objfile_arch (block_objfile (block));
}
-/* Return Nonzero if block a is lexically nested within block b,
- or if a and b have the same pc range.
- Return zero otherwise. */
+/* See block.h. */
-int
-contained_in (const struct block *a, const struct block *b)
+bool
+contained_in (const struct block *a, const struct block *b,
+ bool allow_nested)
{
if (!a || !b)
- return 0;
+ return false;
do
{
if (a == b)
- return 1;
+ return true;
/* If A is a function block, then A cannot be contained in B,
except if A was inlined. */
- if (BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a))
- return 0;
+ if (!allow_nested && BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a))
+ return false;
a = BLOCK_SUPERBLOCK (a);
}
while (a != NULL);
- return 0;
+ return false;
}
"DW_TAG_call_site %s in %s"),
paddress (gdbarch, pc),
(msym.minsym == NULL ? "???"
- : MSYMBOL_PRINT_NAME (msym.minsym)));
+ : msym.minsym->print_name ()));
}
return (struct call_site *) *slot;
}
/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
- ititialize its members to zero. */
+ initialize its members to zero. */
static void
block_initialize_namespace (struct block *block, struct obstack *obstack)
return block_iter_match_step (iterator, name, 0);
}
+/* Return true if symbol A is the best match possible for DOMAIN. */
+
+static bool
+best_symbol (struct symbol *a, const domain_enum domain)
+{
+ return (SYMBOL_DOMAIN (a) == domain
+ && SYMBOL_CLASS (a) != LOC_UNRESOLVED);
+}
+
+/* Return symbol B if it is a better match than symbol A for DOMAIN.
+ Otherwise return A. */
+
+static struct symbol *
+better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain)
+{
+ if (a == NULL)
+ return b;
+ if (b == NULL)
+ return a;
+
+ if (SYMBOL_DOMAIN (a) == domain
+ && SYMBOL_DOMAIN (b) != domain)
+ return a;
+ if (SYMBOL_DOMAIN (b) == domain
+ && SYMBOL_DOMAIN (a) != domain)
+ return b;
+
+ if (SYMBOL_CLASS (a) != LOC_UNRESOLVED
+ && SYMBOL_CLASS (b) == LOC_UNRESOLVED)
+ return a;
+ if (SYMBOL_CLASS (b) != LOC_UNRESOLVED
+ && SYMBOL_CLASS (a) == LOC_UNRESOLVED)
+ return b;
+
+ return a;
+}
+
/* See block.h.
Note that if NAME is the demangled form of a C++ symbol, we will fail
ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
{
- if (SYMBOL_DOMAIN (sym) == domain)
+ /* See comment related to PR gcc/debug/91507 in
+ block_lookup_symbol_primary. */
+ if (best_symbol (sym, domain))
return sym;
/* This is a bit of a hack, but symbol_matches_domain might ignore
STRUCT vs VAR domain symbols. So if a matching symbol is found,
make sure there is no "better" matching symbol, i.e., one with
exactly the same domain. PR 16253. */
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ if (symbol_matches_domain (sym->language (),
SYMBOL_DOMAIN (sym), domain))
- other = sym;
+ other = better_symbol (other, sym, domain);
}
return other;
}
ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
{
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ if (symbol_matches_domain (sym->language (),
SYMBOL_DOMAIN (sym), domain))
{
sym_found = sym;
sym != NULL;
sym = mdict_iter_match_next (lookup_name, &mdict_iter))
{
- if (SYMBOL_DOMAIN (sym) == domain)
+ /* With the fix for PR gcc/debug/91507, we get for:
+ ...
+ extern char *zzz[];
+ char *zzz[ ] = {
+ "abc",
+ "cde"
+ };
+ ...
+ DWARF which will result in two entries in the symbol table, a decl
+ with type char *[] and a def with type char *[2].
+
+ If we return the decl here, we don't get the value of zzz:
+ ...
+ $ gdb a.spec.out -batch -ex "p zzz"
+ $1 = 0x601030 <zzz>
+ ...
+ because we're returning the symbol without location information, and
+ because the fallback that uses the address from the minimal symbols
+ doesn't work either because the type of the decl does not specify a
+ size.
+
+ To fix this, we prefer def over decl in best_symbol and
+ better_symbol.
+
+ In absence of the gcc fix, both def and decl have type char *[], so
+ the only option to make this work is improve the fallback to use the
+ size of the minimal symbol. Filed as PR exp/24989. */
+ if (best_symbol (sym, domain))
return sym;
/* This is a bit of a hack, but symbol_matches_domain might ignore
STRUCT vs VAR domain symbols. So if a matching symbol is found,
make sure there is no "better" matching symbol, i.e., one with
exactly the same domain. PR 16253. */
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), domain))
- other = sym;
+ if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain))
+ other = better_symbol (other, sym, domain);
}
return other;
{
/* MATCHER is deliberately called second here so that it never sees
a non-domain-matching symbol. */
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), domain)
+ if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain)
&& matcher (sym, data))
return sym;
}