Commit 3e0ec82f by Mark Mitchell

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
parent 30482eb0
...@@ -4831,30 +4831,36 @@ tsubst_friend_class (friend_tmpl, args) ...@@ -4831,30 +4831,36 @@ tsubst_friend_class (friend_tmpl, args)
{ {
tree friend_type; tree friend_type;
tree tmpl; tree tmpl;
tree context;
/* First, we look for a class template. */ context = DECL_CONTEXT (friend_tmpl);
if (DECL_CONTEXT (friend_tmpl))
tmpl = friend_tmpl; if (context)
else
{ {
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 /* First, we look for a class template. */
situation like this: tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
template <class T> /* But, if we don't find one, it might be because we're in a
struct S { situation like this:
template <class U>
friend struct S;
};
Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL template <class T>
for `S<int>', not the TEMPLATE_DECL. */ struct S {
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) template <class U>
{ friend struct S;
tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1); };
tmpl = maybe_get_template_decl_from_type_decl (tmpl);
} 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)) if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl))
...@@ -4865,12 +4871,15 @@ tsubst_friend_class (friend_tmpl, args) ...@@ -4865,12 +4871,15 @@ tsubst_friend_class (friend_tmpl, args)
of course. We only need the innermost template parameters of course. We only need the innermost template parameters
because that is all that redeclare_class_template will look because that is all that redeclare_class_template will look
at. */ at. */
tree parms if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (friend_tmpl))
= tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl), > TMPL_ARGS_DEPTH (args))
args, tf_error | tf_warning); {
if (!parms) tree parms;
return error_mark_node; parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
redeclare_class_template (TREE_TYPE (tmpl), parms); args, tf_error | tf_warning);
redeclare_class_template (TREE_TYPE (tmpl), parms);
}
friend_type = TREE_TYPE (tmpl); friend_type = TREE_TYPE (tmpl);
} }
else else
...@@ -4892,6 +4901,14 @@ tsubst_friend_class (friend_tmpl, args) ...@@ -4892,6 +4901,14 @@ tsubst_friend_class (friend_tmpl, args)
friend_type = TREE_TYPE (pushdecl_top_level (tmpl)); 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; return friend_type;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment