From 61fc8c9e2b6e2ca08ebd97384ca26b1f9b125605 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sat, 22 May 1999 14:26:55 +0000 Subject: [PATCH] cp-tree.h (push_nested_namespace): Declare. * 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. From-SVN: r27103 --- gcc/cp/ChangeLog | 8 +++++- gcc/cp/cp-tree.h | 2 ++ gcc/cp/decl.c | 32 ++++++++++++++++++++++++ gcc/cp/pt.c | 13 +++++++--- gcc/testsuite/g++.old-deja/g++.ns/ns18.C | 30 ++++++++++++++++++++++ 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.ns/ns18.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f0b989c4a92..7623f188722 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,12 @@ 1999-05-22 Mark Mitchell - * 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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ec5ef45ba72..a482824c15e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dd2dbb754b0..2308e4c4b7e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 (); +} + /* Subroutines for reverting temporarily to top-level for instantiation of templates and such. We actually need to clear out the class- and diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6db901c9299..8c8017356b8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 00000000000..445ef6bc0f2 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.ns/ns18.C @@ -0,0 +1,30 @@ +// Build don't link: +// Origin: Theo Papadopoulo + +namespace Bname { + class B; +} + +template +class A { + friend class Bname::B; + static const int a = 1; +public: + A() { } +}; + +namespace Bname { + class B { + int a; + public: + template + B(const T&):a(T::a) { } + }; +} + +int +main() +{ + A a; + Bname::B b(a); +} -- 2.30.2