[17/24] pdbout: Prepend namespaces to struct and function names.

Message ID 20210320162652.23346-17-mark@harmstone.com
State New
Headers show
Series
  • [01/24] Add -gcodeview debugging option
Related show

Commit Message

Mark Harmstone March 20, 2021, 4:26 p.m.
---
 gcc/pdbout.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 91 insertions(+), 2 deletions(-)

-- 
2.26.2

Patch

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;
 }