---
 gcc/pdbout.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 91 insertions(+), 2 deletions(-)

diff --git a/gcc/pdbout.c b/gcc/pdbout.c
index d3f251f22d2..fb40f066bd9 100644
--- a/gcc/pdbout.c
+++ b/gcc/pdbout.c
@@ -1484,24 +1484,113 @@ pdbout_finish (const char *filename ATTRIBUTE_UNUSED)
   write_pdb_type_section ();
 }
 
-/* For a tree t, construct the name. */
+/* For a tree t, construct the name - namespaces, plus the
+ * base name of the tree. */
 static char *
 get_tree_name (tree t)
 {
   char *name;
+  tree ns;
+
+  static const char anon_ns[] = "<anonymous>";
 
   if (TREE_CODE (t) == FUNCTION_DECL)
     name = xstrdup (IDENTIFIER_POINTER (DECL_NAME (t)));
   else if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE)
     name = xstrdup (IDENTIFIER_POINTER (TYPE_NAME (t)));
   else if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
-    && IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)))[0] != '.')
+          && IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)))[0] != '.')
     name = xstrdup (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))));
   else if (DECL_NAME (t) && TREE_CODE (DECL_NAME (t)) == IDENTIFIER_NODE)
     name = xstrdup (IDENTIFIER_POINTER (DECL_NAME (t)));
   else
     return NULL;
 
+  /* Prepend any namespaces, if present */
+
+  if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
+    ns = DECL_CONTEXT (TYPE_NAME (t));
+  else if (DECL_NAME (t))
+    ns = DECL_CONTEXT (t);
+  else
+    ns = NULL;
+
+  if (ns)
+    {
+      if (TREE_CODE (ns) == NAMESPACE_DECL)
+       {
+         tree orig_ns = ns;
+         size_t ns_len = 0;
+
+         while (ns && TREE_CODE (ns) == NAMESPACE_DECL)
+           {
+             if (DECL_NAME (ns))
+               ns_len += strlen (IDENTIFIER_POINTER (DECL_NAME (ns))) + 2;
+             else
+               ns_len += sizeof (anon_ns) - 1 + 2;
+
+             ns = DECL_CONTEXT (ns);
+           }
+
+         if (ns_len > 0)
+           {
+             char *tmp, *s;
+             size_t name_len = strlen (name);
+
+             tmp = (char *) xmalloc (name_len + ns_len + 1);
+             memcpy (&tmp[ns_len], name, name_len + 1);
+             free (name);
+             name = tmp;
+
+             ns = orig_ns;
+             s = &name[ns_len];
+
+             while (ns && TREE_CODE (ns) == NAMESPACE_DECL)
+               {
+                 size_t len;
+
+                 s -= 2;
+                 memcpy (s, "::", 2);
+
+                 if (DECL_NAME (ns))
+                   {
+                     len = strlen (IDENTIFIER_POINTER (DECL_NAME (ns)));
+                     s -= len;
+                     memcpy (s, IDENTIFIER_POINTER (DECL_NAME (ns)), len);
+                   }
+                 else
+                   {
+                     s -= sizeof (anon_ns) - 1;
+                     memcpy (s, anon_ns, sizeof (anon_ns) - 1);
+                   }
+
+                 ns = DECL_CONTEXT (ns);
+               }
+           }
+       }
+      else if (TREE_CODE (ns) == RECORD_TYPE
+              || TREE_CODE (ns) == FUNCTION_DECL)
+       {
+         char *s = get_tree_name (ns);
+         char *tmp;
+         size_t name_len = strlen (name);
+         size_t s_len = s ? strlen (s) : 1;
+
+         tmp = (char *) xmalloc (name_len + s_len + 3);
+         memcpy (&tmp[s_len + 2], name, name_len + 1);
+         free (name);
+         name = tmp;
+
+         if (s)
+           memcpy (name, s, s_len);
+         else
+           name[0] = '?';
+
+         name[s_len] = ':';
+         name[s_len + 1] = ':';
+       }
+    }
+
   return name;
 }
 
-- 
2.26.2

Reply via email to