From 6dfbb909771e15460a5f8f6f246ad75ab993442d Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 24 Apr 2000 06:41:16 +0000 Subject: [PATCH] cp-tree.h (lang_decl): Remove pretty_function_p. * cp-tree.h (lang_decl): Remove pretty_function_p. (DECL_PRETTY_FUNCTION_P): Use TREE_LANG_FLAG_0, not a bit in the language-specific node. * decl.c (cp_make_fname_decl): Use build_decl, not build_lang_decl, to build the variables. (grokvardecl): Don't call build_lang_decl for local variables in templates. (grokdeclarator): Don't call build_lang_decl for local type declarations in templates. * lex.c (retrofit_lang_decl): Use ggc_alloc_obj to allocated zero'd memory, rather than calling memset. * pt.c: Include hashtab.h. (local_specializations): New variable. (retrieve_local_specialization): Use it. (register_local_specialization): Likewise. (tsubst_decl): Don't assume local variables have DECL_LANG_SPECIFIC. (instantiate_decl): Set up local_specializations. * Makefile.in (HTAB_H): New variable. From-SVN: r33369 --- gcc/cp/ChangeLog | 22 ++++++++++ gcc/cp/Makefile.in | 3 +- gcc/cp/cp-tree.h | 8 ++-- gcc/cp/decl.c | 17 +++----- gcc/cp/lex.c | 3 +- gcc/cp/pt.c | 104 ++++++++++++++++++++++++++------------------- 6 files changed, 95 insertions(+), 62 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 80d48a64823..3469de86aff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,25 @@ +2000-04-23 Mark Mitchell + + * cp-tree.h (lang_decl): Remove pretty_function_p. + (DECL_PRETTY_FUNCTION_P): Use TREE_LANG_FLAG_0, not a bit in the + language-specific node. + * decl.c (cp_make_fname_decl): Use build_decl, not + build_lang_decl, to build the variables. + (grokvardecl): Don't call build_lang_decl for local variables in + templates. + (grokdeclarator): Don't call build_lang_decl for local type + declarations in templates. + * lex.c (retrofit_lang_decl): Use ggc_alloc_obj to allocated + zero'd memory, rather than calling memset. + * pt.c: Include hashtab.h. + (local_specializations): New variable. + (retrieve_local_specialization): Use it. + (register_local_specialization): Likewise. + (tsubst_decl): Don't assume local variables have + DECL_LANG_SPECIFIC. + (instantiate_decl): Set up local_specializations. + * Makefile.in (HTAB_H): New variable. + 2000-04-23 Richard Henderson * typeck.c (c_expand_asm_operands): Restore the original diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 647c1fa06ed..e8a43fa10d0 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -210,6 +210,7 @@ PARSE_H = $(srcdir)/parse.h PARSE_C = $(srcdir)/parse.c EXPR_H = $(srcdir)/../expr.h ../insn-codes.h GGC_H = $(srcdir)/../ggc.h $(srcdir)/../varray.h +HTAB_H = $(srcdir)/../../include/hashtab.h parse.o : $(PARSE_C) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \ $(srcdir)/../except.h $(srcdir)/../output.h $(srcdir)/../system.h \ @@ -295,7 +296,7 @@ xref.o : xref.c $(CXX_TREE_H) $(srcdir)/../input.h \ $(srcdir)/../toplev.h pt.o : pt.c $(CXX_TREE_H) decl.h $(PARSE_H) lex.h \ $(srcdir)/../toplev.h $(GGC_H) $(RTL_H) \ - $(srcdir)/../except.h + $(srcdir)/../except.h $(HTAB_H) error.o : error.c $(CXX_TREE_H) \ $(srcdir)/../toplev.h errfn.o : errfn.c $(CXX_TREE_H) \ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d419e26027f..be683b23123 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA. */ AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR) SCOPE_BEGIN_P (in SCOPE_STMT) CTOR_BEGIN_P (in CTOR_STMT) + DECL_PRETTY_FUNCTION_P (in VAR_DECL) 1: IDENTIFIER_VIRTUAL_P. TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -1866,7 +1867,7 @@ struct lang_decl_flags unsigned static_function : 1; unsigned pure_virtual : 1; unsigned has_in_charge_parm_p : 1; - unsigned pretty_function_p : 1; + unsigned bitfield : 1; unsigned mutable_flag : 1; unsigned deferred : 1; @@ -1876,12 +1877,11 @@ struct lang_decl_flags unsigned not_really_extern : 1; unsigned needs_final_overrider : 1; - unsigned bitfield : 1; unsigned defined_in_class : 1; unsigned pending_inline_p : 1; unsigned global_ctor_p : 1; unsigned global_dtor_p : 1; - unsigned dummy : 3; + unsigned dummy : 4; tree context; @@ -2106,7 +2106,7 @@ struct lang_decl /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a template function. */ #define DECL_PRETTY_FUNCTION_P(NODE) \ - (DECL_LANG_SPECIFIC(NODE)->decl_flags.pretty_function_p) + (TREE_LANG_FLAG_0 (NODE)) /* The _TYPE context in which this _DECL appears. This field holds the class where a virtual function instance is actually defined. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f667fd52071..8a618b5662c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6550,7 +6550,7 @@ cp_make_fname_decl (id, name, type_dep) (build_qualified_type (char_type_node, TYPE_QUAL_CONST), domain); - decl = build_lang_decl (VAR_DECL, id, type); + decl = build_decl (VAR_DECL, id, type); TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; DECL_SOURCE_LINE (decl) = 0; @@ -8924,9 +8924,9 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) else context = NULL_TREE; - if (processing_template_decl) - /* If we're in a template, we need DECL_LANG_SPECIFIC so that - we can call push_template_decl. */ + if (processing_template_decl && context) + /* For global variables, declared in a template, we need the + full lang_decl. */ decl = build_lang_decl (VAR_DECL, declarator, type); else decl = build_decl (VAR_DECL, declarator, type); @@ -10917,14 +10917,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) decl = build_lang_decl (TYPE_DECL, declarator, type); } else - { - /* Make sure this typedef lives as long as its type, - since it might be used as a template parameter. */ - if (processing_template_decl) - decl = build_lang_decl (TYPE_DECL, declarator, type); - else - decl = build_decl (TYPE_DECL, declarator, type); - } + decl = build_decl (TYPE_DECL, declarator, type); /* If the user declares "typedef struct {...} foo" then the struct will have an anonymous name. Fill that name in now. diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index da03c742852..7dc6d308422 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -4977,8 +4977,7 @@ retrofit_lang_decl (t) else size = sizeof (struct lang_decl_flags); - ld = (struct lang_decl *) ggc_alloc (size); - memset (ld, 0, size); + ld = (struct lang_decl *) ggc_alloc_obj (size, 1); DECL_LANG_SPECIFIC (t) = ld; if (current_lang_name == lang_name_cplusplus) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a3d059d3070..bfad70f9611 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "defaults.h" #include "ggc.h" +#include "hashtab.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -73,6 +74,11 @@ static tree saved_trees; static varray_type inline_parm_levels; static size_t inline_parm_levels_used; +/* A map from local variable declarations in the body of the template + presently being instantiated to the corresponding instantiated + local variables. */ +static htab_t local_specializations; + #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free @@ -119,9 +125,9 @@ static tree build_template_parm_index PARAMS ((int, int, int, tree, tree)); static int inline_needs_template_parms PARAMS ((tree)); static void push_inline_template_parms_recursive PARAMS ((tree, int)); static tree retrieve_specialization PARAMS ((tree, tree)); -static tree retrieve_local_specialization PARAMS ((tree, tree)); +static tree retrieve_local_specialization PARAMS ((tree)); static tree register_specialization PARAMS ((tree, tree, tree)); -static tree register_local_specialization PARAMS ((tree, tree, tree)); +static tree register_local_specialization PARAMS ((tree, tree)); static int unregister_specialization PARAMS ((tree, tree)); static tree reduce_template_parm_level PARAMS ((tree, tree, int)); static tree build_template_decl PARAMS ((tree, tree)); @@ -709,16 +715,13 @@ retrieve_specialization (tmpl, args) return NULL_TREE; } -/* Like retrieve_speciailization, but for local declarations. FN is - the function in which we are looking for an instantiation. */ +/* Like retrieve_speciailization, but for local declarations. */ static tree -retrieve_local_specialization (tmpl, fn) +retrieve_local_specialization (tmpl) tree tmpl; - tree fn; { - tree s = purpose_member (fn, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); - return s ? TREE_VALUE (s) : NULL_TREE; + return (tree) htab_find (local_specializations, tmpl); } /* Returns non-zero iff DECL is a specialization of TMPL. */ @@ -885,18 +888,18 @@ unregister_specialization (spec, tmpl) return 0; } -/* Like register_specialization, but for local declarations. FN is - the function in which we are registering SPEC, an instantiation of - TMPL. */ +/* Like register_specialization, but for local declarations. We are + registering SPEC, an instantiation of TMPL. */ static tree -register_local_specialization (spec, tmpl, fn) +register_local_specialization (spec, tmpl) tree spec; tree tmpl; - tree fn; { - DECL_TEMPLATE_SPECIALIZATIONS (tmpl) - = tree_cons (fn, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); + void **slot; + + slot = htab_find_slot (local_specializations, tmpl, INSERT); + *slot = spec; return spec; } @@ -3307,10 +3310,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be provided in ARGLIST, or else trailing parameters must have default values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument - deduction for any unspecified trailing arguments. - - The resulting TREE_VEC is allocated on a temporary obstack, and - must be explicitly copied if it will be permanent. */ + deduction for any unspecified trailing arguments. */ static tree coerce_template_parms (parms, args, in_decl, @@ -5857,7 +5857,8 @@ tsubst_decl (t, args, type, in_decl) r = TYPE_NAME (type); break; } - else if (!DECL_LANG_SPECIFIC (t)) + else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM + || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM) { /* For a template type parameter, we don't have to do anything special. */ @@ -5874,28 +5875,33 @@ tsubst_decl (t, args, type, in_decl) tree spec; tree tmpl; tree ctx; + int local_p; - /* Nobody should be tsubst'ing into non-template variables. */ - my_friendly_assert (DECL_LANG_SPECIFIC (t) - && DECL_TEMPLATE_INFO (t) != NULL_TREE, 0); + /* Assume this is a non-local variable. */ + local_p = 0; if (TYPE_P (CP_DECL_CONTEXT (t))) ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, /*complain=*/1, in_decl, /*entering_scope=*/1); else - /* Subsequent calls to pushdecl will fill this in. */ - ctx = NULL_TREE; + { + /* Subsequent calls to pushdecl will fill this in. */ + ctx = NULL_TREE; + if (!DECL_NAMESPACE_SCOPE_P (t)) + local_p = 1; + } /* Check to see if we already have this specialization. */ - tmpl = DECL_TI_TEMPLATE (t); - gen_tmpl = most_general_template (tmpl); - argvec = tsubst (DECL_TI_ARGS (t), args, /*complain=*/1, in_decl); - if (ctx) - spec = retrieve_specialization (gen_tmpl, argvec); + if (!local_p) + { + tmpl = DECL_TI_TEMPLATE (t); + gen_tmpl = most_general_template (tmpl); + argvec = tsubst (DECL_TI_ARGS (t), args, /*complain=*/1, in_decl); + spec = retrieve_specialization (gen_tmpl, argvec); + } else - spec = retrieve_local_specialization (gen_tmpl, - current_function_decl); + spec = retrieve_local_specialization (t); if (spec) { @@ -5929,19 +5935,20 @@ tsubst_decl (t, args, type, in_decl) if (TREE_CODE (r) == VAR_DECL) DECL_DEAD_FOR_LOCAL (r) = 0; - /* A static data member declaration is always marked external - when it is declared in-class, even if an initializer is - present. We mimic the non-template processing here. */ - if (ctx) - DECL_EXTERNAL (r) = 1; + if (!local_p) + { + /* A static data member declaration is always marked + external when it is declared in-class, even if an + initializer is present. We mimic the non-template + processing here. */ + DECL_EXTERNAL (r) = 1; - DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE); - SET_DECL_IMPLICIT_INSTANTIATION (r); - if (ctx) - register_specialization (r, gen_tmpl, argvec); + register_specialization (r, gen_tmpl, argvec); + DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE); + SET_DECL_IMPLICIT_INSTANTIATION (r); + } else - register_local_specialization (r, gen_tmpl, - current_function_decl); + register_local_specialization (r, t); TREE_CHAIN (r) = NULL_TREE; if (TREE_CODE (r) == VAR_DECL && TREE_CODE (type) == VOID_TYPE) @@ -9616,6 +9623,13 @@ instantiate_decl (d, defer_ok) } else if (TREE_CODE (d) == FUNCTION_DECL) { + /* Set up the list of local specializations. */ + my_friendly_assert (local_specializations == NULL, 20000422); + local_specializations = htab_create (37, + htab_hash_pointer, + htab_eq_pointer, + NULL); + /* Set up context. */ start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED); store_parm_decls (); @@ -9628,6 +9642,10 @@ instantiate_decl (d, defer_ok) tsubst_expr (DECL_SAVED_TREE (code_pattern), args, /*complain=*/1, tmpl); + /* We don't need the local specializations any more. */ + htab_delete (local_specializations); + local_specializations = NULL; + /* Finish the function. */ expand_body (finish_function (0)); }