diff mbox

[C++] Produce canonical names for debug info without changing normal pretty-printing (issue6215052)

Message ID 20120516200307.ED7281607AF@sterling.mtv.corp.google.com
State New
Headers show

Commit Message

Sterling Augustine May 16, 2012, 8:03 p.m. UTC
This patch adds new flags and defines such that the C++ decl pretty printer
prints both canonical dwarf names for decls without perturbing normal error
message output.

It addresses the issues with the earlier patches submitted as:

http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00516.html
http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00512.html

Which are withdrawn.

This patch requires no changes to the testsuite and does not produce
visible changes to gcc's output except to dwarf consumers, which will now
all agree on the names of functions.

Tested with a full bootstrap.

OK for mainline?

Sterling



2012-05-16   Sterling Augustine  <saugustine@google.com>

	* gcc/c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enumerator.
	* gcc/c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Check
	it at both the start and end of the function.
	* gcc/cp/cp-tree.h (TFF_MATCH_GNU_V3_DEMANGLER): Define and comment.
	* gcc/cp/error.c (dump_decl): Print appropriate string for anonymous
	namespace based on pp_c_flag_gnu_v3.
	(decl_as_string): Set cxx_pp->flags based on TFF_MATCH_GNU_V3_DEMANGLER.
	(lang_decl_name): Handle unnamed namespace decls.
	* gcc/cp/cp-lang.c (cxx_dwarf_name): Call decl_as_string for namespace
	decls.


--
This patch is available for review at http://codereview.appspot.com/6215052

Comments

