diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-10 13:44:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-10 13:44:22 +0000 |
commit | 1b08b196ac845675036ac78f3ac927d0a37f707c (patch) | |
tree | 1fbd923674e903831dc097fdb4fdfd64dd6e47b1 /lib/Sema/SemaTemplate.cpp | |
parent | 551c698530debaae81139c7c76a29fb762793362 (diff) |
Notes
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8cd7efbb1dba..1eea151a4ec8 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4020,6 +4020,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, } } // fallthrough + LLVM_FALLTHROUGH; } default: { // We have a template type parameter but the template argument @@ -7594,6 +7595,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, return false; } // Fall through + LLVM_FALLTHROUGH; case TSK_ExplicitInstantiationDeclaration: case TSK_ExplicitInstantiationDefinition: @@ -7620,6 +7622,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, return true; } + llvm_unreachable("The switch over PrevTSK must be exhaustive."); case TSK_ExplicitInstantiationDeclaration: switch (PrevTSK) { @@ -8955,7 +8958,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, // A member function [...] of a class template can be explicitly // instantiated from the member definition associated with its class // template. - UnresolvedSet<8> Matches; + UnresolvedSet<8> TemplateMatches; + FunctionDecl *NonTemplateMatch = nullptr; AttributeList *Attr = D.getDeclSpec().getAttributes().getList(); TemplateSpecCandidateSet FailedCandidates(D.getIdentifierLoc()); for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end(); @@ -8966,11 +8970,13 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, QualType Adjusted = adjustCCAndNoReturn(R, Method->getType(), /*AdjustExceptionSpec*/true); if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) { - Matches.clear(); - - Matches.addDecl(Method, P.getAccess()); - if (Method->getTemplateSpecializationKind() == TSK_Undeclared) - break; + if (Method->getPrimaryTemplate()) { + TemplateMatches.addDecl(Method, P.getAccess()); + } else { + // FIXME: Can this assert ever happen? Needs a test. + assert(!NonTemplateMatch && "Multiple NonTemplateMatches"); + NonTemplateMatch = Method; + } } } } @@ -9009,22 +9015,25 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, continue; } - Matches.addDecl(Specialization, P.getAccess()); + TemplateMatches.addDecl(Specialization, P.getAccess()); } - // Find the most specialized function template specialization. - UnresolvedSetIterator Result = getMostSpecialized( - Matches.begin(), Matches.end(), FailedCandidates, - D.getIdentifierLoc(), - PDiag(diag::err_explicit_instantiation_not_known) << Name, - PDiag(diag::err_explicit_instantiation_ambiguous) << Name, - PDiag(diag::note_explicit_instantiation_candidate)); - - if (Result == Matches.end()) - return true; + FunctionDecl *Specialization = NonTemplateMatch; + if (!Specialization) { + // Find the most specialized function template specialization. + UnresolvedSetIterator Result = getMostSpecialized( + TemplateMatches.begin(), TemplateMatches.end(), FailedCandidates, + D.getIdentifierLoc(), + PDiag(diag::err_explicit_instantiation_not_known) << Name, + PDiag(diag::err_explicit_instantiation_ambiguous) << Name, + PDiag(diag::note_explicit_instantiation_candidate)); + + if (Result == TemplateMatches.end()) + return true; - // Ignore access control bits, we don't need them for redeclaration checking. - FunctionDecl *Specialization = cast<FunctionDecl>(*Result); + // Ignore access control bits, we don't need them for redeclaration checking. + Specialization = cast<FunctionDecl>(*Result); + } // C++11 [except.spec]p4 // In an explicit instantiation an exception-specification may be specified, @@ -9379,6 +9388,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, } // Fall through to create a dependent typename type, from which we can recover // better. + LLVM_FALLTHROUGH; case LookupResult::NotFoundInCurrentInstantiation: // Okay, it's a member of an unknown instantiation. |