From 67daacbdc26c0fd73881b2327ce65e0d84ae5499 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 30 Mar 2012 16:20:47 +0000 Subject: [PATCH] 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., ). This hack brings us back to the passable-but-not-good state we had previously. llvm-svn: 153752 --- clang/lib/Sema/SemaTemplate.cpp | 8 ++++++-- clang/test/SemaTemplate/friend-template.cpp | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 34e5d722ca8f..ec11f8d22429 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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; } diff --git a/clang/test/SemaTemplate/friend-template.cpp b/clang/test/SemaTemplate/friend-template.cpp index 152df37d3db3..9c95fa0151c1 100644 --- a/clang/test/SemaTemplate/friend-template.cpp +++ b/clang/test/SemaTemplate/friend-template.cpp @@ -230,3 +230,16 @@ namespace PR10660 { template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}} }; } + +namespace rdar11147355 { + template + struct A { + template class B; + template template friend class A::B; + }; + + template template class A::B { + }; + + A::B ab; +}