Sterling Augustine May 21, 2012, 8:16 p.m. UTC | #1
On Wed, May 16, 2012 at 1:03 PM, Sterling Augustine
<saugustine@google.com> wrote:
> This patch adds new flags and defines such that the C++ decl pretty printer
> prints both canonical dwarf names for decls without perturbing normal error
> message output.
>
> It addresses the issues with the earlier patches submitted as:
>
> http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00516.html
> http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00512.html
>
> Which are withdrawn.
>
> This patch requires no changes to the testsuite and does not produce
> visible changes to gcc's output except to dwarf consumers, which will now
> all agree on the names of functions.
>
> Tested with a full bootstrap.
>
> OK for mainline?
>
> Sterling
>
>
>
> 2012-05-16   Sterling Augustine  <saugustine@google.com>
>
>        * gcc/c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enumerator.
>        * gcc/c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Check
>        it at both the start and end of the function.
>        * gcc/cp/cp-tree.h (TFF_MATCH_GNU_V3_DEMANGLER): Define and comment.
>        * gcc/cp/error.c (dump_decl): Print appropriate string for anonymous
>        namespace based on pp_c_flag_gnu_v3.
>        (decl_as_string): Set cxx_pp->flags based on TFF_MATCH_GNU_V3_DEMANGLER.
>        (lang_decl_name): Handle unnamed namespace decls.
>        * gcc/cp/cp-lang.c (cxx_dwarf_name): Call decl_as_string for namespace
>        decls.
>
> Index: gcc/c-family/c-pretty-print.c
> ===================================================================
> --- gcc/c-family/c-pretty-print.c       (revision 187603)
> +++ gcc/c-family/c-pretty-print.c       (working copy)
> @@ -446,8 +446,9 @@ pp_c_specifier_qualifier_list (c_pretty_printer *p
>  {
>   const enum tree_code code = TREE_CODE (t);
>
> -  if (TREE_CODE (t) != POINTER_TYPE)
> +  if (!(pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE)
>     pp_c_type_qualifier_list (pp, t);
> +
>   switch (code)
>     {
>     case REFERENCE_TYPE:
> @@ -494,6 +495,8 @@ pp_c_specifier_qualifier_list (c_pretty_printer *p
>       pp_simple_type_specifier (pp, t);
>       break;
>     }
> +  if ((pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE)
> +    pp_c_type_qualifier_list (pp, t);
>  }
>
>  /* parameter-type-list:
> Index: gcc/c-family/c-pretty-print.h
> ===================================================================
> --- gcc/c-family/c-pretty-print.h       (revision 187603)
> +++ gcc/c-family/c-pretty-print.h       (working copy)
> @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3.  If not see
>  typedef enum
>   {
>      pp_c_flag_abstract = 1 << 1,
> -     pp_c_flag_last_bit = 2
> +     pp_c_flag_last_bit = 2,
> +     pp_c_flag_gnu_v3 = 4
>   } pp_c_pretty_print_flags;
>
>
> Index: gcc/cp/error.c
> ===================================================================
> --- gcc/cp/error.c      (revision 187603)
> +++ gcc/cp/error.c      (working copy)
> @@ -1028,7 +1028,12 @@ dump_decl (tree t, int flags)
>            dump_scope (CP_DECL_CONTEXT (t), flags);
>          flags &= ~TFF_UNQUALIFIED_NAME;
>          if (DECL_NAME (t) == NULL_TREE)
> -           pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
> +            {
> +              if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3))
> +                pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
> +              else
> +                pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)"));
> +            }
>          else
>            pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
>        }
> @@ -2561,6 +2566,8 @@ decl_as_string (tree decl, int flags)
>  {
>   reinit_cxx_pp ();
>   pp_translate_identifiers (cxx_pp) = false;
> +  if (flags & TFF_MATCH_GNU_V3_DEMANGLER)
> +    pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3;
>   dump_decl (decl, flags);
>   return pp_formatted_text (cxx_pp);
>  }
> @@ -2596,6 +2603,9 @@ lang_decl_name (tree decl, int v, bool translate)
>
>   if (TREE_CODE (decl) == FUNCTION_DECL)
>     dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
> +  else if ((DECL_NAME (decl) == NULL_TREE)
> +           && TREE_CODE (decl) == NAMESPACE_DECL)
> +    dump_decl (decl, TFF_PLAIN_IDENTIFIER);
>   else
>     dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
>
> Index: gcc/cp/cp-lang.c
> ===================================================================
> --- gcc/cp/cp-lang.c    (revision 187603)
> +++ gcc/cp/cp-lang.c    (working copy)
> @@ -120,8 +120,14 @@ cxx_dwarf_name (tree t, int verbosity)
>   if (verbosity >= 2)
>     return decl_as_string (t,
>                           TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME
> -                          | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
> +                          | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS
> +                           | TFF_MATCH_GNU_V3_DEMANGLER);
>
> +  /* decl_as_string handles namespaces--especially anonymous ones--more
> +     appropriately for debugging than cxx_printable_name.  But
> +     cxx_printable_name handles templates and global ctors and dtors better.  */
> +  if (TREE_CODE (t) == NAMESPACE_DECL)
> +    return decl_as_string (t, TFF_MATCH_GNU_V3_DEMANGLER);
>   return cxx_printable_name (t, verbosity);
>  }
>
> Index: gcc/cp/cp-tree.h
> ===================================================================
> --- gcc/cp/cp-tree.h    (revision 187603)
> +++ gcc/cp/cp-tree.h    (working copy)
> @@ -4567,7 +4567,9 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
>    TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the
>        top-level entity.
>    TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments
> -       identical to their defaults.  */
> +       identical to their defaults.
> +   TFF_MATCH_GNU_V3_DEMANGLER: match the GNU v3 demangler's names for anonymous
> +       namespaces and order of type-qualifiers vs type-specifiers.  */
>
>  #define TFF_PLAIN_IDENTIFIER                   (0)
>  #define TFF_SCOPE                              (1)
> @@ -4583,6 +4585,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
>  #define TFF_NO_FUNCTION_ARGUMENTS              (1 << 10)
>  #define TFF_UNQUALIFIED_NAME                   (1 << 11)
>  #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12)
> +#define TFF_MATCH_GNU_V3_DEMANGLER             (1 << 13)
>
>  /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
>    node.  */
>
> --
> This patch is available for review at http://codereview.appspot.com/6215052

Gabriel,

Do you have an opinion on this version of the patch?

Sterling
Sterling Augustine May 29, 2012, 10:32 p.m. UTC | #2
On Wed, May 16, 2012 at 1:03 PM, Sterling Augustine
<saugustine@google.com> wrote:
> This patch adds new flags and defines such that the C++ decl pretty printer
> prints both canonical dwarf names for decls without perturbing normal error
> message output.
>
> It addresses the issues with the earlier patches submitted as:
>
> http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00516.html
> http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00512.html
>
> Which are withdrawn.
>
> This patch requires no changes to the testsuite and does not produce
> visible changes to gcc's output except to dwarf consumers, which will now
> all agree on the names of functions.
>
> Tested with a full bootstrap.
>
> OK for mainline?
>
> Sterling
>
>
>
> 2012-05-16   Sterling Augustine  <saugustine@google.com>
>
>        * gcc/c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enumerator.
>        * gcc/c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Check
>        it at both the start and end of the function.
>        * gcc/cp/cp-tree.h (TFF_MATCH_GNU_V3_DEMANGLER): Define and comment.
>        * gcc/cp/error.c (dump_decl): Print appropriate string for anonymous
>        namespace based on pp_c_flag_gnu_v3.
>        (decl_as_string): Set cxx_pp->flags based on TFF_MATCH_GNU_V3_DEMANGLER.
>        (lang_decl_name): Handle unnamed namespace decls.
>        * gcc/cp/cp-lang.c (cxx_dwarf_name): Call decl_as_string for namespace
>        decls.
>
> Index: gcc/c-family/c-pretty-print.c
> ===================================================================
> --- gcc/c-family/c-pretty-print.c       (revision 187603)
> +++ gcc/c-family/c-pretty-print.c       (working copy)
> @@ -446,8 +446,9 @@ pp_c_specifier_qualifier_list (c_pretty_printer *p
>  {
>   const enum tree_code code = TREE_CODE (t);
>
> -  if (TREE_CODE (t) != POINTER_TYPE)
> +  if (!(pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE)
>     pp_c_type_qualifier_list (pp, t);
> +
>   switch (code)
>     {
>     case REFERENCE_TYPE:
> @@ -494,6 +495,8 @@ pp_c_specifier_qualifier_list (c_pretty_printer *p
>       pp_simple_type_specifier (pp, t);
>       break;
>     }
> +  if ((pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE)
> +    pp_c_type_qualifier_list (pp, t);
>  }
>
>  /* parameter-type-list:
> Index: gcc/c-family/c-pretty-print.h
> ===================================================================
> --- gcc/c-family/c-pretty-print.h       (revision 187603)
> +++ gcc/c-family/c-pretty-print.h       (working copy)
> @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3.  If not see
>  typedef enum
>   {
>      pp_c_flag_abstract = 1 << 1,
> -     pp_c_flag_last_bit = 2
> +     pp_c_flag_last_bit = 2,
> +     pp_c_flag_gnu_v3 = 4
>   } pp_c_pretty_print_flags;
>
>
> Index: gcc/cp/error.c
> ===================================================================
> --- gcc/cp/error.c      (revision 187603)
> +++ gcc/cp/error.c      (working copy)
> @@ -1028,7 +1028,12 @@ dump_decl (tree t, int flags)
>            dump_scope (CP_DECL_CONTEXT (t), flags);
>          flags &= ~TFF_UNQUALIFIED_NAME;
>          if (DECL_NAME (t) == NULL_TREE)
> -           pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
> +            {
> +              if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3))
> +                pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
> +              else
> +                pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)"));
> +            }
>          else
>            pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
>        }
> @@ -2561,6 +2566,8 @@ decl_as_string (tree decl, int flags)
>  {
>   reinit_cxx_pp ();
>   pp_translate_identifiers (cxx_pp) = false;
> +  if (flags & TFF_MATCH_GNU_V3_DEMANGLER)
> +    pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3;
>   dump_decl (decl, flags);
>   return pp_formatted_text (cxx_pp);
>  }
> @@ -2596,6 +2603,9 @@ lang_decl_name (tree decl, int v, bool translate)
>
>   if (TREE_CODE (decl) == FUNCTION_DECL)
>     dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
> +  else if ((DECL_NAME (decl) == NULL_TREE)
> +           && TREE_CODE (decl) == NAMESPACE_DECL)
> +    dump_decl (decl, TFF_PLAIN_IDENTIFIER);
>   else
>     dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
>
> Index: gcc/cp/cp-lang.c
> ===================================================================
> --- gcc/cp/cp-lang.c    (revision 187603)
> +++ gcc/cp/cp-lang.c    (working copy)
> @@ -120,8 +120,14 @@ cxx_dwarf_name (tree t, int verbosity)
>   if (verbosity >= 2)
>     return decl_as_string (t,
>                           TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME
> -                          | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
> +                          | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS
> +                           | TFF_MATCH_GNU_V3_DEMANGLER);
>
> +  /* decl_as_string handles namespaces--especially anonymous ones--more
> +     appropriately for debugging than cxx_printable_name.  But
> +     cxx_printable_name handles templates and global ctors and dtors better.  */
> +  if (TREE_CODE (t) == NAMESPACE_DECL)
> +    return decl_as_string (t, TFF_MATCH_GNU_V3_DEMANGLER);
>   return cxx_printable_name (t, verbosity);
>  }
>
> Index: gcc/cp/cp-tree.h
> ===================================================================
> --- gcc/cp/cp-tree.h    (revision 187603)
> +++ gcc/cp/cp-tree.h    (working copy)
> @@ -4567,7 +4567,9 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
>    TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the
>        top-level entity.
>    TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments
> -       identical to their defaults.  */
> +       identical to their defaults.
> +   TFF_MATCH_GNU_V3_DEMANGLER: match the GNU v3 demangler's names for anonymous
> +       namespaces and order of type-qualifiers vs type-specifiers.  */
>
>  #define TFF_PLAIN_IDENTIFIER                   (0)
>  #define TFF_SCOPE                              (1)
> @@ -4583,6 +4585,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
>  #define TFF_NO_FUNCTION_ARGUMENTS              (1 << 10)
>  #define TFF_UNQUALIFIED_NAME                   (1 << 11)
>  #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12)
> +#define TFF_MATCH_GNU_V3_DEMANGLER             (1 << 13)
>
>  /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
>    node.  */
>
> --
> This patch is available for review at http://codereview.appspot.com/6215052

Ping?
Gabriel Dos Reis May 30, 2012, 9:15 p.m. UTC | #3
On Tue, May 29, 2012 at 5:32 PM, Sterling Augustine
<saugustine@google.com> wrote:

>> Index: gcc/c-family/c-pretty-print.h
>> ===================================================================
>> --- gcc/c-family/c-pretty-print.h       (revision 187603)
>> +++ gcc/c-family/c-pretty-print.h       (working copy)
>> @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3.  If not see
>>  typedef enum
>>   {
>>      pp_c_flag_abstract = 1 << 1,
>> -     pp_c_flag_last_bit = 2
>> +     pp_c_flag_last_bit = 2,
>> +     pp_c_flag_gnu_v3 = 4

"last bit" should really be last bit.  That means the value for
pp_c_flags_last_bits
should be 1 << 2 with the new addition.
Sterling Augustine May 30, 2012, 9:40 p.m. UTC | #4
On Wed, May 30, 2012 at 2:15 PM, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:
> On Tue, May 29, 2012 at 5:32 PM, Sterling Augustine
> <saugustine@google.com> wrote:
>
>>> Index: gcc/c-family/c-pretty-print.h
>>> ===================================================================
>>> --- gcc/c-family/c-pretty-print.h       (revision 187603)
>>> +++ gcc/c-family/c-pretty-print.h       (working copy)
>>> @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3.  If not see
>>>  typedef enum
>>>   {
>>>      pp_c_flag_abstract = 1 << 1,
>>> -     pp_c_flag_last_bit = 2
>>> +     pp_c_flag_last_bit = 2,
>>> +     pp_c_flag_gnu_v3 = 4
>
> "last bit" should really be last bit.  That means the value for
> pp_c_flags_last_bits
> should be 1 << 2 with the new addition.

Good catch. There is a single use of pp_c_flag_last_bit in
cxx-pretty-printer.h to define the first C++ flag like so:

 pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit


So shouldn't the enum look like this?

typedef enum
  {
     pp_c_flag_abstract = 1 << 1,
     pp_c_flag_gnu_v3 = 1 << 2,
     pp_c_flag_last_bit = 3
  } pp_c_pretty_print_flags;

Thanks,

Sterling
Gabriel Dos Reis May 31, 2012, 5:11 a.m. UTC | #5
On Wed, May 30, 2012 at 4:40 PM, Sterling Augustine
<saugustine@google.com> wrote:
> On Wed, May 30, 2012 at 2:15 PM, Gabriel Dos Reis
> <gdr@integrable-solutions.net> wrote:
>> On Tue, May 29, 2012 at 5:32 PM, Sterling Augustine
>> <saugustine@google.com> wrote:
>>
>>>> Index: gcc/c-family/c-pretty-print.h
>>>> ===================================================================
>>>> --- gcc/c-family/c-pretty-print.h       (revision 187603)
>>>> +++ gcc/c-family/c-pretty-print.h       (working copy)
>>>> @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3.  If not see
>>>>  typedef enum
>>>>   {
>>>>      pp_c_flag_abstract = 1 << 1,
>>>> -     pp_c_flag_last_bit = 2
>>>> +     pp_c_flag_last_bit = 2,
>>>> +     pp_c_flag_gnu_v3 = 4
>>
>> "last bit" should really be last bit.  That means the value for
>> pp_c_flags_last_bits
>> should be 1 << 2 with the new addition.
>
> Good catch. There is a single use of pp_c_flag_last_bit in
> cxx-pretty-printer.h to define the first C++ flag like so:
>
>  pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
>
>
> So shouldn't the enum look like this?
>
> typedef enum
>  {
>     pp_c_flag_abstract = 1 << 1,
>     pp_c_flag_gnu_v3 = 1 << 2,
>     pp_c_flag_last_bit = 3
>  } pp_c_pretty_print_flags;
>
> Thanks,
>
> Sterling

Yes, you are absolutely right.

-- Gaby
diff mbox

Patch

Index: gcc/c-family/c-pretty-print.c
===================================================================
--- gcc/c-family/c-pretty-print.c	(revision 187603)
+++ gcc/c-family/c-pretty-print.c	(working copy)
@@ -446,8 +446,9 @@  pp_c_specifier_qualifier_list (c_pretty_printer *p
 {
   const enum tree_code code = TREE_CODE (t);
 
-  if (TREE_CODE (t) != POINTER_TYPE)
+  if (!(pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE)
     pp_c_type_qualifier_list (pp, t);
+
   switch (code)
     {
     case REFERENCE_TYPE:
@@ -494,6 +495,8 @@  pp_c_specifier_qualifier_list (c_pretty_printer *p
       pp_simple_type_specifier (pp, t);
       break;
     }
+  if ((pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE)
+    pp_c_type_qualifier_list (pp, t);
 }
 
 /* parameter-type-list:
Index: gcc/c-family/c-pretty-print.h
===================================================================
--- gcc/c-family/c-pretty-print.h	(revision 187603)
+++ gcc/c-family/c-pretty-print.h	(working copy)
@@ -30,7 +30,8 @@  along with GCC; see the file COPYING3.  If not see
 typedef enum
   {
      pp_c_flag_abstract = 1 << 1,
-     pp_c_flag_last_bit = 2
+     pp_c_flag_last_bit = 2,
+     pp_c_flag_gnu_v3 = 4
   } pp_c_pretty_print_flags;
 
 
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 187603)
+++ gcc/cp/error.c	(working copy)
@@ -1028,7 +1028,12 @@  dump_decl (tree t, int flags)
 	    dump_scope (CP_DECL_CONTEXT (t), flags);
 	  flags &= ~TFF_UNQUALIFIED_NAME;
 	  if (DECL_NAME (t) == NULL_TREE)
-	    pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
+            {
+              if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3))
+                pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
+              else
+                pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)"));
+            }
 	  else
 	    pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
 	}
@@ -2561,6 +2566,8 @@  decl_as_string (tree decl, int flags)
 {
   reinit_cxx_pp ();
   pp_translate_identifiers (cxx_pp) = false;
+  if (flags & TFF_MATCH_GNU_V3_DEMANGLER)
+    pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3;
   dump_decl (decl, flags);
   return pp_formatted_text (cxx_pp);
 }
@@ -2596,6 +2603,9 @@  lang_decl_name (tree decl, int v, bool translate)
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
     dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
+  else if ((DECL_NAME (decl) == NULL_TREE)
+           && TREE_CODE (decl) == NAMESPACE_DECL)
+    dump_decl (decl, TFF_PLAIN_IDENTIFIER);
   else
     dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
 
Index: gcc/cp/cp-lang.c
===================================================================
--- gcc/cp/cp-lang.c	(revision 187603)
+++ gcc/cp/cp-lang.c	(working copy)
@@ -120,8 +120,14 @@  cxx_dwarf_name (tree t, int verbosity)
   if (verbosity >= 2)
     return decl_as_string (t,
 			   TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME
-			   | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
+			   | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS
+                           | TFF_MATCH_GNU_V3_DEMANGLER);
 
+  /* decl_as_string handles namespaces--especially anonymous ones--more
+     appropriately for debugging than cxx_printable_name.  But
+     cxx_printable_name handles templates and global ctors and dtors better.  */
+  if (TREE_CODE (t) == NAMESPACE_DECL)
+    return decl_as_string (t, TFF_MATCH_GNU_V3_DEMANGLER);
   return cxx_printable_name (t, verbosity);
 }
 
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 187603)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4567,7 +4567,9 @@  enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
    TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the
        top-level entity.
    TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments
-       identical to their defaults.  */
+       identical to their defaults.
+   TFF_MATCH_GNU_V3_DEMANGLER: match the GNU v3 demangler's names for anonymous
+       namespaces and order of type-qualifiers vs type-specifiers.  */
 
 #define TFF_PLAIN_IDENTIFIER			(0)
 #define TFF_SCOPE				(1)
@@ -4583,6 +4585,7 @@  enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
 #define TFF_NO_FUNCTION_ARGUMENTS		(1 << 10)
 #define TFF_UNQUALIFIED_NAME			(1 << 11)
 #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS	(1 << 12)
+#define TFF_MATCH_GNU_V3_DEMANGLER	        (1 << 13)
 
 /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
    node.  */