aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2014-04-14 15:47:15 -0700
committerKeith Seitz <keiths@redhat.com>2014-04-14 15:47:15 -0700
commitb50c861487bb7d71185777193a9246bac81e4f26 (patch)
tree858f9f12feaafb9ca1aa0e467b9d1149b7f60e9b /gdb/symtab.c
parent3d567982aca11c85a7fa31f13046de3271d3afc8 (diff)
downloadgdb-b50c861487bb7d71185777193a9246bac81e4f26.zip
gdb-b50c861487bb7d71185777193a9246bac81e4f26.tar.gz
gdb-b50c861487bb7d71185777193a9246bac81e4f26.tar.bz2
Remove symbol_matches_domain. This fixes
PR c++/16253. symbol_matches_domain was permitting searches for a VAR_DOMAIN symbol to also match STRUCT_DOMAIN symbols for languages like C++ where STRUCT_DOMAIN symbols also define a typedef of the same name, e.g., "struct foo {}" introduces a typedef of the name "foo". Problems occur if there exists both a VAR_DOMAIN and STRUCT_DOMAIN symbol of the same name. Then it is essentially a race between which symbol is found first. The other symbol is obscurred. [This is a relatively common idiom: enum e { ... } e;] This patchset moves this "language defines a typedef" logic to lookup_symbol[_in_language], looking first for a symbol in the given domain and falling back to searching STRUCT_DOMAIN when/if appropriate. 2014-04-14 Keith Seitz <keiths@redhat.com> PR c++/16253 * ada-lang.c (ada_symbol_matches_domain): Moved here and renamed from symbol_matches_domain in symtab.c. All local callers of symbol_matches_domain updated. (standard_lookup): If DOMAIN is VAR_DOMAIN and no symbol is found, search STRUCT_DOMAIN. (ada_find_any_type_symbol): Do not search STRUCT_DOMAIN independently. standard_lookup will do that automatically. * cp-namespace.c (cp_lookup_symbol_nonlocal): Explain when/why VAR_DOMAIN searches may return a STRUCT_DOMAIN match. (cp_lookup_symbol_in_namespace): Likewise. If no VAR_DOMAIN symbol is found, search STRUCT_DOMAIN. (cp_lookup_symbol_exports): Explain when/why VAR_DOMAIN searches may return a STRUCT_DOMAIN match. (lookup_symbol_file): Search for the class name in STRUCT_DOMAIN. * cp-support.c: Include language.h. (inspect_type): Explicitly search STRUCT_DOMAIN before searching VAR_DOMAIN. * psymtab.c (match_partial_symbol): Compare the requested domain with the symbol's domain directly. (lookup_partial_symbol): Likewise. * symtab.c (lookup_symbol_in_language): Explain when/why VAR_DOMAIN searches may return a STRUCT_DOMAIN match. If no VAR_DOMAIN symbol is found, search STRUCT_DOMAIN for appropriate languages. (symbol_matches_domain): Renamed `ada_symbol_matches_domain' and moved to ada-lang.c (lookup_block_symbol): Explain that this function only returns symbol matching the requested DOMAIN. Compare the requested domain with the symbol's domain directly. (iterate_over_symbols): Compare the requested domain with the symbol's domain directly. * symtab.h (symbol_matches_domain): Remove. 2014-04-14 Keith Seitz <keiths@redhat.com> PR c++/16253 * gdb.cp/var-tag.cc: New file. * gdb.cp/var-tag.exp: New file. * gdb.dwarf2/dw2-ada-ffffffff.exp: Set the language to C++. * gdb.dwarf2/dw2-anon-mptr.exp: Likewise. * gdb.dwarf2/dw2-double-set-die-type.exp: Likewise. * gdb.dwarf2/dw2-inheritance.exp: Likewise.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 66d1624..15ac3d1 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1310,7 +1310,11 @@ demangle_for_lookup (const char *name, enum language lang,
NAME is a field of the current implied argument `this'. If so set
*IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
BLOCK_FOUND is set to the block in which NAME is found (in the case of
- a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
+ a field of `this', value_of_this sets BLOCK_FOUND to the proper value.)
+
+ If DOMAIN is VAR_DOMAIN and the language permits using tag names for
+ elaborated types, such as classes in C++, this function will search
+ STRUCT_DOMAIN if no matching is found. */
/* This function (or rather its subordinates) have a bunch of loops and
it would seem to be attractive to put in some QUIT's (though I'm not really
@@ -1333,6 +1337,23 @@ lookup_symbol_in_language (const char *name, const struct block *block,
returnval = lookup_symbol_aux (modified_name, block, domain, lang,
is_a_field_of_this);
+ if (returnval == NULL)
+ {
+ if (is_a_field_of_this != NULL
+ && is_a_field_of_this->type != NULL)
+ return NULL;
+
+ /* Some languages define typedefs of a type equal to its tag name,
+ e.g., in C++, "struct foo { ... }" also defines a typedef for
+ "foo". */
+ if (domain == VAR_DOMAIN
+ && (lang == language_cplus || lang == language_java
+ || lang == language_ada || lang == language_d))
+ {
+ returnval = lookup_symbol_aux (modified_name, block, STRUCT_DOMAIN,
+ lang, is_a_field_of_this);
+ }
+ }
do_cleanups (cleanup);
return returnval;
@@ -1907,27 +1928,6 @@ lookup_symbol_global (const char *name,
return lookup_data.result;
}
-int
-symbol_matches_domain (enum language symbol_language,
- domain_enum symbol_domain,
- domain_enum domain)
-{
- /* For C++ "struct foo { ... }" also defines a typedef for "foo".
- A Java class declaration also defines a typedef for the class.
- Similarly, any Ada type declaration implicitly defines a typedef. */
- if (symbol_language == language_cplus
- || symbol_language == language_d
- || symbol_language == language_java
- || symbol_language == language_ada)
- {
- if ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN)
- && symbol_domain == STRUCT_DOMAIN)
- return 1;
- }
- /* For all other languages, strict match is required. */
- return (symbol_domain == domain);
-}
-
/* Look up a type named NAME in the struct_domain. The type returned
must not be opaque -- i.e., must have at least one field
defined. */
@@ -2050,7 +2050,12 @@ basic_lookup_transparent_type (const char *name)
binary search terminates, we drop through and do a straight linear
search on the symbols. Each symbol which is marked as being a ObjC/C++
symbol (language_cplus or language_objc set) has both the encoded and
- non-encoded names tested for a match. */
+ non-encoded names tested for a match.
+
+ This function specifically disallows domain mismatches. If a language
+ defines a typedef for an elaborated type, such as classes in C++,
+ then this function will need to be called twice, once to search
+ VAR_DOMAIN and once to search STRUCT_DOMAIN. */
struct symbol *
lookup_block_symbol (const struct block *block, const char *name,
@@ -2065,8 +2070,7 @@ lookup_block_symbol (const struct block *block, const char *name,
sym != NULL;
sym = block_iter_name_next (name, &iter))
{
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), domain))
+ if (SYMBOL_DOMAIN (sym) == domain)
return sym;
}
return NULL;
@@ -2085,8 +2089,7 @@ lookup_block_symbol (const struct block *block, const char *name,
sym != NULL;
sym = block_iter_name_next (name, &iter))
{
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), domain))
+ if (SYMBOL_DOMAIN (sym) == domain)
{
sym_found = sym;
if (!SYMBOL_IS_ARGUMENT (sym))
@@ -2120,8 +2123,7 @@ iterate_over_symbols (const struct block *block, const char *name,
sym != NULL;
sym = block_iter_name_next (name, &iter))
{
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), domain))
+ if (SYMBOL_DOMAIN (sym) == domain)
{
if (!callback (sym, data))
return;