aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-04-22 02:13:50 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-04-22 02:13:50 +0000
commit6e21b16ab226959341b85e16060fd81f71cee628 (patch)
treee9c999c5b86132685f230ee4ea11b36e32471fa7 /lib/Sema/SemaTemplate.cpp
parentbc356d0aa9c25c0831fa0ae9830b5e5e4be23b0a (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155303 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp27
1 files changed, 12 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f1581e0c34..d4b09753d3 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/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;
}