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.
This commit is contained in:
parent
3d567982ac
commit
b50c861487
14 changed files with 339 additions and 66 deletions
|
@ -1,3 +1,39 @@
|
|||
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 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR c++/15246:
|
||||
|
|
|
@ -4391,6 +4391,20 @@ ada_clear_symbol_cache (void)
|
|||
ada_init_symbol_cache (sym_cache);
|
||||
}
|
||||
|
||||
/* STRUCT_DOMAIN symbols are also typedefs for the type. This function tests
|
||||
the equivalency of two Ada symbol domain types. */
|
||||
|
||||
static int
|
||||
ada_symbol_matches_domain (domain_enum symbol_domain, domain_enum domain)
|
||||
{
|
||||
if (symbol_domain == domain
|
||||
|| ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN)
|
||||
&& symbol_domain == STRUCT_DOMAIN))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search our cache for an entry matching NAME and NAMESPACE.
|
||||
Return it if found, or NULL otherwise. */
|
||||
|
||||
|
@ -4492,6 +4506,13 @@ standard_lookup (const char *name, const struct block *block,
|
|||
if (lookup_cached_symbol (name, domain, &sym, NULL))
|
||||
return sym;
|
||||
sym = lookup_symbol_in_language (name, block, domain, language_c, 0);
|
||||
|
||||
/* STRUCT_DOMAIN symbols also define a typedef for the type. Lookup
|
||||
a STRUCT_DOMAIN symbol if one is requested for VAR_DOMAIN and not
|
||||
found. */
|
||||
if (sym == NULL && domain == VAR_DOMAIN)
|
||||
sym = lookup_symbol_in_language (name, block, STRUCT_DOMAIN, language_c, 0);
|
||||
|
||||
cache_symbol (name, domain, sym, block_found);
|
||||
return sym;
|
||||
}
|
||||
|
@ -5317,13 +5338,29 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
|
|||
data.objfile = objfile;
|
||||
|
||||
if (is_wild_match)
|
||||
objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
|
||||
aux_add_nonlocal_symbols, &data,
|
||||
wild_match, NULL);
|
||||
{
|
||||
objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
|
||||
aux_add_nonlocal_symbols,
|
||||
&data, wild_match, NULL);
|
||||
if (domain == VAR_DOMAIN)
|
||||
objfile->sf->qf->map_matching_symbols (objfile, name,
|
||||
STRUCT_DOMAIN, global,
|
||||
aux_add_nonlocal_symbols,
|
||||
&data, wild_match, NULL);
|
||||
}
|
||||
else
|
||||
objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
|
||||
aux_add_nonlocal_symbols, &data,
|
||||
full_match, compare_names);
|
||||
{
|
||||
objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
|
||||
aux_add_nonlocal_symbols,
|
||||
&data, full_match,
|
||||
compare_names);
|
||||
if (domain == VAR_DOMAIN)
|
||||
objfile->sf->qf->map_matching_symbols (objfile, name,
|
||||
STRUCT_DOMAIN, global,
|
||||
aux_add_nonlocal_symbols,
|
||||
&data, full_match,
|
||||
compare_names);
|
||||
}
|
||||
}
|
||||
|
||||
if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
|
||||
|
@ -5847,8 +5884,7 @@ ada_add_block_symbols (struct obstack *obstackp,
|
|||
for (sym = block_iter_match_first (block, name, wild_match, &iter);
|
||||
sym != NULL; sym = block_iter_match_next (name, wild_match, &iter))
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||
SYMBOL_DOMAIN (sym), domain)
|
||||
if (ada_symbol_matches_domain (SYMBOL_DOMAIN (sym), domain)
|
||||
&& wild_match (SYMBOL_LINKAGE_NAME (sym), name) == 0)
|
||||
{
|
||||
if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED)
|
||||
|
@ -5870,8 +5906,7 @@ ada_add_block_symbols (struct obstack *obstackp,
|
|||
for (sym = block_iter_match_first (block, name, full_match, &iter);
|
||||
sym != NULL; sym = block_iter_match_next (name, full_match, &iter))
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||
SYMBOL_DOMAIN (sym), domain))
|
||||
if (ada_symbol_matches_domain (SYMBOL_DOMAIN (sym), domain))
|
||||
{
|
||||
if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
|
||||
{
|
||||
|
@ -5903,8 +5938,7 @@ ada_add_block_symbols (struct obstack *obstackp,
|
|||
|
||||
ALL_BLOCK_SYMBOLS (block, iter, sym)
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||
SYMBOL_DOMAIN (sym), domain))
|
||||
if (ada_symbol_matches_domain (SYMBOL_DOMAIN (sym), domain))
|
||||
{
|
||||
int cmp;
|
||||
|
||||
|
@ -7488,11 +7522,12 @@ ada_find_any_type_symbol (const char *name)
|
|||
struct symbol *sym;
|
||||
|
||||
sym = standard_lookup (name, get_selected_block (NULL), VAR_DOMAIN);
|
||||
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|
||||
if (sym != NULL
|
||||
&& (SYMBOL_DOMAIN (sym) != VAR_DOMAIN
|
||||
|| SYMBOL_CLASS (sym) == LOC_TYPEDEF))
|
||||
return sym;
|
||||
|
||||
sym = standard_lookup (name, NULL, STRUCT_DOMAIN);
|
||||
return sym;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find a type named NAME. Ignores ambiguity. This routine will look
|
||||
|
|
|
@ -221,7 +221,12 @@ cp_is_anonymous (const char *namespace)
|
|||
we're looking for, BLOCK is the block that we're searching within,
|
||||
DOMAIN says what kind of symbols we're looking for, and if SYMTAB
|
||||
is non-NULL, we should store the symtab where we found the symbol
|
||||
in it. */
|
||||
in it.
|
||||
|
||||
Class, union, and enum tag names may be used in C++ without specifying
|
||||
class-key or enum. If searching for a VAR_DOMAIN symbol fails,
|
||||
this function will search STRUCT_DOMAIN. [This is actually done in
|
||||
cp_lookup_symbol_in_namespace.] */
|
||||
|
||||
struct symbol *
|
||||
cp_lookup_symbol_nonlocal (const char *name,
|
||||
|
@ -242,7 +247,10 @@ cp_lookup_symbol_nonlocal (const char *name,
|
|||
|
||||
/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are
|
||||
as in cp_lookup_symbol_nonlocal. If SEARCH is non-zero, search
|
||||
through base classes for a matching symbol. */
|
||||
through base classes for a matching symbol.
|
||||
|
||||
If DOMAIN is VAR_DOMAIN and no matching symbol exists in that domain,
|
||||
this function will search STRUCT_DOMAIN for a match. */
|
||||
|
||||
static struct symbol *
|
||||
cp_lookup_symbol_in_namespace (const char *namespace,
|
||||
|
@ -252,18 +260,30 @@ cp_lookup_symbol_in_namespace (const char *namespace,
|
|||
{
|
||||
if (namespace[0] == '\0')
|
||||
{
|
||||
return lookup_symbol_file (name, block, domain, 0, search);
|
||||
struct symbol *sym = lookup_symbol_file (name, block, domain, 0, search);
|
||||
|
||||
if (sym == NULL && domain == VAR_DOMAIN)
|
||||
sym = lookup_symbol_file (name, block, STRUCT_DOMAIN, 0, search);
|
||||
|
||||
return sym;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct symbol *sym;
|
||||
char *concatenated_name = alloca (strlen (namespace) + 2
|
||||
+ strlen (name) + 1);
|
||||
|
||||
strcpy (concatenated_name, namespace);
|
||||
strcat (concatenated_name, "::");
|
||||
strcat (concatenated_name, name);
|
||||
return lookup_symbol_file (concatenated_name, block, domain,
|
||||
cp_is_anonymous (namespace), search);
|
||||
sym = lookup_symbol_file (concatenated_name, block, domain,
|
||||
cp_is_anonymous (namespace), search);
|
||||
|
||||
if (sym == NULL && domain == VAR_DOMAIN)
|
||||
sym = lookup_symbol_file (concatenated_name, block, STRUCT_DOMAIN,
|
||||
cp_is_anonymous (namespace), search);
|
||||
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,7 +536,12 @@ cp_lookup_symbol_imports_or_template (const char *scope,
|
|||
/* Searches for NAME in the current namespace, and by applying
|
||||
relevant import statements belonging to BLOCK and its parents.
|
||||
SCOPE is the namespace scope of the context in which the search is
|
||||
being evaluated. */
|
||||
being evaluated.
|
||||
|
||||
Class, union, and enum tag names may be used in C++ without specifying
|
||||
class-key or enum. If searching for a VAR_DOMAIN symbol fails,
|
||||
this function will search STRUCT_DOMAIN. [This is done in
|
||||
cp_lookup_symbol_in_namespace.] */
|
||||
|
||||
struct symbol*
|
||||
cp_lookup_symbol_namespace (const char *scope,
|
||||
|
@ -688,7 +713,7 @@ lookup_symbol_file (const char *name,
|
|||
|
||||
/* 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);
|
||||
klass_sym = lookup_symbol_global (klass, block, STRUCT_DOMAIN);
|
||||
if (klass_sym == NULL)
|
||||
{
|
||||
do_cleanups (cleanup);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "expression.h"
|
||||
#include "value.h"
|
||||
#include "cp-abi.h"
|
||||
#include "language.h"
|
||||
|
||||
#include "safe-ctype.h"
|
||||
|
||||
|
@ -177,7 +178,29 @@ inspect_type (struct demangle_parse_info *info,
|
|||
sym = NULL;
|
||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
|
||||
/* It is not legal to have a typedef and tag name of the same
|
||||
name in C++. However, anonymous composite types that are defined
|
||||
with a typedef ["typedef struct {...} anonymous_struct;"] WILL
|
||||
have symbols for a TYPE_CODE_TYPEDEF (in VAR_DOMAIN) and a
|
||||
TYPE_CODE_STRUCT (in STRUCT_DOMAIN).
|
||||
|
||||
If VAR_DOMAIN is searched first, it will return the TYPEDEF symbol,
|
||||
and this function will never output the definition of the typedef,
|
||||
since type_print is called below with SHOW = -1. [The typedef hash
|
||||
is never initialized/used when SHOW <= 0 -- and the finder
|
||||
(find_typedef_for_canonicalize) will always return NULL as a result.]
|
||||
|
||||
Consequently, type_print will eventually keep calling this function
|
||||
to replace the typedef (via
|
||||
print_name_maybe_canonical/cp_canonicalize_full). This leads to
|
||||
infinite recursion.
|
||||
|
||||
This can all be safely avoid by explicitly searching STRUCT_DOMAIN
|
||||
first to find the structure definition. */
|
||||
if (current_language->la_language == language_cplus)
|
||||
sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
|
||||
if (sym == NULL)
|
||||
sym = lookup_symbol (name, 0, VAR_DOMAIN, NULL);
|
||||
}
|
||||
|
||||
if (except.reason >= 0 && sym != NULL)
|
||||
|
|
|
@ -594,8 +594,7 @@ match_partial_symbol (struct objfile *objfile,
|
|||
while (top <= real_top
|
||||
&& match (SYMBOL_SEARCH_NAME (*top), name) == 0)
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
|
||||
SYMBOL_DOMAIN (*top), domain))
|
||||
if (SYMBOL_DOMAIN (*top) == domain)
|
||||
return *top;
|
||||
top++;
|
||||
}
|
||||
|
@ -608,8 +607,7 @@ match_partial_symbol (struct objfile *objfile,
|
|||
{
|
||||
for (psym = start; psym < start + length; psym++)
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
|
||||
SYMBOL_DOMAIN (*psym), domain)
|
||||
if (SYMBOL_DOMAIN (*psym) == domain
|
||||
&& match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
|
||||
return *psym;
|
||||
}
|
||||
|
@ -725,8 +723,7 @@ lookup_partial_symbol (struct objfile *objfile,
|
|||
|
||||
while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
|
||||
SYMBOL_DOMAIN (*top), domain))
|
||||
if (SYMBOL_DOMAIN (*top) == domain)
|
||||
{
|
||||
do_cleanups (cleanup);
|
||||
return (*top);
|
||||
|
@ -742,8 +739,7 @@ lookup_partial_symbol (struct objfile *objfile,
|
|||
{
|
||||
for (psym = start; psym < start + length; psym++)
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
|
||||
SYMBOL_DOMAIN (*psym), domain)
|
||||
if (SYMBOL_DOMAIN (*psym) == domain
|
||||
&& SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
|
||||
{
|
||||
do_cleanups (cleanup);
|
||||
|
@ -1223,8 +1219,7 @@ map_block (const char *name, domain_enum namespace, struct objfile *objfile,
|
|||
for (sym = block_iter_match_first (block, name, match, &iter);
|
||||
sym != NULL; sym = block_iter_match_next (name, match, &iter))
|
||||
{
|
||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||
SYMBOL_DOMAIN (sym), namespace))
|
||||
if (SYMBOL_DOMAIN (sym) == namespace)
|
||||
{
|
||||
if (callback (block, sym, data))
|
||||
return 1;
|
||||
|
|
60
gdb/symtab.c
60
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;
|
||||
|
|
|
@ -1019,10 +1019,6 @@ extern const char multiple_symbols_cancel[];
|
|||
|
||||
const char *multiple_symbols_select_mode (void);
|
||||
|
||||
int symbol_matches_domain (enum language symbol_language,
|
||||
domain_enum symbol_domain,
|
||||
domain_enum domain);
|
||||
|
||||
/* lookup a symbol table by source file name. */
|
||||
|
||||
extern struct symtab *lookup_symtab (const char *);
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
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.
|
||||
|
||||
2014-04-14 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.cp/classes.exp (test_enums): Handle underlying type.
|
||||
|
|
44
gdb/testsuite/gdb.cp/var-tag.cc
Normal file
44
gdb/testsuite/gdb.cp/var-tag.cc
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
int global = 3;
|
||||
|
||||
class C {
|
||||
public:
|
||||
struct C1 {} C1;
|
||||
enum E1 {a1, b1, c1} E1;
|
||||
union U1 {int a1; char b1;} U1;
|
||||
|
||||
C () : E1 (b1) {}
|
||||
void global (void) const {}
|
||||
int f (void) const { global (); return 0; }
|
||||
} C;
|
||||
|
||||
struct S {} S;
|
||||
enum E {a, b, c} E;
|
||||
union U {int a; char b;} U;
|
||||
|
||||
class CC {} cc;
|
||||
struct SS {} ss;
|
||||
enum EE {ea, eb, ec} ee;
|
||||
union UU {int aa; char bb;} uu;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return C.f ();
|
||||
}
|
99
gdb/testsuite/gdb.cp/var-tag.exp
Normal file
99
gdb/testsuite/gdb.cp/var-tag.exp
Normal file
|
@ -0,0 +1,99 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file is part of the gdb testsuite
|
||||
|
||||
# Test expressions in which variable names shadow tag names.
|
||||
|
||||
if {[skip_cplus_tests]} { continue }
|
||||
|
||||
standard_testfile .cc
|
||||
|
||||
if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
proc do_global_tests {lang} {
|
||||
if {$lang == "c"} {
|
||||
set invalid_print "No symbol \"%s\" in current context."
|
||||
set ptypefmt $invalid_print
|
||||
} else {
|
||||
set invalid_print "Attempt to use a type name as an expression"
|
||||
set ptypefmt "type = (class|enum|union|struct) %s {.*}"
|
||||
}
|
||||
|
||||
with_test_prefix $lang {
|
||||
gdb_test_no_output "set language $lang"
|
||||
gdb_test "ptype C" "type = class C {.*}"
|
||||
gdb_test "print E" "= a"
|
||||
gdb_test "ptype E" "type = enum E {.*}"
|
||||
gdb_test "print S" "= {<No data fields>}"
|
||||
gdb_test "ptype S" "type = struct S {.*}"
|
||||
gdb_test "print U" "= {.*}"
|
||||
gdb_test "ptype U" "type = union U {.*}"
|
||||
gdb_test "print cc" "= {.*}"
|
||||
gdb_test "ptype cc" "type = class CC {.*}"
|
||||
gdb_test "print CC" [format $invalid_print "CC"]
|
||||
gdb_test "ptype CC" [format $ptypefmt "CC"]
|
||||
gdb_test "print ss" "= {<No data fields>}"
|
||||
gdb_test "ptype ss" "type = struct SS {.*}"
|
||||
gdb_test "print SS" [format $invalid_print "SS"]
|
||||
gdb_test "ptype SS" [format $ptypefmt "SS"]
|
||||
gdb_test "print ee" "= .*"
|
||||
gdb_test "ptype ee" "type = enum EE {.*}"
|
||||
gdb_test "print EE" [format $invalid_print "EE"]
|
||||
gdb_test "ptype EE" [format $ptypefmt "EE"]
|
||||
gdb_test "print uu" "= {.*}"
|
||||
gdb_test "ptype uu" "type = union UU {.*}"
|
||||
gdb_test "print UU" [format $invalid_print "UU"]
|
||||
gdb_test "ptype UU" [format $ptypefmt "UU"]
|
||||
}
|
||||
}
|
||||
|
||||
# First test expressions when there is no context.
|
||||
with_test_prefix "before start" {
|
||||
do_global_tests c++
|
||||
do_global_tests c
|
||||
}
|
||||
|
||||
# Run to main and test again.
|
||||
if {![runto_main]} {
|
||||
perror "couldn't run to main"
|
||||
continue
|
||||
}
|
||||
|
||||
with_test_prefix "in main" {
|
||||
do_global_tests c++
|
||||
do_global_tests c
|
||||
}
|
||||
|
||||
# Finally run to C::f and test again
|
||||
gdb_breakpoint "C::f"
|
||||
gdb_continue_to_breakpoint "continue to C::f"
|
||||
with_test_prefix "in C::f" {
|
||||
do_global_tests c++
|
||||
do_global_tests c
|
||||
}
|
||||
|
||||
# Another hard-to-guess-the-users-intent bug...
|
||||
# It would be really nice if we could query the user!
|
||||
with_test_prefix "global collision" {
|
||||
gdb_test_no_output "set language c++"
|
||||
setup_kfail "c++/16463" "*-*-*"
|
||||
gdb_test "print global" "= 3"
|
||||
|
||||
# ... with a simple workaround:
|
||||
gdb_test "print ::global" "= 3"
|
||||
}
|
|
@ -28,6 +28,10 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != ""
|
|||
|
||||
clean_restart $executable
|
||||
|
||||
# Force the language to C++, since we want to treat the type
|
||||
# defined in the object file like a C++ type, using sizeof.
|
||||
gdb_test_no_output "set language c++"
|
||||
|
||||
# -1 was produced, it is now caught with the complaint:
|
||||
# Suspicious DW_AT_byte_size value treated as zero instead of ...
|
||||
gdb_test "p sizeof (t)" " = 0"
|
||||
|
|
|
@ -40,5 +40,7 @@ gdb_test "show cp-abi" {The currently selected C\+\+ ABI is "gnu-v3".*}
|
|||
|
||||
gdb_load $binfile
|
||||
|
||||
gdb_test_no_output "set language c++"
|
||||
|
||||
gdb_test "ptype crash" \
|
||||
"type = class crash {\[\r\n \t\]*public:\[\r\n \t\]*crash\\(int \\(class {\\.\\.\\.}::\\*\\)\\(class {\\.\\.\\.} \\* const\\)\\);\[\r\n \t\]*}"
|
||||
|
|
|
@ -30,4 +30,5 @@ if { [gdb_compile [file join $srcdir $subdir $srcfile] $binfile \
|
|||
}
|
||||
|
||||
clean_restart $testfile
|
||||
gdb_test_no_output "set language c++"
|
||||
gdb_test "ptype a" "type = class .*"
|
||||
|
|
|
@ -31,4 +31,5 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" $binfile \
|
|||
|
||||
clean_restart $testfile
|
||||
|
||||
gdb_test_no_output "set language c++"
|
||||
gdb_test "ptype inherited" "type = class inherited .*"
|
||||
|
|
Loading…
Reference in a new issue