PR c++/17976, symtab/17821
This patch addresses two issues. The basic problem is that "(anonymous namespace)" doesn't get entered into the symbol table because when dwarf2read.c:new_symbol_full is called the DIE has no name (dwarf2_name returns NULL). PR 17976: ptype '(anonymous namespace)' should work like any namespace PR 17821: perf issue looking up (anonymous namespace) bash$ gdb monster-program (gdb) mt set per on (gdb) mt set symbol-cache-size 0 (gdb) break (anonymous namespace)::foo Before: Command execution time: 3.266289 (cpu), 6.169030 (wall) Space used: 811429888 (+12910592 for this command) After: Command execution time: 1.264076 (cpu), 4.057408 (wall) Space used: 798781440 (+0 for this command) gdb/ChangeLog: PR c++/17976, symtab/17821 * cp-namespace.c (cp_search_static_and_baseclasses): New parameter is_in_anonymous. All callers updated. (find_symbol_in_baseclass): Ditto. (cp_lookup_nested_symbol_1): Ditto. Don't search all static blocks for symbols in an anonymous namespace. * dwarf2read.c (namespace_name): Don't call dwarf2_name, fetch DW_AT_name directly. (dwarf2_name): Convert missing namespace name to CP_ANONYMOUS_NAMESPACE_STR. gdeb/testsuite/ChangeLog: * gdb.cp/anon-ns.exp: Add test for ptype '(anonymous namespace)'.
This commit is contained in:
parent
e26473a140
commit
96553a0cff
5 changed files with 63 additions and 17 deletions
|
@ -1,3 +1,16 @@
|
|||
2015-02-21 Doug Evans <dje@google.com>
|
||||
|
||||
PR c++/17976, symtab/17821
|
||||
* cp-namespace.c (cp_search_static_and_baseclasses): New parameter
|
||||
is_in_anonymous. All callers updated.
|
||||
(find_symbol_in_baseclass): Ditto.
|
||||
(cp_lookup_nested_symbol_1): Ditto. Don't search all static blocks
|
||||
for symbols in an anonymous namespace.
|
||||
* dwarf2read.c (namespace_name): Don't call dwarf2_name, fetch
|
||||
DW_AT_name directly.
|
||||
(dwarf2_name): Convert missing namespace name to
|
||||
CP_ANONYMOUS_NAMESPACE_STR.
|
||||
|
||||
2015-02-20 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* linux-nat.c (linux_handle_extended_wait): Call
|
||||
|
|
|
@ -37,7 +37,7 @@ static struct symbol *
|
|||
const char *nested_name,
|
||||
const char *concatenated_name,
|
||||
const struct block *block,
|
||||
int basic_lookup);
|
||||
int basic_lookup, int is_in_anonymous);
|
||||
|
||||
static struct type *cp_lookup_transparent_type_loop (const char *name,
|
||||
const char *scope,
|
||||
|
@ -327,7 +327,8 @@ static struct symbol *
|
|||
cp_search_static_and_baseclasses (const char *name,
|
||||
const struct block *block,
|
||||
const domain_enum domain,
|
||||
unsigned int prefix_len)
|
||||
unsigned int prefix_len,
|
||||
int is_in_anonymous)
|
||||
{
|
||||
struct symbol *sym;
|
||||
char *klass, *nested;
|
||||
|
@ -366,7 +367,8 @@ cp_search_static_and_baseclasses (const char *name,
|
|||
/* Look for a symbol named NESTED in this class.
|
||||
The caller is assumed to have already have done a basic lookup of NAME.
|
||||
So we pass zero for BASIC_LOOKUP to cp_lookup_nested_symbol_1 here. */
|
||||
sym = cp_lookup_nested_symbol_1 (klass_type, nested, name, block, 0);
|
||||
sym = cp_lookup_nested_symbol_1 (klass_type, nested, name, block, 0,
|
||||
is_in_anonymous);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return sym;
|
||||
|
@ -416,7 +418,8 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
|
|||
return sym;
|
||||
|
||||
if (search)
|
||||
sym = cp_search_static_and_baseclasses (name, block, domain, prefix_len);
|
||||
sym = cp_search_static_and_baseclasses (name, block, domain, prefix_len,
|
||||
is_in_anonymous);
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
@ -900,7 +903,7 @@ cp_find_type_baseclass_by_name (struct type *parent_type, const char *name)
|
|||
|
||||
static struct symbol *
|
||||
find_symbol_in_baseclass (struct type *parent_type, const char *name,
|
||||
const struct block *block)
|
||||
const struct block *block, int is_in_anonymous)
|
||||
{
|
||||
int i;
|
||||
struct symbol *sym;
|
||||
|
@ -925,7 +928,7 @@ find_symbol_in_baseclass (struct type *parent_type, const char *name,
|
|||
xsnprintf (concatenated_name, len, "%s::%s", base_name, name);
|
||||
|
||||
sym = cp_lookup_nested_symbol_1 (base_type, name, concatenated_name,
|
||||
block, 1);
|
||||
block, 1, is_in_anonymous);
|
||||
if (sym != NULL)
|
||||
break;
|
||||
}
|
||||
|
@ -942,16 +945,17 @@ find_symbol_in_baseclass (struct type *parent_type, const char *name,
|
|||
passed as an argument so that callers can control how space for it is
|
||||
allocated.
|
||||
If BASIC_LOOKUP is non-zero then perform a basic lookup of
|
||||
CONCATENATED_NAME. See cp_basic_lookup_symbol for details. */
|
||||
CONCATENATED_NAME. See cp_basic_lookup_symbol for details.
|
||||
If IS_IN_ANONYMOUS is non-zero then CONCATENATED_NAME is in an anonymous
|
||||
namespace. */
|
||||
|
||||
static struct symbol *
|
||||
cp_lookup_nested_symbol_1 (struct type *container_type,
|
||||
const char *nested_name,
|
||||
const char *concatenated_name,
|
||||
const struct block *block,
|
||||
int basic_lookup)
|
||||
int basic_lookup, int is_in_anonymous)
|
||||
{
|
||||
int is_in_anonymous = cp_is_in_anonymous (concatenated_name);
|
||||
struct symbol *sym;
|
||||
|
||||
/* NOTE: carlton/2003-11-10: We don't treat C++ class members
|
||||
|
@ -981,16 +985,22 @@ cp_lookup_nested_symbol_1 (struct type *container_type,
|
|||
|
||||
/* Nope. We now have to search all static blocks in all objfiles,
|
||||
even if block != NULL, because there's no guarantees as to which
|
||||
symtab the symbol we want is in. */
|
||||
symtab the symbol we want is in. Except for symbols defined in
|
||||
anonymous namespaces should be treated as local to a single file,
|
||||
which we just searched. */
|
||||
if (!is_in_anonymous)
|
||||
{
|
||||
sym = lookup_static_symbol (concatenated_name, VAR_DOMAIN);
|
||||
if (sym != NULL)
|
||||
return sym;
|
||||
}
|
||||
|
||||
/* If this is a class with baseclasses, search them next. */
|
||||
CHECK_TYPEDEF (container_type);
|
||||
if (TYPE_N_BASECLASSES (container_type) > 0)
|
||||
{
|
||||
sym = find_symbol_in_baseclass (container_type, nested_name, block);
|
||||
sym = find_symbol_in_baseclass (container_type, nested_name, block,
|
||||
is_in_anonymous);
|
||||
if (sym != NULL)
|
||||
return sym;
|
||||
}
|
||||
|
@ -1038,14 +1048,17 @@ cp_lookup_nested_symbol (struct type *parent_type,
|
|||
const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
|
||||
struct symbol *sym;
|
||||
char *concatenated_name;
|
||||
int is_in_anonymous;
|
||||
|
||||
size = strlen (parent_name) + 2 + strlen (nested_name) + 1;
|
||||
concatenated_name = alloca (size);
|
||||
xsnprintf (concatenated_name, size, "%s::%s",
|
||||
parent_name, nested_name);
|
||||
is_in_anonymous = cp_is_in_anonymous (concatenated_name);
|
||||
|
||||
sym = cp_lookup_nested_symbol_1 (parent_type, nested_name,
|
||||
concatenated_name, block, 1);
|
||||
concatenated_name, block, 1,
|
||||
is_in_anonymous);
|
||||
|
||||
if (symbol_lookup_debug)
|
||||
{
|
||||
|
|
|
@ -14109,7 +14109,12 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
|
|||
current_die != NULL;
|
||||
current_die = dwarf2_extension (die, &cu))
|
||||
{
|
||||
name = dwarf2_name (current_die, cu);
|
||||
/* We don't use dwarf2_name here so that we can detect the absence
|
||||
of a name -> anonymous namespace. */
|
||||
struct attribute *attr = dwarf2_attr (die, DW_AT_name, cu);
|
||||
|
||||
if (attr != NULL)
|
||||
name = DW_STRING (attr);
|
||||
if (name != NULL)
|
||||
break;
|
||||
}
|
||||
|
@ -19253,7 +19258,8 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
|
|||
return name;
|
||||
}
|
||||
|
||||
/* Get name of a die, return NULL if not found. */
|
||||
/* Get name of a die, return NULL if not found.
|
||||
Anonymous namespaces are converted to their magic string. */
|
||||
|
||||
static const char *
|
||||
dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
|
||||
|
@ -19262,6 +19268,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
|
|||
|
||||
attr = dwarf2_attr (die, DW_AT_name, cu);
|
||||
if ((!attr || !DW_STRING (attr))
|
||||
&& die->tag != DW_TAG_namespace
|
||||
&& die->tag != DW_TAG_class_type
|
||||
&& die->tag != DW_TAG_interface_type
|
||||
&& die->tag != DW_TAG_structure_type
|
||||
|
@ -19280,6 +19287,11 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
|
|||
to canonicalize them. */
|
||||
return DW_STRING (attr);
|
||||
|
||||
case DW_TAG_namespace:
|
||||
if (attr != NULL && DW_STRING (attr) != NULL)
|
||||
return DW_STRING (attr);
|
||||
return CP_ANONYMOUS_NAMESPACE_STR;
|
||||
|
||||
case DW_TAG_subprogram:
|
||||
/* Java constructors will all be named "<init>", so return
|
||||
the class name when we see this special case. */
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2015-02-21 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.cp/anon-ns.exp: Add test for ptype '(anonymous namespace)'.
|
||||
|
||||
2015-02-21 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR corefiles/17808
|
||||
|
|
|
@ -64,5 +64,9 @@ foreach test $methods {
|
|||
}
|
||||
}
|
||||
|
||||
# PR c++/17976
|
||||
gdb_test "ptype '(anonymous namespace)'" \
|
||||
"type = namespace \\\(anonymous namespace\\\)"
|
||||
|
||||
gdb_exit
|
||||
return 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue