PR c++/13615

* cp-namespace.c (cp_lookup_symbol_in_namespace): Add SEARCH
	parameter and pass it to lookup_symbol_file.
	(cp_lookup_symbol_imports): Tell cp_lookup_symbol_in_namespace
	to search base classes.
	(cp_lookup_symbol_namespace): Likewise.
	(lookup_namespace_scope): Likewise.
	(lookup_symbol_file): Add SEARCH parameter.
	If SEARCH is non-zero and no symbol is found, lookup the class
	and call cp_lookup_nested_symbol.
	(find_symbol_in_baseclass): New function.
	(cp_lookup_nested_symbol): Do not let
	cp_lookup_symbol_in_namespace search through base classes.
	Do that later when there is no global symbol match.

	PR c++/13615
	* gdb.cp/baseenum.cc: New file.
	* gdb.cp/baseenum.exp: New file.
	* gdb.cp/derivation.cc (A): Add copyright.
	Add a typedef.
	(B): Use A::value_type instead of int.  Change all references.
	(D): Use value_type instead of int.  Change all references.
	(E): Likewise.
	(F); Likewise.
	(Z): New class.
	(ZZ): New class.
 	(N, Base, Derived): New namespace and classes.
	(main): Add instances of Z and ZZ.
	Make sure all symbols from N are kept.
	* gdb.cp/derivation.exp: Update typedef changes in tests.
	Add tests for class typedefs both before and after starting
	the inferior.
	Add tests for searching for a typedef while stopped in a
	method.
This commit is contained in:
Keith Seitz 2012-11-16 20:54:30 +00:00
parent e64e03922c
commit 8dea366bbe
7 changed files with 456 additions and 68 deletions

View file

