From: Patrick Palka <patrick@parcs.ath.cx>
To: gdb-patches@sourceware.org
Cc: Patrick Palka <patrick@parcs.ath.cx>
Subject: [PATCH] [RFC] PR c++/16874: make it easier to use anonymous namespaces
Date: Mon, 01 Dec 2014 03:22:00 -0000 [thread overview]
Message-ID: <1417404096-16170-1-git-send-email-patrick@parcs.ath.cx> (raw)
Symbols referring to names defined inside a top-level C++ anonymous
namespace have an "(anonymous namespace)::" prefix attached to them.
Referring to such symbols in commands such as "print" and "break" is
cumbersome because the prefix is tricky to type and symbols with this
prefix do not TAB-complete properly.
To make it easier to refer to such symbols, this patch allows the user
to omit "(anonymous namespace)::" prefix from these symbols. In other
words, this patch allows the symbol "(anonymous namespace)::FOO" to be
referred to as "FOO". Likewise "(anonymous namespace)::FOO::BAR" ==>
"FOO::BAR". But not "FOO::(anonymous namespace)::BAZ" ==> "FOO::BAZ"
because the anonymous namespace in question is not the top-level one.
It also doesn't handle "(anonymous namespace)::(anonymous namespace)::FOO"
==> "FOO".
This patch is implemented in three hunks. The cp-namespace.c hunk
handles the elision of the anon prefix during symbol lookup in the
expression context (.e.g. "print foo"). The linespec.c hunk handles the
elision of the anon prefix during symbol lookup in the breakpoint
context (e.g. "break foo"). And finally the symtab.c hunk handles the
elision of the anon prefix during symbol completion. This patch does
not yet have a test case, but nonetheless I would very much appreciate
comments on the approach that this patch takes in address the mentioned
PR.
I chose this approach because symbols defined in the root anonymous
namespace are very akin to static symbols so it is intuitive and
convenient to treat them as such, that is, to pretend that their
(anonymous namespace):: prefix doesn't even exist (unless the prefix was
explicitly given by the user).
gdb/ChangeLog:
* cp-support.h (cp_in_root_anonymous_namespace_p): New function.
* cp-namespace.c (cp_lookup_symbol_nonlocal): Try looking for
the symbol within the root anonymous namespace.
* linespec.c (find_linespec_symbols): Likewise.
* symtab.c (completion_list_add_name): Ignore the root anonymous
namespace prefix when looking for matching symbols.
---
gdb/cp-namespace.c | 23 +++++++++++++++++++++--
gdb/cp-support.h | 10 ++++++++++
gdb/linespec.c | 20 +++++++++++++++++++-
gdb/symtab.c | 10 ++++++++++
4 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index fcfd17b..149c3c1 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -233,8 +233,27 @@ cp_lookup_symbol_nonlocal (const char *name,
if (sym != NULL)
return sym;
- return cp_lookup_symbol_namespace (scope, name,
- block, domain);
+ sym = cp_lookup_symbol_namespace (scope, name, block, domain);
+ if (sym != NULL)
+ return sym;
+
+ /* If we can't find the symbol then try searching for it inside the
+ root anonymous namespace, i.e. the symbol
+ (anonymous namespace)::NAME. */
+
+ if (!cp_in_root_anonymous_namespace_p (name))
+ {
+ char *anon_name = alloca (strlen (CP_ANONYMOUS_NAMESPACE_STR "::")
+ + strlen (name) + 1);
+ strcpy (anon_name, CP_ANONYMOUS_NAMESPACE_STR "::");
+ strcat (anon_name, name);
+
+ sym = cp_lookup_symbol_nonlocal (anon_name, block, domain);
+ if (sym != NULL)
+ return sym;
+ }
+
+ return NULL;
}
/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index c0ae35b..10be09f 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -143,6 +143,16 @@ struct using_direct
};
+/* Test whether SYMBOL correponds to a name inside the root anonymous
+ namespace. */
+
+static inline int
+cp_in_root_anonymous_namespace_p (const char *symbol)
+{
+ return strncmp (symbol, CP_ANONYMOUS_NAMESPACE_STR "::",
+ CP_ANONYMOUS_NAMESPACE_LEN + 2) == 0;
+}
+
/* Functions from cp-support.c. */
extern char *cp_canonicalize_string (const char *string);
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 82384ca..8a6c7f7 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -3134,7 +3134,25 @@ find_linespec_symbols (struct linespec_state *state,
find_function_symbols (state, file_symtabs, lookup_name,
symbols, minsyms);
- /* If we were unable to locate a symbol of the same name, try dividing
+ /* For convenience, if LOOKUP_NAME was not found then look for
+ (anonymous namespace)::LOOKUP_NAME (C++ only). */
+
+ if (state->language->la_language == language_cplus
+ && VEC_empty (symbolp, *symbols)
+ && VEC_empty (bound_minimal_symbol_d, *minsyms)
+ && !cp_in_root_anonymous_namespace_p (name))
+ {
+ char *new_lookup_name = alloca (strlen (CP_ANONYMOUS_NAMESPACE_STR "::")
+ + strlen (lookup_name) + 1);
+
+ strcpy (new_lookup_name, CP_ANONYMOUS_NAMESPACE_STR "::");
+ strcat (new_lookup_name, name);
+
+ find_function_symbols (state, file_symtabs, new_lookup_name,
+ symbols, minsyms);
+ }
+
+ /* If we were still unable to locate a corresponding symbol, try dividing
the name into class and method names and searching the class and its
baseclasses. */
if (VEC_empty (symbolp, *symbols)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 345c20d..30f0dbe 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4164,6 +4164,16 @@ completion_list_add_name (const char *symname,
const char *sym_text, int sym_text_len,
const char *text, const char *word)
{
+ /* Skip over the redundant "(anonymous namespace)::" prefix on symbols within
+ the root anonymous namespace so that if the user is completing the name
+ FOO then we want to match it with the symbol (anonymous namespace)::FOOBAR
+ and to output FOOBAR in the completion list (C++ only). */
+
+ if (current_language->la_language == language_cplus
+ && cp_in_root_anonymous_namespace_p (symname)
+ && !cp_in_root_anonymous_namespace_p (sym_text))
+ symname += strlen (CP_ANONYMOUS_NAMESPACE_STR "::");
+
/* Clip symbols that cannot match. */
if (!compare_symbol_name (symname, sym_text, sym_text_len))
return;
--
2.2.0.rc1.23.gf570943
next reply other threads:[~2014-12-01 3:22 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-01 3:22 Patrick Palka [this message]
2014-12-01 7:17 ` Doug Evans
2014-12-07 23:33 ` Doug Evans
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=1417404096-16170-1-git-send-email-patrick@parcs.ath.cx \
--to=patrick@parcs.ath.cx \
--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