diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-22 02:13:50 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-22 02:13:50 +0000 |
| commit | e85e1766005ef4510d388f99e5084259b327c594 (patch) | |
| tree | d6b2054462681d218d3e7f8c465e28e15753cefb /clang/lib | |
| parent | 4304101fb2991826b13cfd68a5d9798595906d04 (diff) | |
| download | bcm5719-llvm-e85e1766005ef4510d388f99e5084259b327c594.tar.gz bcm5719-llvm-e85e1766005ef4510d388f99e5084259b327c594.zip | |
PR12585: When processing a friend template inside a class template, don't
pretend there was no previous declaration -- that can lead us to injecting
a class template (with no access specifier) into a class scope. Instead,
just avoid the problematic checks.
llvm-svn: 155303
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index f1581e0c349..d4b09753d30 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -969,20 +969,15 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, PrevDecl = (*Previous.begin())->getUnderlyingDecl(); } } - - if (CurContext->isDependentContext() && PrevClassTemplate) { - // If this is a dependent context, we don't want to link the friend - // class template to the template in scope, because that would perform - // checking of the template parameter lists that can't be performed - // until the outer context is instantiated. - PrevDecl = PrevClassTemplate = 0; - } } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S)) PrevDecl = PrevClassTemplate = 0; if (PrevClassTemplate) { - // Ensure that the template parameter lists are compatible. - if (!TemplateParameterListsAreEqual(TemplateParams, + // Ensure that the template parameter lists are compatible. Skip this check + // for a friend in a dependent context: the template parameter list itself + // could be dependent. + if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && + !TemplateParameterListsAreEqual(TemplateParams, PrevClassTemplate->getTemplateParameters(), /*Complain=*/true, TPL_TemplateMatch)) @@ -1031,8 +1026,10 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // Check the template parameter list of this declaration, possibly // merging in the template parameter list from the previous class - // template declaration. - if (CheckTemplateParameterList(TemplateParams, + // template declaration. Skip this check for a friend in a dependent + // context, because the template parameter list might be dependent. + if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && + CheckTemplateParameterList(TemplateParams, PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0, (SS.isSet() && SemanticContext && SemanticContext->isRecord() && @@ -1044,9 +1041,9 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (SS.isSet()) { // If the name of the template was qualified, we must be defining the // template out-of-line. - if (!SS.isInvalid() && !Invalid && !PrevClassTemplate && - !(TUK == TUK_Friend && CurContext->isDependentContext())) { - Diag(NameLoc, diag::err_member_def_does_not_match) + if (!SS.isInvalid() && !Invalid && !PrevClassTemplate) { + Diag(NameLoc, TUK == TUK_Friend ? diag::err_friend_decl_does_not_match + : diag::err_member_def_does_not_match) << Name << SemanticContext << SS.getRange(); Invalid = true; } |

