[PATCH] [RFC] PR c++/16874: make it easier to use anonymous namespaces

Patrick Palka patrick@parcs.ath.cx
Mon Dec 1 03:22:00 GMT 2014


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



More information about the Gdb-patches mailing list