@@ -15694,7 +15694,10 @@ Explicit locations are similar to linespecs but use an option/argument\n\
syntax to specify location parameters.\n\
Example: To specify the start of the label named \"the_top\" in the\n\
function \"fact\" in the file \"factorial.c\", use \"-source factorial.c\n\
--function fact -label the_top\".\n"
+-function fact -label the_top\".\n\
+For C++, \"-function\" matches all functions with the given name ignoring\n\
+missing leading specifiers (namespaces and classes). You can override\n\
+that by instead specifying a fully qualified name using \"-qualified\".\n"
/* This help string is used for the break, hbreak, tbreak and thbreak
commands. It is defined as a macro to prevent duplication.
@@ -1016,7 +1016,7 @@ extern const struct language_defn cplus_language_defn =
c_watch_location_expression,
cp_get_symbol_name_matcher,
iterate_over_symbols,
- default_search_name_hash,
+ cp_search_name_hash,
&cplus_varobj_ops,
NULL,
NULL,
@@ -76,6 +76,9 @@ enum explicit_location_match_type
/* The name of a function or method. */
MATCH_FUNCTION,
+ /* The fully-qualified name of a function or method. */
+ MATCH_QUALIFIED,
+
/* A line number. */
MATCH_LINE,
@@ -609,6 +612,7 @@ static const char *const explicit_options[] =
{
"-source",
"-function",
+ "-qualified",
"-line",
"-label",
NULL
@@ -660,9 +664,11 @@ collect_explicit_location_matches (completion_tracker &tracker,
break;
case MATCH_FUNCTION:
+ case MATCH_QUALIFIED:
{
const char *function = string_or_empty (explicit_loc->function_name);
linespec_complete_function (tracker, function,
+ explicit_loc->func_name_match_type,
explicit_loc->source_filename);
}
break;
@@ -677,6 +683,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
linespec_complete_label (tracker, language,
explicit_loc->source_filename,
explicit_loc->function_name,
+ explicit_loc->func_name_match_type,
label);
}
break;
@@ -1642,7 +1642,96 @@ gdb_sniff_from_mangled_name (const char *mangled, char **demangled)
return *demangled != NULL;
}
-/* C++ symbol_name_matcher_ftype implementation. */
+/* Produce an unsigned hash value from SEARCH_NAME that is compatible
+ with cp_symbol_name_matches. Only the last component in
+ "foo::bar::function()" is considered for hashing purposes (i.e.,
+ the entire prefix is skipped), so that later on looking up for
+ "function" or "bar::function" in all namespaces is possible. */
+
+unsigned int
+cp_search_name_hash (const char *search_name)
+{
+ /* cp_entire_prefix_len assumes a fully-qualified name with no
+ leading "::". */
+ if (startswith (search_name, "::"))
+ search_name += 2;
+
+ unsigned int prefix_len = cp_entire_prefix_len (search_name);
+ if (prefix_len != 0)
+ search_name += prefix_len + 2;
+
+ return default_search_name_hash (search_name);
+}
+
+/* Helper for cp_symbol_name_matches (i.e., symbol_name_matcher_ftype
+ implementation for symbol_name_match_type::WILD matching). Split
+ to a separate function for unit-testing convenience.
+
+ If SYMBOL_SEARCH_NAME has more scopes than LOOKUP_NAME, we try to
+ match ignoring the extra leading scopes of SYMBOL_SEARCH_NAME.
+ This allows conveniently setting breakpoints on functions/methods
+ inside any namespace/class without specifying the fully-qualified
+ name.
+
+ E.g., these match:
+
+ [symbol search name] [lookup name]
+ foo::bar::func foo::bar::func
+ foo::bar::func bar::func
+ foo::bar::func func
+
+ While these don't:
+
+ [symbol search name] [lookup name]
+ foo::zbar::func bar::func
+ foo::bar::func foo::func
+
+ See more examples in the test_cp_symbol_name_matches selftest
+ function below.
+
+ See symbol_name_matcher_ftype for description of SYMBOL_SEARCH_NAME
+ and COMP_MATCH_RES. .
+
+ LOOKUP_NAME/LOOKUP_NAME_LEN is the name we're looking up.
+
+ See strncmp_iw_with_mode for description of MODE.
+*/
+
+static bool
+cp_symbol_name_matches_1 (const char *symbol_search_name,
+ const char *lookup_name,
+ size_t lookup_name_len,
+ strncmp_iw_mode mode,
+ completion_match_result *comp_match_res)
+{
+ const char *sname = symbol_search_name;
+
+ while (true)
+ {
+ if (strncmp_iw_with_mode (sname, lookup_name, lookup_name_len,
+ mode) == 0)
+ {
+ if (comp_match_res != NULL)
+ {
+ comp_match_res->match.set_match (symbol_search_name);
+ comp_match_res->match_for_lcd.set_match (sname);
+ }
+ return true;
+ }
+
+ unsigned int len = cp_find_first_component (sname);
+
+ if (sname[len] == '\0')
+ return false;
+
+ gdb_assert (sname[len] == ':');
+ /* Skip the '::'. */
+ sname += len + 2;
+ }
+}
+
+/* C++ symbol_name_matcher_ftype implementation for fully qualified
+ matches. */
static bool
cp_fq_symbol_name_matches (const char *symbol_search_name,
@@ -1671,19 +1760,151 @@ cp_fq_symbol_name_matches (const char *symbol_search_name,
return false;
}
+/* C++ symbol_name_matcher_ftype implementation for wild matches.
+ Defers work to cp_symbol_name_ncmp. */
+
+static bool
+cp_symbol_name_matches (const char *symbol_search_name,
+ const lookup_name_info &lookup_name,
+ completion_match_result *comp_match_res)
+{
+ const std::string &name = lookup_name.cplus ().lookup_name ();
+
+ strncmp_iw_mode mode = (lookup_name.completion_mode ()
+ ? strncmp_iw_mode::NORMAL
+ : strncmp_iw_mode::MATCH_PARAMS);
+
+ return cp_symbol_name_matches_1 (symbol_search_name,
+ name.c_str (), name.size (),
+ mode, comp_match_res);
+}
+
/* Implement the "la_get_symbol_name_matcher" language_defn method for
C++. */
symbol_name_matcher_ftype *
cp_get_symbol_name_matcher (const lookup_name_info &lookup_name)
{
- return cp_fq_symbol_name_matches;
+ switch (lookup_name.match_type ())
+ {
+ case symbol_name_match_type::FULL:
+ case symbol_name_match_type::EXPRESSION:
+ return cp_fq_symbol_name_matches;
+ case symbol_name_match_type::WILD:
+ return cp_symbol_name_matches;
+ }
+
+ gdb_assert_not_reached ("");
}
#if GDB_SELF_TEST
namespace selftests {
+void
+test_cp_symbol_name_cmp ()
+{
+#define CHECK_MATCH(SYMBOL, INPUT) \
+ SELF_CHECK (cp_symbol_name_matches_1 (SYMBOL, \
+ INPUT, sizeof (INPUT) - 1, \
+ strncmp_iw_mode::MATCH_PARAMS, \
+ NULL))
+
+#define CHECK_NOT_MATCH(SYMBOL, INPUT) \
+ SELF_CHECK (!cp_symbol_name_matches_1 (SYMBOL, \
+ INPUT, sizeof (INPUT) - 1, \
+ strncmp_iw_mode::MATCH_PARAMS, \
+ NULL))
+
+ /* Like CHECK_MATCH, and also check that INPUT (and all substrings
+ that start at index 0) completes to SYMBOL. */
+#define CHECK_MATCH_C(SYMBOL, INPUT) \
+ CHECK_MATCH (SYMBOL, INPUT); \
+ for (size_t i = 0; i < sizeof (INPUT) - 1; i++) \
+ SELF_CHECK (cp_symbol_name_matches_1 (SYMBOL, INPUT, i, \
+ strncmp_iw_mode::NORMAL, \
+ NULL))
+
+ /* Like CHECK_NOT_MATCH, and also check that INPUT does NOT complete
+ to SYMBOL. */
+#define CHECK_NOT_MATCH_C(SYMBOL, INPUT) \
+ CHECK_NOT_MATCH (SYMBOL, INPUT); \
+ SELF_CHECK (!cp_symbol_name_matches_1 (SYMBOL, INPUT, \
+ sizeof (INPUT) - 1, \
+ strncmp_iw_mode::NORMAL, \
+ NULL))
+
+ /* Lookup name without parens matches all overloads. */
+ CHECK_MATCH_C ("function()", "function");
+ CHECK_MATCH_C ("function(int)", "function");
+
+ /* Check whitespace around parameters is ignored. */
+ CHECK_MATCH_C ("function()", "function ()");
+ CHECK_MATCH_C ("function ( )", "function()");
+ CHECK_MATCH_C ("function ()", "function( )");
+ CHECK_MATCH_C ("func(int)", "func( int )");
+ CHECK_MATCH_C ("func(int)", "func ( int ) ");
+ CHECK_MATCH_C ("func ( int )", "func( int )");
+ CHECK_MATCH_C ("func ( int )", "func ( int ) ");
+
+ /* Check symbol name prefixes aren't incorrectly matched. */
+ CHECK_NOT_MATCH ("func", "function");
+ CHECK_NOT_MATCH ("function", "func");
+ CHECK_NOT_MATCH ("function()", "func");
+
+ /* Check that if the lookup name includes parameters, only the right
+ overload matches. */
+ CHECK_MATCH_C ("function(int)", "function(int)");
+ CHECK_NOT_MATCH_C ("function(int)", "function()");
+
+ /* Tests matching symbols in some scope. */
+ CHECK_MATCH_C ("foo::function()", "function");
+ CHECK_MATCH_C ("foo::function(int)", "function");
+ CHECK_MATCH_C ("foo::bar::function()", "function");
+ CHECK_MATCH_C ("bar::function()", "bar::function");
+ CHECK_MATCH_C ("foo::bar::function()", "bar::function");
+ CHECK_MATCH_C ("foo::bar::function(int)", "bar::function");
+
+ /* Same, with parameters in the lookup name. */
+ CHECK_MATCH_C ("foo::function()", "function()");
+ CHECK_MATCH_C ("foo::bar::function()", "function()");
+ CHECK_MATCH_C ("foo::function(int)", "function(int)");
+ CHECK_MATCH_C ("foo::function()", "foo::function()");
+ CHECK_MATCH_C ("foo::bar::function()", "bar::function()");
+ CHECK_MATCH_C ("foo::bar::function(int)", "bar::function(int)");
+ CHECK_NOT_MATCH_C ("foo::bar::function(int)", "bar::function()");
+
+ CHECK_MATCH_C ("(anonymous namespace)::bar::function(int)",
+ "bar::function(int)");
+ CHECK_MATCH_C ("foo::(anonymous namespace)::bar::function(int)",
+ "function(int)");
+
+ /* Lookup scope wider than symbol scope, should not match. */
+ CHECK_NOT_MATCH_C ("function()", "bar::function");
+ CHECK_NOT_MATCH_C ("function()", "bar::function()");
+
+ /* An explicit global scope forces a fully qualified match. */
+ CHECK_NOT_MATCH_C ("foo::function()", "::function");
+ CHECK_NOT_MATCH_C ("foo::function()", "::function()");
+ CHECK_NOT_MATCH_C ("foo::function(int)", "::function()");
+ CHECK_NOT_MATCH_C ("foo::function(int)", "::function(int)");
+
+ CHECK_MATCH_C ("abc::def::ghi()", "abc::def::ghi()");
+ CHECK_MATCH_C ("abc::def::ghi ( )", "abc::def::ghi()");
+ CHECK_MATCH_C ("abc::def::ghi()", "abc::def::ghi ( )");
+ CHECK_MATCH_C ("function()", "function()");
+ CHECK_MATCH_C ("foo::function()", "function()");
+ CHECK_MATCH_C ("foo::bar::function()", "function()");
+ CHECK_MATCH_C ("bar::function()", "bar::function()");
+ CHECK_MATCH_C ("foo::bar::function()", "bar::function");
+ CHECK_MATCH_C ("(anonymous namespace)::bar::function(int)",
+ "function(int)");
+ CHECK_MATCH_C ("foo::(anonymous namespace)::bar::function(int)",
+ "function(int)");
+ CHECK_NOT_MATCH_C ("function()", "bar::function");
+ CHECK_NOT_MATCH_C ("foo::function()", "::function");
+}
+
/* If non-NULL, return STR wrapped in quotes. Otherwise, return a
"<null>" string (with no quotes). */
@@ -1890,6 +2111,7 @@ display the offending symbol."),
#endif
#if GDB_SELF_TEST
+ register_self_test (selftests::test_cp_symbol_name_cmp);
register_self_test (selftests::test_cp_remove_params);
#endif
}
@@ -110,6 +110,8 @@ extern struct symbol **make_symbol_overload_list_adl (struct type **arg_types,
extern struct type *cp_lookup_rtti_type (const char *name,
struct block *block);
+extern unsigned int cp_search_name_hash (const char *search_name);
+
extern symbol_name_matcher_ftype *cp_get_symbol_name_matcher
(const lookup_name_info &lookup_name);
@@ -4548,6 +4548,8 @@ static const char *test_symbols[] = {
"ns::foo<char*>",
"ns::foo<int>",
"ns::foo<long>",
+ "ns2::tmpl<int>::foo2",
+ "(anonymous namespace)::A::B::C",
/* A name with all sorts of complications. Starts with "z" to make
it easier for the completion tests below. */
@@ -4627,6 +4629,8 @@ run_test ()
{
CHECK_MATCH ("w", symbol_name_match_type::FULL, true,
EXPECT ("w1::w2"));
+ CHECK_MATCH ("w", symbol_name_match_type::WILD, true,
+ EXPECT ("w1::w2"));
}
/* Same, with a "complicated" symbol. */
@@ -4654,6 +4658,10 @@ run_test ()
{
CHECK_MATCH ("std::zfunction(int)", symbol_name_match_type::FULL, true,
EXPECT ("std::zfunction", "std::zfunction2"));
+ CHECK_MATCH ("zfunction(int)", symbol_name_match_type::WILD, true,
+ EXPECT ("std::zfunction", "std::zfunction2"));
+ CHECK_MATCH ("zfunc", symbol_name_match_type::WILD, true,
+ EXPECT ("std::zfunction", "std::zfunction2"));
}
/* Check that whitespace is ignored appropriately. A symbol with a
@@ -4662,6 +4670,8 @@ run_test ()
static const char expected[] = "ns::foo<int>";
CHECK_MATCH ("ns :: foo < int > ", symbol_name_match_type::FULL, false,
EXPECT (expected));
+ CHECK_MATCH ("foo < int > ", symbol_name_match_type::WILD, false,
+ EXPECT (expected));
}
/* Check that whitespace is ignored appropriately. A symbol with a
@@ -4674,9 +4684,13 @@ run_test ()
{
CHECK_MATCH ("ns :: foo < char * >", symbol_name_match_type::FULL,
completion_mode[i], EXPECT (expected));
+ CHECK_MATCH ("foo < char * >", symbol_name_match_type::WILD,
+ completion_mode[i], EXPECT (expected));
CHECK_MATCH ("ns :: foo < char * > (int)", symbol_name_match_type::FULL,
completion_mode[i], EXPECT (expected));
+ CHECK_MATCH ("foo < char * > (int)", symbol_name_match_type::WILD,
+ completion_mode[i], EXPECT (expected));
}
}
@@ -4687,14 +4701,48 @@ run_test ()
symbol_name_match_type::FULL, true, EXPECT (expected));
CHECK_MATCH ("ns :: foo < char * > ( int ) &&",
symbol_name_match_type::FULL, true, EXPECT (expected));
+ CHECK_MATCH ("foo < char * > ( int ) const",
+ symbol_name_match_type::WILD, true, EXPECT (expected));
+ CHECK_MATCH ("foo < char * > ( int ) &&",
+ symbol_name_match_type::WILD, true, EXPECT (expected));
}
/* Test lookup names that don't match anything. */
{
+ CHECK_MATCH ("bar2", symbol_name_match_type::WILD, false,
+ {});
+
CHECK_MATCH ("doesntexist", symbol_name_match_type::FULL, false,
{});
}
+ /* Some wild matching tests, exercising "(anonymous namespace)",
+ which should not be confused with a parameter list. */
+ {
+ static const char *syms[] = {
+ "A::B::C",
+ "B::C",
+ "C",
+ "A :: B :: C ( int )",
+ "B :: C ( int )",
+ "C ( int )",
+ };
+
+ for (const char *s : syms)
+ {
+ CHECK_MATCH (s, symbol_name_match_type::WILD, false,
+ EXPECT ("(anonymous namespace)::A::B::C"));
+ }
+ }
+
+ {
+ static const char expected[] = "ns2::tmpl<int>::foo2";
+ CHECK_MATCH ("tmp", symbol_name_match_type::WILD, true,
+ EXPECT (expected));
+ CHECK_MATCH ("tmpl<", symbol_name_match_type::WILD, true,
+ EXPECT (expected));
+ }
+
SELF_CHECK (!any_mismatch);
#undef EXPECT
@@ -351,6 +351,7 @@ static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
static void find_linespec_symbols (struct linespec_state *self,
VEC (symtab_ptr) *file_symtabs,
const char *name,
+ symbol_name_match_type name_match_type,
VEC (symbolp) **symbols,
VEC (bound_minimal_symbol_d) **minsyms);
@@ -1873,6 +1874,7 @@ linespec_parse_basic (linespec_parser *parser)
linespec_complete_function (tmp_tracker,
parser->completion_word,
+ symbol_name_match_type::WILD,
source_filename);
if (tmp_tracker.have_completions ())
@@ -1897,6 +1899,7 @@ linespec_parse_basic (linespec_parser *parser)
/* Try looking it up as a function/method. */
find_linespec_symbols (PARSER_STATE (parser),
PARSER_RESULT (parser)->file_symtabs, name,
+ symbol_name_match_type::WILD,
&symbols, &minimal_symbols);
if (symbols != NULL || minimal_symbols != NULL)
@@ -2405,6 +2408,7 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
linespec_p result,
const char *source_filename,
const char *function_name,
+ symbol_name_match_type fname_match_type,
const char *label_name,
struct line_offset line_offset)
{
@@ -2434,8 +2438,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
if (function_name != NULL)
{
find_linespec_symbols (self, result->file_symtabs,
- function_name, &symbols,
- &minimal_symbols);
+ function_name, fname_match_type,
+ &symbols, &minimal_symbols);
if (symbols == NULL && minimal_symbols == NULL)
symbol_not_found_error (function_name,
@@ -2475,6 +2479,7 @@ convert_explicit_location_to_sals (struct linespec_state *self,
convert_explicit_location_to_linespec (self, result,
explicit_loc->source_filename,
explicit_loc->function_name,
+ explicit_loc->func_name_match_type,
explicit_loc->label_name,
explicit_loc->line_offset);
return convert_linespec_to_sals (self, result);
@@ -2853,10 +2858,10 @@ linespec_lex_to_end (char **stringp)
void
linespec_complete_function (completion_tracker &tracker,
const char *function,
+ symbol_name_match_type func_match_type,
const char *source_filename)
{
complete_symbol_mode mode = complete_symbol_mode::LINESPEC;
- symbol_name_match_type func_match_type = symbol_name_match_type::WILD;
if (source_filename != NULL)
{
@@ -2895,7 +2900,8 @@ complete_linespec_component (linespec_parser *parser,
{
completion_list fn_list;
- linespec_complete_function (tracker, text, source_filename);
+ linespec_complete_function (tracker, text, symbol_name_match_type::WILD,
+ source_filename);
if (source_filename == NULL)
fn_list = complete_source_filenames (text);
@@ -2960,6 +2966,7 @@ linespec_complete_label (completion_tracker &tracker,
const struct language_defn *language,
const char *source_filename,
const char *function_name,
+ symbol_name_match_type func_name_match_type,
const char *label_name)
{
linespec_parser parser;
@@ -2976,6 +2983,7 @@ linespec_complete_label (completion_tracker &tracker,
PARSER_RESULT (&parser),
source_filename,
function_name,
+ func_name_match_type,
NULL, unknown_offset);
}
CATCH (ex, RETURN_MASK_ERROR)
@@ -3059,7 +3067,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
VEC (bound_minimal_symbol_d) *minimal_symbols;
find_linespec_symbols (PARSER_STATE (&parser),
PARSER_RESULT (&parser)->file_symtabs,
- func_name,
+ func_name, symbol_name_match_type::WILD,
&function_symbols, &minimal_symbols);
PARSER_RESULT (&parser)->function_symbols = function_symbols;
@@ -3940,6 +3948,7 @@ symtabs_from_filename (const char *filename,
static void
find_function_symbols (struct linespec_state *state,
VEC (symtab_ptr) *file_symtabs, const char *name,
+ symbol_name_match_type name_match_type,
VEC (symbolp) **symbols,
VEC (bound_minimal_symbol_d) **minsyms)
{
@@ -3959,8 +3968,7 @@ find_function_symbols (struct linespec_state *state,
add_all_symbol_names_from_pspace (&info, state->search_pspace,
symbol_names, FUNCTIONS_DOMAIN);
else
- add_matching_symbols_to_info (name, symbol_name_match_type::WILD,
- FUNCTIONS_DOMAIN,
+ add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN,
&info, state->search_pspace);
do_cleanups (cleanup);
@@ -3989,6 +3997,7 @@ static void
find_linespec_symbols (struct linespec_state *state,
VEC (symtab_ptr) *file_symtabs,
const char *lookup_name,
+ symbol_name_match_type name_match_type,
VEC (symbolp) **symbols,
VEC (bound_minimal_symbol_d) **minsyms)
{
@@ -4006,6 +4015,7 @@ find_linespec_symbols (struct linespec_state *state,
2) break class::method where method is in class (and not a baseclass) */
find_function_symbols (state, file_symtabs, lookup_name,
+ name_match_type,
symbols, minsyms);
/* If we were unable to locate a symbol of the same name, try dividing
@@ -191,12 +191,14 @@ extern const char * const linespec_keywords[];
extern void linespec_complete (completion_tracker &tracker,
const char *text);
-/* Complete a function symbol, in linespec mode. If SOURCE_FILENAME
- is non-NULL, limits completion to the list of functions defined in
- source files that match SOURCE_FILENAME. */
+/* Complete a function symbol, in linespec mode, according to
+ FUNC_MATCH_TYPE. If SOURCE_FILENAME is non-NULL, limits completion
+ to the list of functions defined in source files that match
+ SOURCE_FILENAME. */
extern void linespec_complete_function (completion_tracker &tracker,
const char *function,
+ symbol_name_match_type func_match_type,
const char *source_filename);
/* Complete a label symbol, in linespec mode. Only labels of
@@ -208,6 +210,7 @@ extern void linespec_complete_label (completion_tracker &tracker,
const struct language_defn *language,
const char *source_filename,
const char *function_name,
+ symbol_name_match_type name_match_type,
const char *label_name);
/* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR,
@@ -245,7 +245,13 @@ explicit_to_string_internal (int as_linespec,
if (need_space)
buf.putc (space);
if (!as_linespec)
- buf.puts ("-function ");
+ {
+ if (explicit_loc->func_name_match_type
+ == symbol_name_match_type::FULL)
+ buf.puts ("-qualified ");
+ else
+ buf.puts ("-function ");
+ }
buf.puts (explicit_loc->function_name);
need_space = 1;
}
@@ -775,6 +781,16 @@ string_to_explicit_location (const char **argp,
set_oarg (explicit_location_lex_one_function (argp, language,
completion_info));
EL_EXPLICIT (location)->function_name = oarg.release ();
+ EL_EXPLICIT (location)->func_name_match_type
+ = symbol_name_match_type::WILD;
+ }
+ else if (strncmp (opt.get (), "-qualified", len) == 0)
+ {
+ set_oarg (explicit_location_lex_one_function (argp, language,
+ completion_info));
+ EL_EXPLICIT (location)->function_name = oarg.release ();
+ EL_EXPLICIT (location)->func_name_match_type
+ = symbol_name_match_type::FULL;
}
else if (strncmp (opt.get (), "-line", len) == 0)
{
@@ -79,6 +79,9 @@ struct explicit_location
/* The function name. Malloc'd. */
char *function_name;
+ /* Whether the function name is fully-qualified or not. */
+ symbol_name_match_type func_name_match_type;
+
/* The name of a label. Malloc'd. */
char *label_name;
@@ -38,7 +38,7 @@ if [get_compiler_info] {
return -1
}
-gdb_test_multiple "b langs0" "break on nonexistent function in langs.exp" {
+gdb_test_multiple "b -qualified langs0" "break on nonexistent function in langs.exp" {
-re "Function \"langs0\" not defined\..*Make breakpoint pending on future shared library load.*y or .n.. $" {
gdb_test "n" "" "break on nonexistent function in langs.exp"
@@ -145,15 +145,37 @@ foreach test $methods {
set func [lindex $test 0]
set result [lindex $test 1]
- gdb_test "list $func" $result
- gdb_test "list '$func'" $result
- if {[gdb_breakpoint $func]} {
- pass "break $func"
+ gdb_test "list -qualified $func" $result
+ gdb_test "list -qualified '$func'" $result
+ if {[gdb_breakpoint "-qualified $func"]} {
+ pass "break -qualified $func"
}
- if {[gdb_breakpoint '$func']} {
- pass "break '$func'"
+ if {[gdb_breakpoint "-qualified '$func'"]} {
+ pass "break -qualified '$func'"
}
}
+# The tests above use -qualified to explicitly pick the one "test"
+# symbol each test cares about. Now check that both "break test(..)"
+# and "list test(..)" without -qualified find "test(..)" in all the 3
+# scopes that have the this particular overload.
+set func "test(aenum, astruct const&, aunion const***)"
+set line1 [gdb_get_line_number " A::FOO::$func"]
+set line2 [gdb_get_line_number " B::$func"]
+set line3 [gdb_get_line_number " $func"]
+
+foreach f [list "$func" "'$func'"] {
+ gdb_test \
+ "list $f" \
+ [multi_line \
+ "file: \".*$srcfile\", line number: $line1" \
+ "file: \".*$srcfile\", line number: $line2" \
+ "file: \".*$srcfile\", line number: $line3"] \
+ "list $f"
+
+ delete_breakpoints
+ gdb_test "break $f" "\\(3 locations\\)"
+}
+
gdb_exit
return 0
@@ -120,7 +120,7 @@ gdb_test "break AAA::xyzq" \
# Break on a function in the global namespace.
-gdb_test "break ::ensureOtherRefs" \
+gdb_test "break -qualified ::ensureOtherRefs" \
"Breakpoint.*at $hex: file.*$srcfile2, line $decimal\\."
# Call a function in a nested namespace