From a0ad3539f415e3f925691340ce389c0dc0819c91 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Thu, 22 Feb 2007 17:03:48 +0000 Subject: [PATCH] dwarf2out.c (add_AT_string): Call ggc_strdup once per string. * dwarf2out.c (add_AT_string): Call ggc_strdup once per string. (type_tag): Use lang_hooks.dwarf_name instead of DECL_NAME. * cp-tree.h (TFF_NO_OUTER_SCOPE): New formatting flag. * error.c (dump_aggr_type, dump_simple_decl, dump_decl, dump_function_decl): Guard emitting outer scopes by new flag. * cp-lang.c (cxx_dwarf_name): New function. (LANG_HOOKS_DWARF_NAME): Define to cxx_dwarf_name. * pt.c (classtype_mangled_name, mangle_class_name_for_template): Remove functions. (push_template_decl_real, lookup_template_class): Remove calls to above functions. From-SVN: r122230 --- gcc/ChangeLog | 8 ++- gcc/cp/ChangeLog | 13 +++++ gcc/cp/cp-lang.c | 14 +++++ gcc/cp/cp-tree.h | 5 +- gcc/cp/error.c | 22 ++++++-- gcc/cp/pt.c | 133 +---------------------------------------------- gcc/dwarf2out.c | 23 ++++++-- 7 files changed, 74 insertions(+), 144 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 15adfd335b44..0c8ccb90f291 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-02-22 Michael Matz PR debug/30898 @@ -5,7 +11,7 @@ (mem_loc_descriptor): Call it. 2007-02-22 Zdenek Dvorak - Ira Rosen + Ira Rosen * tree-data-ref.c (ptr_ptr_may_alias_p): Take alias sets into account. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c3263933a46a..63dddf944eb0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2007-02-22 Michael Matz + + PR c++/29433 + * cp-tree.h (TFF_UNQUALIFIED_NAME): New formatting flag. + * error.c (dump_aggr_type, dump_simple_decl, dump_decl, + dump_function_decl): Guard emitting outer scopes by new flag. + * cp-lang.c (cxx_dwarf_name): New function. + (LANG_HOOKS_DWARF_NAME): Define to cxx_dwarf_name. + * pt.c (classtype_mangled_name, mangle_class_name_for_template): + Remove functions. + (push_template_decl_real, lookup_template_class): Remove calls + to above functions. + 2007-02-19 Mark Mitchell * call.c (build_new_method_call): Ensure that explicit calls of diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 793046b3469d..507641c36bd5 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -36,6 +36,7 @@ Boston, MA 02110-1301, USA. */ enum c_language_kind c_language = clk_cxx; static void cp_init_ts (void); +static const char * cxx_dwarf_name (tree t, int verbosity); /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h; consequently, there should be very few hooks below. */ @@ -46,6 +47,8 @@ static void cp_init_ts (void); #define LANG_HOOKS_INIT cxx_init #undef LANG_HOOKS_DECL_PRINTABLE_NAME #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name +#undef LANG_HOOKS_DWARF_NAME +#define LANG_HOOKS_DWARF_NAME cxx_dwarf_name #undef LANG_HOOKS_FOLD_OBJ_TYPE_REF #define LANG_HOOKS_FOLD_OBJ_TYPE_REF cp_fold_obj_type_ref #undef LANG_HOOKS_INIT_TS @@ -138,6 +141,17 @@ cp_init_ts (void) } +static const char * +cxx_dwarf_name (tree t, int verbosity) +{ + gcc_assert (DECL_P (t)); + + if (verbosity >= 2) + return decl_as_string (t, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME); + + return cxx_printable_name (t, verbosity); +} + void finish_file (void) { diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b3857815c2a2..a070411e6253 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3647,7 +3647,9 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; template-declaration. TFF_TEMPLATE_NAME: show only template-name. TFF_EXPR_IN_PARENS: parenthesize expressions. - TFF_NO_FUNCTION_ARGUMENTS: don't show function arguments. */ + TFF_NO_FUNCTION_ARGUMENTS: don't show function arguments. + TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the + top-level entity. */ #define TFF_PLAIN_IDENTIFIER (0) #define TFF_SCOPE (1) @@ -3661,6 +3663,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; #define TFF_TEMPLATE_NAME (1 << 8) #define TFF_EXPR_IN_PARENS (1 << 9) #define TFF_NO_FUNCTION_ARGUMENTS (1 << 10) +#define TFF_UNQUALIFIED_NAME (1 << 11) /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM node. */ diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 6a0eed5e16b1..5779805d80ce 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -447,7 +447,10 @@ dump_aggr_type (tree t, int flags) && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); - dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); + + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); + flags &= ~TFF_UNQUALIFIED_NAME; if (tmplate) { /* Because the template names are mangled, we have to locate @@ -697,11 +700,14 @@ dump_simple_decl (tree t, tree type, int flags) { if (flags & TFF_DECL_SPECIFIERS) { - dump_type_prefix (type, flags); + dump_type_prefix (type, flags & ~TFF_UNQUALIFIED_NAME); pp_maybe_space (cxx_pp); } - if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX) + if (! (flags & TFF_UNQUALIFIED_NAME) + && (!DECL_INITIAL (t) + || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)) dump_scope (CP_DECL_CONTEXT (t), flags); + flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t)) dump_decl (DECL_NAME (t), flags); else @@ -763,7 +769,9 @@ dump_decl (tree t, int flags) pp_cxx_declaration (cxx_pp, t); else { - dump_scope (CP_DECL_CONTEXT (t), flags); + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (CP_DECL_CONTEXT (t), flags); + flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t) == NULL_TREE) pp_identifier (cxx_pp, ""); else @@ -998,7 +1006,9 @@ dump_function_decl (tree t, int flags) tree template_args = NULL_TREE; tree template_parms = NULL_TREE; int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; + int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME); + flags &= ~TFF_UNQUALIFIED_NAME; if (TREE_CODE (t) == TEMPLATE_DECL) t = DECL_TEMPLATE_RESULT (t); @@ -1040,7 +1050,9 @@ dump_function_decl (tree t, int flags) dump_type_prefix (TREE_TYPE (fntype), flags); /* Print the function name. */ - if (cname) + if (!do_outer_scope) + /* Nothing. */; + else if (cname) { dump_type (cname, flags); pp_cxx_colon_colon (cxx_pp); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 31ad46c50528..8ade0a095c5f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -106,8 +106,6 @@ static void add_pending_template (tree); static int push_tinst_level (tree); static void pop_tinst_level (void); static void reopen_tinst_level (tree); -static tree classtype_mangled_name (tree); -static char* mangle_class_name_for_template (const char *, tree, tree); static tree tsubst_initializer_list (tree, tree); static tree get_class_bindings (tree, tree, tree); static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, @@ -3349,14 +3347,7 @@ push_template_decl_real (tree decl, bool is_friend) info = tree_cons (tmpl, args, NULL_TREE); if (DECL_IMPLICIT_TYPEDEF_P (decl)) - { - SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); - if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL) - && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE - /* Don't change the name if we've already set it up. */ - && !IDENTIFIER_TEMPLATE (DECL_NAME (decl))) - DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl)); - } + SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); else if (DECL_LANG_SPECIFIC (decl)) DECL_TEMPLATE_INFO (decl) = info; @@ -4301,124 +4292,6 @@ comp_template_args (tree oldargs, tree newargs) return 1; } -/* Given class template name and parameter list, produce a user-friendly name - for the instantiation. */ - -static char * -mangle_class_name_for_template (const char* name, tree parms, tree arglist) -{ - static struct obstack scratch_obstack; - static char *scratch_firstobj; - int i, nparms; - - if (!scratch_firstobj) - gcc_obstack_init (&scratch_obstack); - else - obstack_free (&scratch_obstack, scratch_firstobj); - scratch_firstobj = (char *) obstack_alloc (&scratch_obstack, 1); - -#define ccat(C) obstack_1grow (&scratch_obstack, (C)); -#define cat(S) obstack_grow (&scratch_obstack, (S), strlen (S)) - - cat (name); - ccat ('<'); - nparms = TREE_VEC_LENGTH (parms); - arglist = INNERMOST_TEMPLATE_ARGS (arglist); - gcc_assert (nparms == TREE_VEC_LENGTH (arglist)); - for (i = 0; i < nparms; i++) - { - tree parm; - tree arg; - - parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - arg = TREE_VEC_ELT (arglist, i); - - if (parm == error_mark_node) - continue; - - if (i) - ccat (','); - - if (TREE_CODE (parm) == TYPE_DECL) - { - cat (type_as_string (arg, TFF_CHASE_TYPEDEF)); - continue; - } - else if (TREE_CODE (parm) == TEMPLATE_DECL) - { - if (TREE_CODE (arg) == TEMPLATE_DECL) - { - /* Already substituted with real template. Just output - the template name here */ - tree context = DECL_CONTEXT (arg); - if (context) - { - /* The template may be defined in a namespace, or - may be a member template. */ - gcc_assert (TREE_CODE (context) == NAMESPACE_DECL - || CLASS_TYPE_P (context)); - cat (decl_as_string (DECL_CONTEXT (arg), - TFF_PLAIN_IDENTIFIER)); - cat ("::"); - } - cat (IDENTIFIER_POINTER (DECL_NAME (arg))); - } - else - /* Output the parameter declaration. */ - cat (type_as_string (arg, TFF_CHASE_TYPEDEF)); - continue; - } - else - gcc_assert (TREE_CODE (parm) == PARM_DECL); - - /* No need to check arglist against parmlist here; we did that - in coerce_template_parms, called from lookup_template_class. */ - cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER)); - } - { - char *bufp = obstack_next_free (&scratch_obstack); - int offset = 0; - while (bufp[offset - 1] == ' ') - offset--; - obstack_blank_fast (&scratch_obstack, offset); - - /* B >, not B> */ - if (bufp[offset - 1] == '>') - ccat (' '); - } - ccat ('>'); - ccat ('\0'); - return (char *) obstack_base (&scratch_obstack); -} - -static tree -classtype_mangled_name (tree t) -{ - if (CLASSTYPE_TEMPLATE_INFO (t) - /* Specializations have already had their names set up in - lookup_template_class. */ - && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) - { - tree tmpl = most_general_template (CLASSTYPE_TI_TEMPLATE (t)); - - /* For non-primary templates, the template parameters are - implicit from their surrounding context. */ - if (PRIMARY_TEMPLATE_P (tmpl)) - { - tree name = DECL_NAME (tmpl); - char *mangled_name = mangle_class_name_for_template - (IDENTIFIER_POINTER (name), - DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - CLASSTYPE_TI_ARGS (t)); - tree id = get_identifier (mangled_name); - IDENTIFIER_TEMPLATE (id) = name; - return id; - } - } - - return TYPE_IDENTIFIER (t); -} - static void add_pending_template (tree d) { @@ -4965,10 +4838,6 @@ lookup_template_class (tree d1, the instantiation and exit above. */ tsubst_enum (template_type, t, arglist); - /* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO - is set up. */ - if (TREE_CODE (t) != ENUMERAL_TYPE) - DECL_NAME (type_decl) = classtype_mangled_name (t); if (is_partial_instantiation) /* If the type makes use of template parameters, the code that generates debugging information will crash. */ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 2bb68dc9cd85..3f2dbba930cd 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5039,9 +5039,15 @@ add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str) slot = htab_find_slot_with_hash (debug_str_hash, str, htab_hash_string (str), INSERT); if (*slot == NULL) - *slot = ggc_alloc_cleared (sizeof (struct indirect_string_node)); - node = (struct indirect_string_node *) *slot; - node->str = ggc_strdup (str); + { + node = (struct indirect_string_node *) + ggc_alloc_cleared (sizeof (struct indirect_string_node)); + node->str = ggc_strdup (str); + *slot = node; + } + else + node = (struct indirect_string_node *) *slot; + node->refcount++; attr.dw_attr = attr_kind; @@ -11251,10 +11257,17 @@ type_tag (tree type) involved. */ else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ! DECL_IGNORED_P (TYPE_NAME (type))) - t = DECL_NAME (TYPE_NAME (type)); + { + /* We want to be extra verbose. Don't call dwarf_name if + DECL_NAME isn't set. The default hook for decl_printable_name + doesn't like that, and in this context it's correct to return + 0, instead of "" or the like. */ + if (DECL_NAME (TYPE_NAME (type))) + name = lang_hooks.dwarf_name (TYPE_NAME (type), 2); + } /* Now get the name as a string, or invent one. */ - if (t != 0) + if (!name && t != 0) name = IDENTIFIER_POINTER (t); }