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