* cp-tree.h (push_nested_namespace): Declare.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 May 1999 14:26:55 +0000 (14:26 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 May 1999 14:26:55 +0000 (14:26 +0000)
(pop_nested_namespace): Likewise.
* decl.c (push_nested_namespace): New function.
(pop_nested_namespace): Likewise.
* pt.c (instantiate_class_template): Use them.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.ns/ns18.C [new file with mode: 0644]

index f0b989c..7623f18 100644 (file)
@@ -1,6 +1,12 @@
 1999-05-22  Mark Mitchell  <mark@codesourcery.com>
 
-       * tree.c (mapcar): Handle LVALUE_EXPR.
+       * cp-tree.h (push_nested_namespace): Declare.
+       (pop_nested_namespace): Likewise.
+       * decl.c (push_nested_namespace): New function.
+       (pop_nested_namespace): Likewise.
+       * pt.c (instantiate_class_template): Use them.
+
+       * tree.c (mapcar): Handle NON_LVALUE_EXPR.
 
        * cp-tree.h (cplus_expand_constant): Declare.
        * cvt.c (convert_to_pointer): Expand PTRMEM_CSTs when they're
index ec5ef45..a482824 100644 (file)
@@ -2781,6 +2781,8 @@ extern void print_binding_stack                   PROTO((void));
 extern void print_binding_level                        PROTO((struct binding_level *));
 extern void push_namespace                     PROTO((tree));
 extern void pop_namespace                      PROTO((void));
+extern void push_nested_namespace              PROTO((tree));
+extern void pop_nested_namespace               PROTO((tree));
 extern void maybe_push_to_top_level            PROTO((int));
 extern void push_to_top_level                  PROTO((void));
 extern void pop_from_top_level                 PROTO((void));
index dd2dbb7..2308e4c 100644 (file)
@@ -2396,6 +2396,38 @@ pop_namespace ()
   suspend_binding_level ();
 }
 
+/* Push into the scope of the namespace NS, even if it is deeply
+   nested within another namespace.  */
+
+void
+push_nested_namespace (ns)
+     tree ns;
+{
+  if (ns == global_namespace)
+    push_to_top_level ();
+  else
+    {
+      push_nested_namespace (CP_DECL_CONTEXT (ns));
+      push_namespace (DECL_NAME (ns));
+    }
+}
+
+/* Pop back from the scope of the namespace NS, which was previously
+   entered with push_nested_namespace.  */
+     
+void
+pop_nested_namespace (ns)
+     tree ns;
+{
+  while (ns != global_namespace)
+    {
+      pop_namespace ();
+      ns = CP_DECL_CONTEXT (ns);
+    }
+
+  pop_from_top_level ();
+}
+
 \f
 /* Subroutines for reverting temporarily to top-level for instantiation
    of templates and such.  We actually need to clear out the class- and
index 6db901c..8c80173 100644 (file)
@@ -5079,11 +5079,16 @@ instantiate_class_template (type)
        new_friend_type = tsubst (friend_type, args, /*complain=*/1,
                                  NULL_TREE);
       else 
-       /* The call to xref_tag_from_type does injection for friend
-          classes.  */
-       new_friend_type = 
-         xref_tag_from_type (friend_type, NULL_TREE, 1);
+       {
+         tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
 
+         /* The call to xref_tag_from_type does injection for friend
+            classes.  */
+         push_nested_namespace (ns);
+         new_friend_type = 
+           xref_tag_from_type (friend_type, NULL_TREE, 1);
+         pop_nested_namespace (ns);
+       }
 
       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
        /* Trick make_friend_class into realizing that the friend
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns18.C b/gcc/testsuite/g++.old-deja/g++.ns/ns18.C
new file mode 100644 (file)
index 0000000..445ef6b
--- /dev/null
@@ -0,0 +1,30 @@
+// Build don't link:
+// Origin: Theo Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+namespace Bname {
+  class B;
+}
+
+template <class T>
+class A {
+  friend class Bname::B;
+  static const int a = 1;
+public:
+  A() { }
+};
+
+namespace Bname {
+  class B {
+       int a;
+  public:
+       template<class T>
+       B(const T&):a(T::a) { }
+  };
+}
+
+int
+main()
+{
+  A<int> a;
+  Bname::B b(a);
+}