aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>2002-04-30 17:00:59 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-04-30 17:00:59 +0000
commit3e0ec82fa75231234279a846f1d3174d48f2ddcc (patch)
tree8ac961b42915337dce0c192c0975fede1238658f
parent30482eb0deaebc6d4241460e0626945816337f50 (diff)
downloadgcc-3e0ec82fa75231234279a846f1d3174d48f2ddcc.zip
gcc-3e0ec82fa75231234279a846f1d3174d48f2ddcc.tar.gz
gcc-3e0ec82fa75231234279a846f1d3174d48f2ddcc.tar.bz2
re PR c++/6492 (New boost regression (friends))
PR c++/6492 * pt.c (tsubst_friend_class): If the friend has an explicit scope, enter that scope before name lookup. From-SVN: r52951
-rw-r--r--gcc/cp/pt.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 39c6bf6..7551df7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
}