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:
Keith Seitz 2014-04-14 15:47:15 -07:00
parent 3d567982ac
commit b50c861487
14 changed files with 339 additions and 66 deletions

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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 *);

View File

@ -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.

View 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 ();
}

View 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"
}

View File

@ -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"

View File

@ -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\]*}"

View File

@ -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 .*"

View File

@ -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 .*"