PR c++/6492
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Apr 2002 17:00:59 +0000 (17:00 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Apr 2002 17:00:59 +0000 (17:00 +0000)
* pt.c (tsubst_friend_class): If the friend has an explicit scope,
enter that scope before name lookup.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52951 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/pt.c

index 39c6bf6..7551df7 100644 (file)
@@ -4831,30 +4831,36 @@ tsubst_friend_class (friend_tmpl, args)
 {
   tree friend_type;
   tree tmpl;
+  tree context;
 
-  /* First, we look for a class template.  */
-  if (DECL_CONTEXT (friend_tmpl))
-    tmpl = friend_tmpl;
-  else
+  context = DECL_CONTEXT (friend_tmpl);
+
+  if (context)
     {
-      tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0); 
+      if (TREE_CODE (context) == NAMESPACE_DECL)
+       push_nested_namespace (context);
+      else
+       push_nested_class (context, 2);
+    }
 
-      /* But, if we don't find one, it might be because we're in a
-        situation like this:
+  /* First, we look for a class template.  */
+  tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0); 
 
-          template <class T>
-          struct S {
-            template <class U>
-            friend struct S;
-          };
+  /* But, if we don't find one, it might be because we're in a
+     situation like this:
 
-        Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
-        for `S<int>', not the TEMPLATE_DECL.  */
-      if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
-       {
-         tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
-         tmpl = maybe_get_template_decl_from_type_decl (tmpl);
-       }
+       template <class T>
+       struct S {
+        template <class U>
+        friend struct S;
+       };
+
+     Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
+     for `S<int>', not the TEMPLATE_DECL.  */
+  if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
+    {
+      tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
+      tmpl = maybe_get_template_decl_from_type_decl (tmpl);
     }
 
   if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl))
@@ -4865,12 +4871,15 @@ tsubst_friend_class (friend_tmpl, args)
         of course.  We only need the innermost template parameters
         because that is all that redeclare_class_template will look
         at.  */
-      tree parms 
-       = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
-                                args, tf_error | tf_warning);
-      if (!parms)
-        return error_mark_node;
-      redeclare_class_template (TREE_TYPE (tmpl), parms);
+      if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (friend_tmpl))
+         > TMPL_ARGS_DEPTH (args))
+       {
+         tree parms;
+         parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
+                                        args, tf_error | tf_warning);
+         redeclare_class_template (TREE_TYPE (tmpl), parms);
+       }
+
       friend_type = TREE_TYPE (tmpl);
     }
   else
@@ -4892,6 +4901,14 @@ tsubst_friend_class (friend_tmpl, args)
       friend_type = TREE_TYPE (pushdecl_top_level (tmpl));
     }
 
+  if (context) 
+    {
+      if (TREE_CODE (context) == NAMESPACE_DECL)
+       pop_nested_namespace (context);
+      else
+       pop_nested_class ();
+    }
+
   return friend_type;
 }