decl.c (add_decl_to_level): New function.
authorMark Mitchell <mark@codesourcery.com>
Tue, 17 Aug 1999 22:35:19 +0000 (22:35 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 17 Aug 1999 22:35:19 +0000 (22:35 +0000)
* decl.c (add_decl_to_level): New function.
(push_local_binding): Use it.
(find_binding): Fix typo in comment.
(pushdecl): Use add_decl_to_level.  Put templates on the
corresponding namespace-scope binding levels.
* dump.c (dequeue_and_dump): Print the specializations of a
template.
* pt.c (push_template_decl_real): Don't push a template multiple
times.

From-SVN: r28738

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/dump.c
gcc/cp/pt.c

index da75c334d448d209b37e6cd6db4d055fa32cf556..ee595ab50c00443076fc385139c9320bcc72e91f 100644 (file)
@@ -1,3 +1,15 @@
+1999-08-17  Mark Mitchell  <mark@codesourcery.com>
+
+       * decl.c (add_decl_to_level): New function.
+       (push_local_binding): Use it.
+       (find_binding): Fix typo in comment.
+       (pushdecl): Use add_decl_to_level.  Put templates on the
+       corresponding namespace-scope binding levels.
+       * dump.c (dequeue_and_dump): Print the specializations of a
+       template.
+       * pt.c (push_template_decl_real): Don't push a template multiple
+       times.
+
 1999-08-17  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (CALL_DECLARATOR_PARMS): New macro.
index d5fcbeae89d895cfde67f710ace5ac5da2de20d3..baf1a32cbf59d1002d7b0e6858feccbfe519bfb5 100644 (file)
@@ -189,6 +189,7 @@ static tree poplevel_class PROTO((void));
 static void warn_about_implicit_typename_lookup PROTO((tree, tree));
 static int walk_namespaces_r PROTO((tree, walk_namespaces_fn, void *));
 static int walk_globals_r PROTO((tree, void *));
+static void add_decl_to_level PROTO((tree, struct binding_level *));
 
 #if defined (DEBUG_CP_BINDING_LEVELS)
 static void indent PROTO((void));
@@ -1099,9 +1100,29 @@ add_binding (id, decl)
   return ok;
 }
 
-/* Bind DECL to ID in the current_binding_level.
-   If PUSH_USING is set in FLAGS, we know that DECL doesn't really belong
-   to this binding level, that it got here through a using-declaration.  */
+/* Add DECL to the list of things declared in B.  */
+
+static void
+add_decl_to_level (decl, b)
+     tree decl;
+     struct binding_level *b;
+{
+  /* Only things that will live forever should go in the global
+     binding level.  */
+  my_friendly_assert (!(b == global_binding_level 
+                       && !TREE_PERMANENT (decl)),
+                     19990817);
+
+  /* We build up the list in reverse order, and reverse it later if
+     necessary.  */
+  TREE_CHAIN (decl) = b->names;
+  b->names = decl;
+}
+
+/* Bind DECL to ID in the current_binding_level, assumed to be a local
+   binding level.  If PUSH_USING is set in FLAGS, we know that DECL
+   doesn't really belong to this binding level, that it got here
+   through a using-declaration.  */
 
 void
 push_local_binding (id, decl, flags)
@@ -1138,8 +1159,7 @@ push_local_binding (id, decl, flags)
 
   /* And put DECL on the list of things declared by the current
      binding level.  */
-  TREE_CHAIN (decl) = b->names;
-  b->names = decl;
+  add_decl_to_level (decl, b);
 }
 
 /* Bind DECL to ID in the class_binding_level.  Returns nonzero if the
@@ -2148,7 +2168,7 @@ find_binding (name, scope)
       my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
       if (BINDING_SCOPE (iter) == scope)
        {
-         /* Move binding found to the fron of the list, so
+         /* Move binding found to the front of the list, so
              subsequent lookups will find it faster. */
          if (prev)
            {
@@ -3955,7 +3975,12 @@ pushdecl (x)
            need_new_binding = 0;
        }
       else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
-       return push_overloaded_decl (x, PUSH_GLOBAL);
+       {
+         t = push_overloaded_decl (x, PUSH_GLOBAL);
+         if (t == x)
+           add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
+         return t;
+       }
 
       /* If declaring a type as a typedef, copy the type (unless we're
         at line 0), and install this TYPE_DECL as the new type's typedef
@@ -4189,15 +4214,7 @@ pushdecl (x)
     }
 
   if (need_new_binding)
-    {
-      /* Put decls on list in reverse order.
-        We will reverse them later if necessary.  */
-      TREE_CHAIN (x) = current_binding_level->names;
-      current_binding_level->names = x;
-      if (current_binding_level == global_binding_level
-         && !TREE_PERMANENT (x))
-       my_friendly_abort (124);
-    }
+    add_decl_to_level (x, current_binding_level);
 
   return x;
 }
index e04655264a8ca3f47a9bffc80d82007964ed1286..d67ab68867de93368cd4af580c883a75449fd110 100644 (file)
@@ -606,7 +606,7 @@ dequeue_and_dump (di)
       if (DECL_CONV_FN_P (t))
        dump_string (di, "conversion");
       if (dump_children_p)
-       dump_child ("body", DECL_INITIAL (t));
+       dump_child ("body", DECL_SAVED_TREE (t));
       break;
 
     case NAMESPACE_DECL:
@@ -618,6 +618,11 @@ dequeue_and_dump (di)
        dump_child ("dcls", cp_namespace_decls (t));
       break;
 
+    case TEMPLATE_DECL:
+      if (dump_children_p)
+       dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
+      break;
+
     case OVERLOAD:
       if (dump_children_p)
        {
index cf2050ab20d5eeee1382c6e26e4e61311110b7a4..924f03fad59e9be94fce683e3acb6bcc3530789e 100644 (file)
@@ -2385,6 +2385,7 @@ push_template_decl_real (decl, is_friend)
   tree ctx;
   int primary;
   int is_partial;
+  int new_template_p = 0;
 
   /* See if this is a partial specialization.  */
   is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl)
@@ -2449,7 +2450,8 @@ push_template_decl_real (decl, is_friend)
       else
        {
          tmpl = build_template_decl (decl, current_template_parms);
-         
+         new_template_p = 1;
+
          if (DECL_LANG_SPECIFIC (decl)
              && DECL_TEMPLATE_SPECIALIZATION (decl))
            {
@@ -2560,7 +2562,7 @@ push_template_decl_real (decl, is_friend)
      that we do not try to push a global template friend declared in a
      template class; such a thing may well depend on the template
      parameters of the class.  */
-  if (ctx 
+  if (new_template_p && !ctx 
       && !(is_friend && template_class_depth (current_class_type) > 0))
     tmpl = pushdecl_namespace_level (tmpl);