@ -42,7 +42,8 @@ static struct symbol *lookup_namespace_scope (const char *name,
static struct symbol *lookup_symbol_file (const char *name,
const struct block *block,
const domain_enum domain,
int anonymous_namespace);
int anonymous_namespace,
int search);
static struct type *cp_lookup_transparent_type_loop (const char *name,
const char *scope,
@ -264,17 +265,18 @@ cp_lookup_symbol_nonlocal (const char *name,
}
/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are
as in cp_lookup_symbol_nonlocal. */
as in cp_lookup_symbol_nonlocal. If SEARCH is non-zero, search
through base classes for a matching symbol. */
static struct symbol *
cp_lookup_symbol_in_namespace (const char *namespace,
const char *name,
const struct block *block,
const domain_enum domain)
const domain_enum domain, int search)
{
if (namespace[0] == '\0')
{
return lookup_symbol_file (name, block, domain, 0);
return lookup_symbol_file (name, block, domain, 0, search);
}
else
{
@ -285,7 +287,7 @@ cp_lookup_symbol_in_namespace (const char *namespace,
strcat (concatenated_name, "::");
strcat (concatenated_name, name);
return lookup_symbol_file (concatenated_name, block, domain,
cp_is_anonymous (namespace));
cp_is_anonymous (namespace), search);
}
}
@ -341,7 +343,7 @@ cp_lookup_symbol_imports (const char *scope,
/* First, try to find the symbol in the given namespace. */
if (!declaration_only)
sym = cp_lookup_symbol_in_namespace (scope, name,
block, domain);
block, domain, 1);
if (sym != NULL)
return sym;
@ -385,7 +387,7 @@ cp_lookup_symbol_imports (const char *scope,
? current->alias : current->declaration) == 0)
sym = cp_lookup_symbol_in_namespace (current->import_src,
current->declaration,
block, domain);
block, domain, 1);
/* If this is a DECLARATION_ONLY search or a symbol was found
or this import statement was an import declaration, the
@ -419,7 +421,7 @@ cp_lookup_symbol_imports (const char *scope,
{
sym = cp_lookup_symbol_in_namespace (scope,
current->import_src,
block, domain);
block, domain, 1);
}
else if (current->alias == NULL)
{
@ -550,7 +552,7 @@ cp_lookup_symbol_namespace (const char *scope,
/* First, try to find the symbol in the given namespace. */
sym = cp_lookup_symbol_in_namespace (scope, name,
block, domain);
block, domain, 1);
if (sym != NULL)
return sym;
@ -621,19 +623,20 @@ lookup_namespace_scope (const char *name,
strncpy (namespace, scope, scope_len);
namespace[scope_len] = '\0';
return cp_lookup_symbol_in_namespace (namespace, name,
block, domain);
block, domain, 1);
}
/* Look up NAME in BLOCK's static block and in global blocks. If
ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located
within an anonymous namespace. Other arguments are as in
within an anonymous namespace. If SEARCH is non-zero, search through
base classes for a matching symbol. Other arguments are as in
cp_lookup_symbol_nonlocal. */
static struct symbol *
lookup_symbol_file (const char *name,
const struct block *block,
const domain_enum domain,
int anonymous_namespace)
int anonymous_namespace, int search)
{
struct symbol *sym = NULL;
@ -657,6 +660,127 @@ lookup_symbol_file (const char *name,
sym = lookup_symbol_global (name, block, domain);
}
if (sym != NULL)
return sym;
if (search)
{
char *klass, *nested;
unsigned int prefix_len;
struct cleanup *cleanup;
struct symbol *klass_sym;
/* A simple lookup failed. Check if the symbol was defined in
a base class. */
cleanup = make_cleanup (null_cleanup, NULL);
/* Find the name of the class and the name of the method,
variable, etc. */
prefix_len = cp_entire_prefix_len (name);
/* If no prefix was found, search "this". */
if (prefix_len == 0)
{
struct type *type;
struct symbol *this;
this = lookup_language_this (language_def (language_cplus), block);
if (this == NULL)
{
do_cleanups (cleanup);
return NULL;
}
type = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (this)));
klass = xstrdup (TYPE_NAME (type));
nested = xstrdup (name);
}
else
{
/* The class name is everything up to and including PREFIX_LEN. */
klass = savestring (name, prefix_len);
/* The rest of the name is everything else past the initial scope
operator. */
nested = xstrdup (name + prefix_len + 2);
}
/* Add cleanups to free memory for these strings. */
make_cleanup (xfree, klass);
make_cleanup (xfree, nested);
/* Lookup a class named KLASS. If none is found, there is nothing
more that can be done. */
klass_sym = lookup_symbol_global (klass, block, domain);
if (klass_sym == NULL)
{
do_cleanups (cleanup);
return NULL;
}
/* Look for a symbol named NESTED in this class. */
sym = cp_lookup_nested_symbol (SYMBOL_TYPE (klass_sym), nested, block);
do_cleanups (cleanup);
}
return sym;
}
/* Search through the base classes of PARENT_TYPE for a symbol named
NAME in block BLOCK. */
static struct symbol *
find_symbol_in_baseclass (struct type *parent_type, const char *name,
const struct block *block)
{
int i;
struct symbol *sym;
struct cleanup *cleanup;
char *concatenated_name;
sym = NULL;
concatenated_name = NULL;
cleanup = make_cleanup (free_current_contents, &concatenated_name);
for (i = 0; i < TYPE_N_BASECLASSES (parent_type); ++i)
{
size_t len;
const char *base_name = TYPE_BASECLASS_NAME (parent_type, i);
if (base_name == NULL)
continue;
/* Search this particular base class. */
sym = cp_lookup_symbol_namespace (base_name, name, block, VAR_DOMAIN);
if (sym != NULL)
break;
len = strlen (base_name) + 2 + strlen (name) + 1;
concatenated_name = xrealloc (concatenated_name, len);
xsnprintf (concatenated_name, len, "%s::%s", base_name, name);
sym = lookup_symbol_static (concatenated_name, block, VAR_DOMAIN);
/* If there is currently no BLOCK, e.g., the inferior hasn't yet
been started, then try searching all STATIC_BLOCK symbols in
all objfiles. */
if (block == NULL)
{
sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
if (sym != NULL)
break;
}
/* If this class has base classes, search them next. */
if (TYPE_N_BASECLASSES (TYPE_BASECLASS (parent_type, i)) > 0)
{
sym = find_symbol_in_baseclass (TYPE_BASECLASS (parent_type, i),
name, block);
if (sym != NULL)
break;
}
}
do_cleanups (cleanup);
return sym;
}
@ -692,7 +816,7 @@ cp_lookup_nested_symbol (struct type *parent_type,
const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
struct symbol *sym
= cp_lookup_symbol_in_namespace (parent_name, nested_name,
block, VAR_DOMAIN);
block, VAR_DOMAIN, 0);
char *concatenated_name;
if (sym != NULL)
@ -701,7 +825,7 @@ cp_lookup_nested_symbol (struct type *parent_type,
/* Now search all static file-level symbols. Not strictly
correct, but more useful than an error. We do not try to
guess any imported namespace as even the fully specified
namespace seach is is already not C++ compliant and more
namespace search is already not C++ compliant and more
assumptions could make it too magic. */
size = strlen (parent_name) + 2 + strlen (nested_name) + 1;
@ -712,7 +836,9 @@ cp_lookup_nested_symbol (struct type *parent_type,
if (sym != NULL)
return sym;
return NULL;
/* If no matching symbols were found, try searching any
base classes. */
return find_symbol_in_baseclass (parent_type, nested_name, block);
}
default:
internal_error (__FILE__, __LINE__,