cp-tree.h (lang_decl): Remove pretty_function_p.
authorMark Mitchell <mark@codesourcery.com>
Mon, 24 Apr 2000 06:41:16 +0000 (06:41 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 24 Apr 2000 06:41:16 +0000 (06:41 +0000)
* 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
gcc/cp/Makefile.in
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/lex.c
gcc/cp/pt.c

index 80d48a6..3469de8 100644 (file)
@@ -1,3 +1,25 @@
+2000-04-23  Mark Mitchell  <mark@codesourcery.com>
+
+       * 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  <rth@cygnus.com>
 
        * typeck.c (c_expand_asm_operands): Restore the original
index 647c1fa..e8a43fa 100644 (file)
@@ -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) \
index d419e26..be683b2 100644 (file)
@@ -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. */
index f667fd5..8a618b5 100644 (file)
@@ -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.
index da03c74..7dc6d30 100644 (file)
@@ -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)
index a3d059d..bfad70f 100644 (file)
@@ -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));
     }