From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 28/40] lookup_name_info::make_ignore_params
Date: Fri, 02 Jun 2017 12:23:00 -0000 [thread overview]
Message-ID: <1496406158-12663-29-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1496406158-12663-1-git-send-email-palves@redhat.com>
A few places in the completion code look for a "(" to find a
function's parameter list, in order to strip it, because psymtabs (and
gdb index) don't include parameter info in the symbol names.
See compare_symbol_name and
default_collect_symbol_completion_matches_break_on.
This is too naive. Consider:
ns_overload2_test::([TAB]
We'd want to complete that to:
ns_overload2_test::(anonymous namespace)::struct_overload2_test
Or:
b (anonymous namespace)::[TAB]
That currently completes to:
b (anonymous namespace)
Which is obviously broken. This patch makes that work.
Also, the current compare_symbol_name hack means that while this
works:
"b function([TAB]" -> "b function()"
This does not:
"b function ([TAB]"
This patch fixes that. Whitespace "ignoring" now Just Works, i.e.,
assuming a symbol named "function(int, long)", this:
b function ( int , lon[TAB]
completes to:
b function ( int , long)
To address all of this, this patch builds on top of the rest of the
series, and pushes the responsibility of stripping parameters from a
lookup name to the new lookup_name_info object, where we can apply
per-language rules. Also note that we now only make a version of the
lookup name with parameters stripped out where it's actually required
to do that, in the psymtab and GDB index code.
For C++, the right way to strip parameters is with "cp_remove_params",
which uses a real parser (cp-name-parser.y) to split the name into a
component tree and then discards parameters.
The trouble for completion is that in that case we have an incomplete
name, like "foo::func(int" and thus cp_remove_params throws an error.
This patch sorts that by adding a cp_remove_params_if_any variant of
cp_remove_params that tries removing characters from the end of the
string until cp_remove_params works. So cp_remove_params_if_any
behaves like this:
With a complete name:
"foo::func(int)" => foo::func(int) # cp_remove_params_1 succeeds the first time.
With an incomplete name:
"foo::func(int" => NULL # cp_remove_params fails the first time.
"foo::func(in" => NULL # and again...
"foo::func(i" => NULL # and again...
"foo::func(" => NULL # and again...
"foo::func" => "foo::func" # success!
Note that even if this approach removes significant rightmost
characters, it's still OK, because this parameter stripping is only
necessary for psymtabs and gdb index, where we're determining whether
to expand a symbol table. Say cp_remove_params_if_any returned
"foo::" above for "foo::func(int". That'd cause us to expand more
symtabs than ideal (because we'd expand all symtabs with symbols that
start with "foo::", not just "foo::func"), but then when we actually
look for completion matches, we'd still use the original lookup name,
with parameter information ["foo::func(int"], and thus we'll return no
false positive to the user. Whether the stripping works as intended
and doesn't strip too much is thus covered by a unit test instead of a
testsuite test.
The "if_any" part of the name refers to the fact that while
cp_remove_params returns NULL if the input name has no parameters in
the first place, like:
"foo::func" => NULL # cp_remove_params
cp_remove_params_if_any still returns the function name:
"foo::func" => "foo::func" # cp_remove_params_if_any
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
* Makefile.in (SUBDIR_UNITTESTS_SRCS): Add
unittests/lookup_name_info-selftests.c.
(SUBDIR_UNITTESTS_OBS): Add lookup_name_info-selftests.o.
* cp-support.c: Include "selftest.h".
(cp_remove_params_1): Rename from cp_remove_params. Add
'require_param's parameter, and handle it.
(cp_remove_params): Reimplement.
(cp_remove_params_if_any): New.
(selftests::quote): New.
(selftests::check_remove_params): New.
(selftests::test_cp_remove_params): New.
(_initialize_cp_support): Install
selftests::test_cp_remove_params.
* cp-support.h (cp_remove_params_if_any): Declare.
* dwarf2read.c :Include "selftest.h".
(dw2_expand_symtabs_matching_symbol): Use
lookup_name_info::make_ignore_params.
(selftests::dw2_expand_symtabs_matching::mock_mapped_index)
(selftests::dw2_expand_symtabs_matching::string_or_null)
(selftests::dw2_expand_symtabs_matching::check_match)
(selftests::dw2_expand_symtabs_matching::test_symbols)
(selftests::dw2_expand_symtabs_matching::run_test): New.
(_initialize_dwarf2_read): Register
selftests::dw2_expand_symtabs_matching::run_test.
* psymtab.c (psym_expand_symtabs_matching): Use
lookup_name_info::make_ignore_params.
* symtab.c (demangle_for_lookup_info::demangle_for_lookup_info):
If the lookup name wants to ignore parameters, strip them.
(compare_symbol_name): Remove sym_text/sym_text_len parameters and
code handling '('.
(completion_list_add_name): Don't pass down sym_text/sym_text_len.
(default_collect_symbol_completion_matches_break_on): Don't try to
strip parameters.
* symtab.h (lookup_name_info::lookup_name_info): Add
'ignore_parameters' parameter.
(lookup_name_info::ignore_parameters)
(lookup_name_info::make_ignore_params): New methods.
(lookup_name_info::m_ignore_parameters): New field.
* unittests/lookup_name_info-selftests.c: New file.
---
gdb/Makefile.in | 2 +
gdb/cp-support.c | 190 +++++++++++++++++-
gdb/cp-support.h | 3 +
gdb/dwarf2read.c | 299 ++++++++++++++++++++++++++++-
gdb/psymtab.c | 4 +-
gdb/symtab.c | 65 ++-----
gdb/symtab.h | 15 +-
gdb/unittests/lookup_name_info-selftests.c | 110 +++++++++++
8 files changed, 629 insertions(+), 59 deletions(-)
create mode 100644 gdb/unittests/lookup_name_info-selftests.c
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 380df11..d92c823 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -527,6 +527,7 @@ SUBDIR_PYTHON_CFLAGS =
SUBDIR_UNITTESTS_SRCS = \
unittests/function-view-selftests.c \
+ unittests/lookup_name_info-selftests.c \
unittests/offset-type-selftests.c \
unittests/optional-selftests.c \
unittests/ptid-selftests.c \
@@ -534,6 +535,7 @@ SUBDIR_UNITTESTS_SRCS = \
SUBDIR_UNITTESTS_OBS = \
function-view-selftests.o \
+ lookup_name_info-selftests.o \
offset-type-selftests.o \
optional-selftests.o \
ptid-selftests.o \
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 0095c6d..064a45b 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -36,6 +36,7 @@
#include <signal.h>
#include "gdb_setjmp.h"
#include "safe-ctype.h"
+#include "selftest.h"
#define d_left(dc) (dc)->u.s_binary.left
#define d_right(dc) (dc)->u.s_binary.right
@@ -833,12 +834,14 @@ cp_func_name (const char *full_name)
return ret;
}
-/* DEMANGLED_NAME is the name of a function, including parameters and
- (optionally) a return type. Return the name of the function without
- parameters or return type, or NULL if we can not parse the name. */
+/* Helper for cp_remove_params. DEMANGLED_NAME is the name of a
+ function, including parameters and (optionally) a return type.
+ Return the name of the function without parameters or return type,
+ or NULL if we can not parse the name. If COMPLETION_MODE is true,
+ then tolerate a non-existing or unbalanced parameter list. */
-gdb::unique_xmalloc_ptr<char>
-cp_remove_params (const char *demangled_name)
+static gdb::unique_xmalloc_ptr<char>
+cp_remove_params_1 (const char *demangled_name, bool require_params)
{
bool done = false;
struct demangle_component *ret_comp;
@@ -874,10 +877,60 @@ cp_remove_params (const char *demangled_name)
/* What we have now should be a function. Return its name. */
if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
ret = cp_comp_to_string (d_left (ret_comp), 10);
+ else if (!require_params
+ && (ret_comp->type == DEMANGLE_COMPONENT_NAME
+ || ret_comp->type == DEMANGLE_COMPONENT_QUAL_NAME
+ || ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE))
+ ret = cp_comp_to_string (ret_comp, 10);
return gdb::unique_xmalloc_ptr<char> (ret);
}
+/* DEMANGLED_NAME is the name of a function, including parameters and
+ (optionally) a return type. Return the name of the function
+ without parameters or return type, or NULL if we can not parse the
+ name. */
+
+gdb::unique_xmalloc_ptr<char>
+cp_remove_params (const char *demangled_name)
+{
+ return cp_remove_params_1 (demangled_name, true);
+}
+
+/* DEMANGLED_NAME is the name of a function, (optionally) including
+ parameters and (optionally) a return type. Return the name of the
+ function without parameters or return type, or NULL if we can not
+ parse the name. If COMPLETION_MODE is true, then tolerate a
+ non-existing or unbalanced parameter list. */
+
+gdb::unique_xmalloc_ptr<char>
+cp_remove_params_if_any (const char *qualified, bool completion_mode)
+{
+ /* Trying to remove parameters from the empty string fails. If
+ we're completing / matching everything, avoid returning NULL
+ which would make callers interpret the result as an error. */
+ if (qualified[0] == '\0' && completion_mode)
+ return gdb::unique_xmalloc_ptr<char> (xstrdup (""));
+
+ gdb::unique_xmalloc_ptr<char> without_params
+ = cp_remove_params_1 (qualified, false);
+
+ if (without_params == NULL && completion_mode)
+ {
+ std::string copy = qualified;
+
+ while (!copy.empty ())
+ {
+ copy.pop_back ();
+ without_params = cp_remove_params_1 (copy.c_str (), false);
+ if (without_params != NULL)
+ break;
+ }
+ }
+
+ return without_params;
+}
+
/* Here are some random pieces of trivia to keep in mind while trying
to take apart demangled names:
@@ -1624,6 +1677,129 @@ cp_get_symbol_name_matcher (const lookup_name_info &lookup_name)
return cp_fq_symbol_name_matches;
}
+#if GDB_SELF_TEST
+
+namespace selftests {
+
+/* If non-NULL, return STR wrapped in quotes. Otherwise, return a
+ "<null>" string (with no quotes). */
+
+static std::string
+quote (const char *str)
+{
+ if (str != NULL)
+ return std::string (1, '\"') + str + '\"';
+ else
+ return "<null>";
+}
+
+/* Check that removing parameter info out of NAME produces EXPECTED.
+ COMPLETION_MODE indicates whether we're testing normal and
+ completion mode. FILE and LINE are used to provide better test
+ location information in case ithe check fails. */
+
+static void
+check_remove_params (const char *file, int line,
+ const char *name, const char *expected,
+ bool completion_mode)
+{
+ gdb::unique_xmalloc_ptr<char> result
+ = cp_remove_params_if_any (name, completion_mode);
+
+ if ((expected == NULL) != (result == NULL)
+ || (expected != NULL
+ && strcmp (result.get (), expected) != 0))
+ {
+ error (_("%s:%d: make-paramless self-test failed: (completion=%d) "
+ "\"%s\" -> %s, expected %s"),
+ file, line, completion_mode, name,
+ quote (result.get ()).c_str (), quote (expected).c_str ());
+ }
+}
+
+/* Entry point for cp_remove_params unit tests. */
+
+static void
+test_cp_remove_params ()
+{
+ /* Check that removing parameter info out of NAME produces EXPECTED.
+ Checks both normal and completion modes. */
+#define CHECK(NAME, EXPECTED) \
+ do \
+ { \
+ check_remove_params (__FILE__, __LINE__, NAME, EXPECTED, false); \
+ check_remove_params (__FILE__, __LINE__, NAME, EXPECTED, true); \
+ } \
+ while (0)
+
+ /* Similar, but used when NAME is incomplete -- i.e., is has
+ unbalanced parentheses. In this case, looking for the exact name
+ should fail / return empty. */
+#define CHECK_INCOMPL(NAME, EXPECTED) \
+ do \
+ { \
+ check_remove_params (__FILE__, __LINE__, NAME, NULL, false); \
+ check_remove_params (__FILE__, __LINE__, NAME, EXPECTED, true); \
+ } \
+ while (0)
+
+ CHECK ("function()", "function");
+ CHECK_INCOMPL ("function(", "function");
+ CHECK ("function() const", "function");
+
+ CHECK ("(anonymous namespace)::A::B::C",
+ "(anonymous namespace)::A::B::C");
+
+ CHECK ("A::(anonymous namespace)",
+ "A::(anonymous namespace)");
+
+ CHECK_INCOMPL ("A::(anonymou", "A");
+
+ CHECK ("A::foo<int>()",
+ "A::foo<int>");
+
+ CHECK_INCOMPL ("A::foo<int>(",
+ "A::foo<int>");
+
+ CHECK ("A::foo<(anonymous namespace)::B>::func(int)",
+ "A::foo<(anonymous namespace)::B>::func");
+
+ CHECK_INCOMPL ("A::foo<(anonymous namespace)::B>::func(in",
+ "A::foo<(anonymous namespace)::B>::func");
+
+ CHECK_INCOMPL ("A::foo<(anonymous namespace)::B>::",
+ "A::foo<(anonymous namespace)::B>");
+
+ CHECK_INCOMPL ("A::foo<(anonymous namespace)::B>:",
+ "A::foo<(anonymous namespace)::B>");
+
+ CHECK ("A::foo<(anonymous namespace)::B>",
+ "A::foo<(anonymous namespace)::B>");
+
+ CHECK_INCOMPL ("A::foo<(anonymous namespace)::B",
+ "A::foo");
+
+ /* Shouldn't this parse? Looks like a bug in
+ cp_demangled_name_to_comp. */
+#if 0
+ CHECK ("A::foo<void(int)>::func(int)",
+ "A::foo<void(int)>::func");
+#else
+ CHECK_INCOMPL ("A::foo<void(int)>::func(int)",
+ "A::foo");
+#endif
+
+ CHECK_INCOMPL ("A::foo<void(int",
+ "A::foo");
+
+#undef CHECK
+#undef CHECK_INCOMPL
+}
+
+} // namespace selftests
+
+#endif /* GDB_SELF_CHECK */
+
/* Don't allow just "maintenance cplus". */
static void
@@ -1709,4 +1885,8 @@ display the offending symbol."),
&maintenance_set_cmdlist,
&maintenance_show_cmdlist);
#endif
+
+#if GDB_SELF_TEST
+ register_self_test (selftests::test_cp_remove_params);
+#endif
}
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index dd42415..1cef3f7 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -97,6 +97,9 @@ extern char *cp_func_name (const char *full_name);
extern gdb::unique_xmalloc_ptr<char> cp_remove_params (const char *qualified);
+extern gdb::unique_xmalloc_ptr<char> cp_remove_params_if_any
+ (const char *qualified, bool completion_mode);
+
extern struct symbol **make_symbol_overload_list (const char *,
const char *);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index dfa79aa..a267377 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -77,6 +77,7 @@
#include <sys/types.h>
#include <algorithm>
#include "filename-seen-cache.h"
+#include "selftest.h"
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
@@ -4253,13 +4254,15 @@ dw2_expand_symtabs_matching
static void
dw2_expand_symtabs_matching_symbol
(mapped_index &index,
- const lookup_name_info &lookup_name,
+ const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
enum search_domain kind,
gdb::function_view<void (offset_type)> match_callback)
{
+ lookup_name_info lookup_name_without_params
+ = lookup_name_in.make_ignore_params ();
gdb_index_symbol_name_matcher lookup_name_matcher
- (lookup_name);
+ (lookup_name_without_params);
auto *name_cmp = case_sensitivity == case_sensitive_on ? strcmp : strcasecmp;
@@ -4317,7 +4320,7 @@ dw2_expand_symtabs_matching_symbol
}
const char *cplus
- = lookup_name.cplus ().lookup_name ().c_str ();
+ = lookup_name_without_params.cplus ().lookup_name ().c_str ();
/* Comparison function object for lower_bound that matches against a
given symbol name. */
@@ -4345,7 +4348,7 @@ dw2_expand_symtabs_matching_symbol
/* Find the lower bound. */
auto lower = [&] ()
{
- if (lookup_name.completion_mode () && cplus[0] == '\0')
+ if (lookup_name_in.completion_mode () && cplus[0] == '\0')
return begin;
else
return std::lower_bound (begin, end, cplus, lookup_compare_lower);
@@ -4354,7 +4357,7 @@ dw2_expand_symtabs_matching_symbol
/* Find the upper bound. */
auto upper = [&] ()
{
- if (lookup_name.completion_mode ())
+ if (lookup_name_in.completion_mode ())
{
/* The string frobbing below won't work if the string is
empty. We don't need it then, anyway -- if we're
@@ -4420,6 +4423,288 @@ dw2_expand_symtabs_matching_symbol
static_assert (sizeof (prev) > sizeof (offset_type), "");
}
+#if GDB_SELF_TEST
+
+namespace selftests { namespace dw2_expand_symtabs_matching {
+
+/* A wrapper around mapped_index that builds a mock mapped_index, from
+ the symbol list passed as parameter to the constructor. */
+class mock_mapped_index
+{
+public:
+ template<size_t N>
+ mock_mapped_index (const char *(&symbols)[N])
+ : mock_mapped_index (symbols, N)
+ {}
+
+ /* Access the built index. */
+ mapped_index &index ()
+ { return m_index; }
+
+ /* Disable copy. */
+ mock_mapped_index(const mock_mapped_index &) = delete;
+ void operator= (const mock_mapped_index &) = delete;
+
+private:
+ mock_mapped_index (const char **symbols, size_t symbols_size)
+ {
+ /* No string can live at offset zero. Add a dummy entry. */
+ obstack_grow_str0 (&m_constant_pool, "");
+
+ for (size_t i = 0; i < symbols_size; i++)
+ {
+ const char *sym = symbols[i];
+ size_t offset = obstack_object_size (&m_constant_pool);
+ obstack_grow_str0 (&m_constant_pool, sym);
+ m_symbol_table.push_back (offset);
+ m_symbol_table.push_back (0);
+ };
+
+ m_index.constant_pool = (const char *) obstack_base (&m_constant_pool);
+ m_index.symbol_table = m_symbol_table.data ();
+ m_index.symbol_table_slots = m_symbol_table.size () / 2;
+ }
+
+public:
+ /* The built mapped_index. */
+ mapped_index m_index{};
+
+ /* The storage that the built mapped_index uses for symbol and
+ constant pool tables. */
+ std::vector<offset_type> m_symbol_table;
+ auto_obstack m_constant_pool;
+};
+
+/* Convenience function that converts a NULL pointer to a "<null>"
+ string, to pass to print routines. */
+
+static const char *
+string_or_null (const char *str)
+{
+ return str != NULL ? str : "<null>";
+}
+
+/* Check if a lookup_name_info built from
+ NAME/MATCH_TYPE/COMPLETION_MODE matches the symbols in the mock
+ index. EXPECTED_LIST is the list of expected matches, in expected
+ matching order. If no match expected, then an empty list is
+ specified. Returns true on success. On failure prints a warning
+ indicating the file:line that failed, and returns false. */
+
+static bool
+check_match (const char *file, int line,
+ mock_mapped_index &mock_index,
+ const char *name, symbol_name_match_type match_type,
+ bool completion_mode,
+ std::initializer_list<const char *> expected_list)
+{
+ lookup_name_info lookup_name (name, match_type, completion_mode);
+
+ bool matched = true;
+
+ auto mismatch = [&] (const char *expected_str,
+ const char *got)
+ {
+ warning (_("%s:%d: match_type=%s, looking-for=\"%s\", "
+ "expected=\"%s\", got=\"%s\"\n"),
+ file, line,
+ (match_type == symbol_name_match_type::FULL
+ ? "FULL" : "WILD"),
+ name, string_or_null (expected_str), string_or_null (got));
+ matched = false;
+ };
+
+ auto expected_it = expected_list.begin ();
+ auto expected_end = expected_list.end ();
+
+ dw2_expand_symtabs_matching_symbol (mock_index.index (), lookup_name,
+ NULL, ALL_DOMAIN,
+ [&] (offset_type idx)
+ {
+ const char *matched_name = mock_index.index ().symbol_name_at (idx);
+ const char *expected_str
+ = expected_it == expected_end ? NULL : *expected_it++;
+
+ if (expected_str == NULL || strcmp (expected_str, matched_name) != 0)
+ mismatch (expected_str, matched_name);
+ });
+
+ const char *expected_str
+ = expected_it == expected_end ? NULL : *expected_it++;
+ if (expected_str != NULL)
+ mismatch (expected_str, NULL);
+
+ return matched;
+}
+
+/* The symbols added to the mock mapped_index for testing (in
+ canonical form). */
+static const char *test_symbols[] = {
+ "function",
+ "std::bar",
+ "std::zfunction",
+ "std::zfunction2",
+ "w1::w2",
+ "ns::foo<char*>",
+ "ns::foo<int>",
+ "ns::foo<long>",
+
+ /* A name with all sorts of complications. Starts with "z" to make
+ it easier for the completion tests below. */
+#define Z_SYM_NAME \
+ "z::std::tuple<(anonymous namespace)::ui*, std::bar<(anonymous namespace)::ui> >" \
+ "::tuple<(anonymous namespace)::ui*, " \
+ "std::default_delete<(anonymous namespace)::ui>, void>"
+
+ Z_SYM_NAME
+};
+
+static void
+run_test ()
+{
+ mock_mapped_index mock_index (test_symbols);
+
+ /* We let all tests run until the end even if some fails, for debug
+ convenience. */
+ bool any_mismatch = false;
+
+ /* Create the expected symbols list (an initializer_list). Needed
+ because lists have commas, and we need to pass them to CHECK,
+ which is a macro. */
+#define EXPECT(...) { __VA_ARGS__ }
+
+ /* Wrapper for check_match that passes down the current
+ __FILE__/__LINE__. */
+#define CHECK_MATCH(NAME, MATCH_TYPE, COMPLETION_MODE, EXPECTED_LIST) \
+ any_mismatch |= !check_match (__FILE__, __LINE__, \
+ mock_index, \
+ NAME, MATCH_TYPE, COMPLETION_MODE, \
+ EXPECTED_LIST)
+
+ /* Identity checks. */
+ for (const char *sym : test_symbols)
+ {
+ /* Should be able to match all existing symbols. */
+ CHECK_MATCH (sym, symbol_name_match_type::FULL, false,
+ EXPECT (sym));
+
+ /* Should be able to match all existing symbols with
+ parameters. */
+ std::string with_params = std::string (sym) + "(int)";
+ CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
+ EXPECT (sym));
+
+ /* Should be able to match all existing symbols with
+ parameters and qualifiers. */
+ with_params = std::string (sym) + " ( int ) const";
+ CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
+ EXPECT (sym));
+
+ /* This should really find sym, but cp-name-parser.y doesn't
+ know about lvalue/rvalue qualifiers yet. */
+ with_params = std::string (sym) + " ( int ) &&";
+ CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
+ {});
+ }
+
+ /* Check that completion mode works at each prefix of the expected
+ symbol name. */
+ {
+ static const char str[] = "function(int)";
+ size_t len = strlen (str);
+ std::string lookup;
+
+ for (size_t i = 1; i < len; i++)
+ {
+ lookup.assign (str, i);
+ CHECK_MATCH (lookup.c_str (), symbol_name_match_type::FULL, true,
+ EXPECT ("function"));
+ }
+ }
+
+ /* While "w" is a prefix of both components, the match function
+ should still only be called once. */
+ {
+ CHECK_MATCH ("w", symbol_name_match_type::FULL, true,
+ EXPECT ("w1::w2"));
+ }
+
+ /* Same, with a "complicated" symbol. */
+ {
+ static const char str[] = Z_SYM_NAME;
+ size_t len = strlen (str);
+ std::string lookup;
+
+ for (size_t i = 1; i < len; i++)
+ {
+ lookup.assign (str, i);
+ CHECK_MATCH (lookup.c_str (), symbol_name_match_type::FULL, true,
+ EXPECT (Z_SYM_NAME));
+ }
+ }
+
+ /* In FULL mode, an incomplete symbol doesn't match. */
+ {
+ CHECK_MATCH ("std::zfunction(int", symbol_name_match_type::FULL, false,
+ {});
+ }
+
+ /* A complete symbol with parameters matches any overload, since the
+ index has no overload info. */
+ {
+ CHECK_MATCH ("std::zfunction(int)", symbol_name_match_type::FULL, true,
+ EXPECT ("std::zfunction", "std::zfunction2"));
+ }
+
+ /* Check that whitespace is ignored appropriately. A symbol with a
+ template argument list. */
+ {
+ static const char expected[] = "ns::foo<int>";
+ CHECK_MATCH ("ns :: foo < int > ", symbol_name_match_type::FULL, false,
+ EXPECT (expected));
+ }
+
+ /* Check that whitespace is ignored appropriately. A symbol with a
+ template argument list that includes a pointer. */
+ {
+ static const char expected[] = "ns::foo<char*>";
+ /* Try both completion and non-completion modes. */
+ static const bool completion_mode[2] = {false, true};
+ for (size_t i = 0; i < 2; i++)
+ {
+ CHECK_MATCH ("ns :: foo < char * >", symbol_name_match_type::FULL,
+ completion_mode[i], EXPECT (expected));
+
+ CHECK_MATCH ("ns :: foo < char * > (int)", symbol_name_match_type::FULL,
+ completion_mode[i], EXPECT (expected));
+ }
+ }
+
+ {
+ /* Check method qualifiers are ignored. */
+ static const char expected[] = "ns::foo<char*>";
+ CHECK_MATCH ("ns :: foo < char * > ( int ) const",
+ symbol_name_match_type::FULL, true, EXPECT (expected));
+ CHECK_MATCH ("ns :: foo < char * > ( int ) &&",
+ symbol_name_match_type::FULL, true, EXPECT (expected));
+ }
+
+ /* Test lookup names that don't match anything. */
+ {
+ CHECK_MATCH ("doesntexist", symbol_name_match_type::FULL, false,
+ {});
+ }
+
+ SELF_CHECK (!any_mismatch);
+
+#undef EXPECT
+#undef CHECK_MATCH
+}
+
+}} // namespace selftests::dw2_expand_symtabs_matching
+
+#endif /* GDB_SELF_TEST */
+
/* Helper for dw2_expand_matching symtabs. Called on each symbol
matched, to expand corresponding CUs that were marked. IDX is the
index of the symbol name that matched. */
@@ -24536,4 +24821,8 @@ Usage: save gdb-index DIRECTORY"),
&dwarf2_block_frame_base_locexpr_funcs);
dwarf2_loclist_block_index = register_symbol_block_impl (LOC_BLOCK,
&dwarf2_block_frame_base_loclist_funcs);
+
+#if GDB_SELF_TEST
+ register_self_test (selftests::dw2_expand_symtabs_matching::run_test);
+#endif
}
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 1a1929d..a51637b 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1408,13 +1408,15 @@ static void
psym_expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info &lookup_name,
+ const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain domain)
{
struct partial_symtab *ps;
+ lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
+
/* Clear the search flags. */
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 41348bd..68b8af5 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1769,6 +1769,20 @@ demangle_for_lookup_info::demangle_for_lookup_info (const lookup_name_info &look
{
demangle_result_storage storage;
+ if (lookup_name.ignore_parameters () && lang == language_cplus)
+ {
+ gdb::unique_xmalloc_ptr<char> without_params
+ = cp_remove_params_if_any (lookup_name.name ().c_str (),
+ lookup_name.completion_mode ());
+
+ if (without_params != NULL)
+ {
+ m_demangled_name = demangle_for_lookup (without_params.get (),
+ lang, storage);
+ return;
+ }
+ }
+
m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (),
lang, storage);
}
@@ -4767,20 +4781,11 @@ rbreak_command (char *regexp, int from_tty)
}
\f
-/* Evaluate if NAME matches SYM_TEXT and SYM_TEXT_LEN.
-
- Either sym_text[sym_text_len] != '(' and then we search for any
- symbol starting with SYM_TEXT text.
-
- Otherwise sym_text[sym_text_len] == '(' and then we require symbol name to
- be terminated at that point. Partial symbol tables do not have parameters
- information. */
+/* Evaluate if SYMNAME matches LOOKUP_NAME. */
static int
-compare_symbol_name (const char *name,
- language symbol_language,
+compare_symbol_name (const char *symbol_name, language symbol_language,
const lookup_name_info &lookup_name,
- const char *sym_text, int sym_text_len,
completion_match_result &match_res)
{
const language_defn *lang;
@@ -4802,23 +4807,7 @@ compare_symbol_name (const char *name,
symbol_name_matcher_ftype *name_match
= language_get_symbol_name_matcher (lang, lookup_name);
- /* Clip symbols that cannot match. */
- if (!name_match (name, lookup_name, &match_res.match))
- return 0;
-
- if (sym_text[sym_text_len] == '(')
- {
- /* User searches for `name(someth...'. Require NAME to be terminated.
- Normally psymtabs and gdbindex have no parameter types so '\0' will be
- present but accept even parameters presence. In this case this
- function is in fact strcmp_iw but whitespace skipping is not supported
- for tab completion. */
-
- if (name[sym_text_len] != '\0' && name[sym_text_len] != '(')
- return 0;
- }
-
- return 1;
+ return name_match (symbol_name, lookup_name, &match_res.match);
}
/* Test to see if the symbol specified by SYMNAME (which is already
@@ -4837,10 +4826,7 @@ completion_list_add_name (completion_tracker &tracker,
= tracker.reset_completion_match_result ();
/* Clip symbols that cannot match. */
- if (!compare_symbol_name (symname, symbol_language,
- lookup_name,
- sym_text, sym_text_len,
- match_res))
+ if (!compare_symbol_name (symname, symbol_language, lookup_name, match_res))
return;
/* Refresh SYMNAME from the match string. It's potentially
@@ -5165,21 +5151,6 @@ default_collect_symbol_completion_matches_break_on
sym_text_len = strlen (sym_text);
- /* Prepare SYM_TEXT_LEN for compare_symbol_name. */
-
- if (current_language->la_language == language_cplus
- || current_language->la_language == language_fortran)
- {
- /* These languages may have parameters entered by user but they are never
- present in the partial symbol tables. */
-
- const char *cs = (const char *) memchr (sym_text, '(', sym_text_len);
-
- if (cs)
- sym_text_len = cs - sym_text;
- }
- gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
-
lookup_name_info lookup_name (std::string (sym_text, sym_text_len),
name_match_type, true);
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 4c8b1f6..a452804 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -166,9 +166,11 @@ class lookup_name_info final
/* Create a new object. */
lookup_name_info (std::string name,
symbol_name_match_type match_type,
- bool completion_mode = false)
+ bool completion_mode = false,
+ bool ignore_parameters = false)
: m_match_type (match_type),
m_completion_mode (completion_mode),
+ m_ignore_parameters (ignore_parameters),
m_name (std::move (name))
{}
@@ -176,6 +178,16 @@ class lookup_name_info final
symbol_name_match_type match_type () const { return m_match_type; }
bool completion_mode () const { return m_completion_mode; }
const std::string &name () const { return m_name; }
+ const bool ignore_parameters () const { return m_ignore_parameters; }
+
+ /* Return a version of this lookup name that is usable with
+ comparisons against symbols have have no parameter info, such as
+ psymbols and GDB index symbols. */
+ lookup_name_info make_ignore_params () const
+ {
+ return lookup_name_info (m_name, m_match_type, m_completion_mode,
+ true /* ignore params */);
+ }
/* Get the search name hash for searches in language LANG. */
unsigned int search_name_hash (language lang) const
@@ -252,6 +264,7 @@ private:
/* The lookup info as passed to the ctor. */
symbol_name_match_type m_match_type;
bool m_completion_mode;
+ bool m_ignore_parameters;
std::string m_name;
/* Language-specific info. These fields are filled lazily the first
diff --git a/gdb/unittests/lookup_name_info-selftests.c b/gdb/unittests/lookup_name_info-selftests.c
new file mode 100644
index 0000000..99238ae
--- /dev/null
+++ b/gdb/unittests/lookup_name_info-selftests.c
@@ -0,0 +1,110 @@
+/* Self tests for lookup_name_info for GDB, the GNU debugger.
+
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#include "defs.h"
+#include "selftest.h"
+#include "symtab.h"
+
+namespace selftests {
+namespace lookup_name {
+
+/* Check that removing parameter info out of NAME produces EXPECTED.
+ COMPLETION_MODE indicates whether we're testing normal and
+ completion mode. FILE and LINE are used to provide better test
+ location information in case the check fails. */
+
+static void
+check_make_paramless (const char *file, int line,
+ enum language lang,
+ const char *name, const char *expected,
+ bool completion_mode)
+{
+ lookup_name_info lookup_name (name, symbol_name_match_type::FULL,
+ completion_mode, true /* ignore_parameters */);
+ const std::string &result = lookup_name.language_lookup_name (lang);
+
+ if (result != expected)
+ {
+ error (_("%s:%d: make-paramless self-test failed: (completion=%d, lang=%d) "
+ "\"%s\" -> \"%s\", expected \"%s\""),
+ file, line, completion_mode, lang, name,
+ result.c_str (), expected);
+ }
+}
+
+static void
+run_tests ()
+{
+ /* Helper for CHECK and CHECK_INCOMPL. */
+#define CHECK_1(INCOMPLETE, LANG, NAME, EXPECTED) \
+ do \
+ { \
+ check_make_paramless (__FILE__, __LINE__, \
+ LANG, NAME, \
+ (INCOMPLETE) ? "" : (EXPECTED), false); \
+ check_make_paramless (__FILE__, __LINE__, \
+ LANG, NAME, EXPECTED, true); \
+ } \
+ while (0)
+
+ /* Check that removing parameter info out of NAME produces EXPECTED.
+ Checks both normal and completion modes. */
+#define CHECK(LANG, NAME, EXPECTED) \
+ CHECK_1(false, LANG, NAME, EXPECTED)
+
+ /* Similar, but used when NAME is incomplete -- i.e., NAME has
+ unbalanced parentheses. In this case, looking for the exact name
+ should fail / return empty. */
+#define CHECK_INCOMPL(LANG, NAME, EXPECTED) \
+ CHECK_1 (true, LANG, NAME, EXPECTED)
+
+ /* None of these languages support function overloading like C++
+ does, so building a nameless lookup name ends up being just the
+ same as any other lookup name. Mainly this serves as smoke test
+ that C++-specific code doesn't mess up with other languages that
+ use some other scoping character ('.' vs '::'). */
+ CHECK (language_ada, "pck.ada_hello", "pck__ada_hello");
+ CHECK (language_go, "pck.go_hello", "pck.go_hello");
+ CHECK (language_fortran, "mod::func", "mod::func");
+
+ /* D does support function overloading similar to C++, but we're
+ missing support for stripping parameters. At least make sure the
+ input name is preserved unmodified. */
+ CHECK (language_d, "pck.d_hello", "pck.d_hello");
+
+ /* Just a few basic tests to make sure
+ lookup_name_info::make_paramless is well integrated with
+ cp_remove_params_if_any. gdb/cp-support.c has comprehensive
+ testing of C++ specifics. */
+ CHECK (language_cplus, "function()", "function");
+ CHECK (language_cplus, "function() const", "function");
+ CHECK (language_cplus, "A::B::C()", "A::B::C");
+ CHECK (language_cplus, "A::B::C", "A::B::C");
+
+#undef CHECK
+#undef CHECK_INCOMPL
+}
+
+}} // namespace selftests::lookup_name
+
+void
+_initialize_lookup_name_info_selftests ()
+{
+ register_self_test (selftests::lookup_name::run_tests);
+}
--
2.5.5
next prev parent reply other threads:[~2017-06-02 12:23 UTC|newest]
Thread overview: 182+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-02 12:22 [PATCH 00/40] C++ debugging improvements: breakpoints, TAB completion, more Pedro Alves
2017-06-02 12:22 ` [PATCH 02/40] Eliminate make_cleanup_obstack_free, introduce auto_obstack Pedro Alves
2017-06-26 13:47 ` Yao Qi
2017-06-27 10:25 ` Pedro Alves
2017-06-28 10:36 ` Yao Qi
2017-06-28 14:39 ` Pedro Alves
2017-06-28 21:33 ` Yao Qi
2017-06-02 12:22 ` [PATCH 03/40] Fix gdb.base/completion.exp with --target_board=dwarf4-gdb-index Pedro Alves
2017-07-13 20:28 ` Keith Seitz
2017-07-14 16:02 ` Pedro Alves
2017-06-02 12:22 ` [PATCH 01/40] Make gdb.base/dmsym.exp independent of "set language ada" Pedro Alves
2017-07-18 19:42 ` Simon Marchi
2017-07-20 17:00 ` Pedro Alves
2017-06-02 12:22 ` [PATCH 14/40] Introduce CP_OPERATOR_STR/CP_OPERATOR_LEN and use throughout Pedro Alves
2017-07-14 18:04 ` Keith Seitz
2017-07-17 14:55 ` Pedro Alves
2017-06-02 12:22 ` [PATCH 06/40] Expression completer should not match explicit location options Pedro Alves
2017-06-29 8:29 ` Yao Qi
2017-06-29 10:56 ` Pedro Alves
2017-06-29 11:08 ` Pedro Alves
2017-06-29 15:23 ` Pedro Alves
2017-06-29 11:24 ` Yao Qi
2017-06-29 15:25 ` Pedro Alves
2017-06-02 12:22 ` [PATCH 08/40] completion_list_add_name wrapper functions Pedro Alves
2017-06-27 12:56 ` Yao Qi
2017-06-27 15:35 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 11/40] Introduce class completion_tracker & rewrite completion<->readline interaction Pedro Alves
2017-07-14 17:23 ` Keith Seitz
2017-07-17 13:56 ` Pedro Alves
2017-07-18 8:23 ` Christophe Lyon
[not found] ` <845f435e-d3d5-b327-4e3a-ce9434bd6ffd@redhat.com>
2017-07-18 10:42 ` [pushed] Fix GDB builds that include the simulator (Re: [PATCH 11/40] Introduce class completion_tracker & rewrite completion<->readline interaction) Pedro Alves
2018-03-05 21:43 ` [PATCH 11/40] Introduce class completion_tracker & rewrite completion<->readline interaction Simon Marchi
2017-06-02 12:23 ` [PATCH 19/40] Fix cp_find_first_component_aux bug Pedro Alves
2017-07-17 19:17 ` Keith Seitz
2017-07-17 19:50 ` Pedro Alves
2017-07-17 21:38 ` Keith Seitz
2017-07-20 17:03 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 40/40] Document breakpoints / linespec & co improvements (manual + NEWS) Pedro Alves
2017-06-02 13:01 ` Eli Zaretskii
2017-06-02 13:33 ` Pedro Alves
2017-06-21 15:50 ` Pedro Alves
2017-06-21 19:14 ` Pedro Alves
2017-06-22 19:45 ` Eli Zaretskii
2017-06-22 19:42 ` Eli Zaretskii
2017-06-21 13:32 ` Pedro Alves
2017-06-21 18:26 ` Eli Zaretskii
2017-06-21 19:01 ` Pedro Alves
2017-06-22 19:43 ` Eli Zaretskii
2017-06-02 12:23 ` Pedro Alves [this message]
2017-08-08 20:55 ` [PATCH 28/40] lookup_name_info::make_ignore_params Keith Seitz
2017-11-08 16:18 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 18/40] A smarter linespec completer Pedro Alves
2017-07-15 0:07 ` Keith Seitz
2017-07-17 18:21 ` Pedro Alves
2017-07-17 19:02 ` Keith Seitz
2017-07-17 19:33 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 38/40] Use TOLOWER in SYMBOL_HASH_NEXT Pedro Alves
2017-08-09 19:25 ` Keith Seitz
2017-11-25 0:35 ` [pushed] " Pedro Alves
2017-06-02 12:23 ` [PATCH 13/40] Introduce strncmp_iw Pedro Alves
2017-06-29 8:42 ` Yao Qi
2017-07-17 19:16 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 09/40] Rename make_symbol_completion_list_fn -> symbol_completer Pedro Alves
2017-06-28 21:40 ` Yao Qi
2017-07-13 20:46 ` Keith Seitz
2017-07-17 11:00 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 37/40] Fix completing an empty string Pedro Alves
2017-08-09 18:01 ` Keith Seitz
2017-11-25 0:28 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 27/40] Make cp_remove_params return a unique_ptr Pedro Alves
2017-08-08 20:35 ` Keith Seitz
2017-10-09 15:13 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 10/40] Clean up "completer_handle_brkchars" callback handling Pedro Alves
2017-07-13 21:08 ` Keith Seitz
2017-07-17 11:14 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 34/40] Make strcmp_iw NOT ignore whitespace in the middle of tokens Pedro Alves
2017-08-09 15:48 ` Keith Seitz
2017-11-24 23:38 ` [pushed] " Pedro Alves
2017-06-02 12:23 ` [PATCH 15/40] Rewrite/enhance explicit locations completer, parse left->right Pedro Alves
2017-07-14 20:55 ` Keith Seitz
2017-07-17 19:24 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 39/40] Breakpoints in symbols with ABI tags (PR c++/19436) Pedro Alves
2017-08-09 19:34 ` Keith Seitz
2017-11-27 17:14 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 35/40] Comprehensive C++ linespec/completer tests Pedro Alves
2017-08-09 17:30 ` Keith Seitz
2017-11-24 16:25 ` Pedro Alves
2017-06-02 12:23 ` [PATCH 36/40] Add comprehensive C++ operator linespec/location/completion tests Pedro Alves
2017-08-09 17:59 ` Keith Seitz
2017-11-25 0:18 ` [pushed] " Pedro Alves
2017-11-30 15:43 ` Yao Qi
2017-11-30 16:06 ` Pedro Alves
2017-11-30 16:35 ` [pushed] Fix gdb.linespec/cpls-ops.exp on 32-bit (Re: [pushed] Re: [PATCH 36/40] Add comprehensive C++ operator linespec/location/completion tests) Pedro Alves
2017-06-02 12:28 ` [PATCH 24/40] Per-language symbol name hashing algorithm Pedro Alves
2017-07-18 17:33 ` Keith Seitz
2017-07-20 18:53 ` Pedro Alves
2017-11-08 16:08 ` Pedro Alves
2017-06-02 12:29 ` [PATCH 17/40] Linespec lexing and C++ operators Pedro Alves
2017-07-14 21:45 ` Keith Seitz
2017-07-17 19:34 ` Pedro Alves
2017-06-02 12:29 ` [PATCH 07/40] objfile_per_bfd_storage non-POD Pedro Alves
2017-06-27 12:00 ` Yao Qi
2017-06-27 15:30 ` Pedro Alves
2017-06-02 12:29 ` [PATCH 16/40] Explicit locations -label completer Pedro Alves
2017-07-14 21:32 ` Keith Seitz
2017-06-02 12:29 ` [PATCH 12/40] "complete" command and completion word break characters Pedro Alves
2017-07-14 17:50 ` Keith Seitz
2017-07-17 14:36 ` Pedro Alves
2017-06-02 12:29 ` [PATCH 33/40] Make the linespec/location completer ignore data symbols Pedro Alves
2017-08-09 15:42 ` Keith Seitz
2017-11-08 16:22 ` Pedro Alves
2017-06-02 12:29 ` [PATCH 21/40] Use SYMBOL_MATCHES_SEARCH_NAME some more Pedro Alves
2017-07-17 21:39 ` Keith Seitz
2017-07-20 17:08 ` Pedro Alves
2017-06-02 12:29 ` [PATCH 05/40] command.h: Include scoped_restore_command.h Pedro Alves
2017-06-27 11:30 ` Yao Qi
2017-06-27 11:45 ` Pedro Alves
2017-06-27 11:52 ` Pedro Alves
2017-06-27 12:03 ` Pedro Alves
2017-06-27 15:46 ` [PATCH 05/40] command.h: Include common/scoped_restore.h Pedro Alves
2017-06-28 7:54 ` Yao Qi
2017-06-28 14:20 ` Pedro Alves
2017-06-02 12:30 ` [PATCH 32/40] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Pedro Alves
2017-08-08 23:48 ` Keith Seitz
2017-11-22 16:48 ` Pedro Alves
2017-11-24 16:48 ` Pedro Alves
2017-11-24 16:57 ` Pedro Alves
2017-11-28 0:39 ` Keith Seitz
2017-11-28 0:02 ` Keith Seitz
2017-11-28 0:21 ` Pedro Alves
2017-11-28 0:42 ` Keith Seitz
2017-06-02 12:30 ` [PATCH 30/40] Use search_domain::FUNCTIONS_DOMAIN when setting breakpoints Pedro Alves
2017-08-08 21:07 ` Keith Seitz
2017-11-08 16:20 ` Pedro Alves
2017-06-02 12:30 ` [PATCH 20/40] Eliminate block_iter_name_* Pedro Alves
2017-07-17 19:47 ` Keith Seitz
2017-07-20 17:05 ` Pedro Alves
2017-06-02 12:31 ` [PATCH 29/40] Simplify completion_list_add_name | remove sym_text / sym_text_len Pedro Alves
2017-08-08 20:59 ` Keith Seitz
2017-11-08 16:19 ` Pedro Alves
2017-06-02 12:31 ` [PATCH 04/40] Fix TAB-completion + .gdb_index slowness (generalize filename_seen_cache) Pedro Alves
2017-07-13 20:41 ` Keith Seitz
2017-07-14 19:40 ` Pedro Alves
2017-07-17 10:51 ` Pedro Alves
2017-06-02 12:31 ` [PATCH 22/40] get_int_var_value Pedro Alves
2017-07-17 22:11 ` Keith Seitz
2017-07-20 17:15 ` Pedro Alves
2017-06-02 12:33 ` [PATCH 31/40] Handle custom completion match prefix / LCD Pedro Alves
2017-08-08 21:28 ` Keith Seitz
2017-11-27 17:11 ` Pedro Alves
2017-06-02 12:39 ` [PATCH 25/40] Introduce lookup_name_info and generalize Ada's FULL/WILD name matching Pedro Alves
2017-07-18 20:14 ` Keith Seitz
2017-07-18 22:31 ` Pedro Alves
2017-07-20 19:00 ` Pedro Alves
2017-07-20 19:06 ` Pedro Alves
2017-08-08 20:29 ` Keith Seitz
2017-10-19 17:36 ` Pedro Alves
2017-11-01 15:38 ` Joel Brobecker
2017-11-08 16:10 ` Pedro Alves
2017-11-08 22:15 ` Joel Brobecker
2017-06-02 12:39 ` [PATCH 23/40] Make language_def O(1) Pedro Alves
2017-07-17 23:03 ` Keith Seitz
2017-07-20 17:40 ` Pedro Alves
2017-07-20 18:12 ` Get rid of "set language local"? (was: Re: [PATCH 23/40] Make language_def O(1)) Pedro Alves
2017-07-20 23:44 ` Matt Rice
2017-06-02 12:39 ` [PATCH 26/40] Optimize .gdb_index symbol name searching Pedro Alves
2017-08-08 20:32 ` Keith Seitz
2017-11-08 16:14 ` Pedro Alves
2017-11-08 16:16 ` [pushed] Reorder/reindent dw2_expand_symtabs_matching & friends (Re: [PATCH 26/40] Optimize .gdb_index symbol name searching) Pedro Alves
2017-11-18 5:23 ` [PATCH 26/40] Optimize .gdb_index symbol name searching Simon Marchi
2017-11-20 0:33 ` Pedro Alves
2017-11-20 0:42 ` [PATCH 2/3] Unit test name-component bounds searching directly Pedro Alves
2017-11-20 3:16 ` Simon Marchi
2017-11-20 14:17 ` Pedro Alves
2017-11-20 0:42 ` [PATCH 3/3] Fix mapped_index::find_name_components_bounds upper bound computation Pedro Alves
2017-11-20 3:17 ` Simon Marchi
2017-11-20 0:42 ` [PATCH 1/3] 0xff chars in name components table; cp-name-parser lex UTF-8 identifiers Pedro Alves
2017-11-20 1:38 ` Simon Marchi
2017-11-20 11:56 ` Pedro Alves
2017-11-20 16:50 ` Simon Marchi
2017-11-21 0:11 ` Pedro Alves
2017-06-02 15:26 ` [PATCH 00/40] C++ debugging improvements: breakpoints, TAB completion, more Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1496406158-12663-29-git-send-email-palves@redhat.com \
--to=palves@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox