If we encounter a friend class template for which we cannot resolve

the nested-name-specifier (e.g., because it is dependent), do not
error even though we can't represent it in the AST at this point.

This is a horrible, horrible hack. The actual feature we still need to
implement (for C++98!) is covered by PR12292. However, we used to
silently accept this code, so when we recently started rejecting it we
caused some regressions (e.g., <rdar://problem/11147355>). This hack
brings us back to the passable-but-not-good state we had previously.

llvm-svn: 153752
This commit is contained in:
Douglas Gregor 2012-03-30 16:20:47 +00:00
parent 22fe3171ee
commit 67daacbdc2
2 changed files with 19 additions and 2 deletions

View File

@ -872,8 +872,12 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (SS.isNotEmpty() && !SS.isInvalid()) {
SemanticContext = computeDeclContext(SS, true);
if (!SemanticContext) {
Diag(NameLoc, diag::err_template_qualified_declarator_no_match)
<< SS.getScopeRep() << SS.getRange();
// FIXME: Horrible, horrible hack! We can't currently represent this
// in the AST, and historically we have just ignored such friend
// class templates, so don't complain here.
if (TUK != TUK_Friend)
Diag(NameLoc, diag::err_template_qualified_declarator_no_match)
<< SS.getScopeRep() << SS.getRange();
return true;
}

View File

@ -230,3 +230,16 @@ namespace PR10660 {
template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
};
}
namespace rdar11147355 {
template <class T>
struct A {
template <class U> class B;
template <class S> template <class U> friend class A<S>::B;
};
template <class S> template <class U> class A<S>::B {
};
A<double>::B<double> ab;
}