@@ -10124,8 +10124,9 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
1012410124 // instantiated from the member definition associated with its class
1012510125 // template.
1012610126 UnresolvedSet<8 > TemplateMatches;
10127- FunctionDecl *NonTemplateMatch = nullptr ;
10128- TemplateSpecCandidateSet FailedCandidates (D.getIdentifierLoc ());
10127+ OverloadCandidateSet NonTemplateMatches (D.getBeginLoc (),
10128+ OverloadCandidateSet::CSK_Normal);
10129+ TemplateSpecCandidateSet FailedTemplateCandidates (D.getIdentifierLoc ());
1012910130 for (LookupResult::iterator P = Previous.begin (), PEnd = Previous.end ();
1013010131 P != PEnd; ++P) {
1013110132 NamedDecl *Prev = *P;
@@ -10137,9 +10138,18 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
1013710138 if (Method->getPrimaryTemplate ()) {
1013810139 TemplateMatches.addDecl (Method, P.getAccess ());
1013910140 } else {
10140- // FIXME: Can this assert ever happen? Needs a test.
10141- assert (!NonTemplateMatch && " Multiple NonTemplateMatches" );
10142- NonTemplateMatch = Method;
10141+ OverloadCandidate &C = NonTemplateMatches.addCandidate ();
10142+ C.FoundDecl = P.getPair ();
10143+ C.Function = Method;
10144+ C.Viable = true ;
10145+ ConstraintSatisfaction S;
10146+ if (Method->getTrailingRequiresClause () &&
10147+ (CheckFunctionConstraints (Method, S, D.getIdentifierLoc (),
10148+ /* ForOverloadResolution=*/ true ) ||
10149+ !S.IsSatisfied )) {
10150+ C.Viable = false ;
10151+ C.FailureKind = ovl_fail_constraints_not_satisfied;
10152+ }
1014310153 }
1014410154 }
1014510155 }
@@ -10149,16 +10159,16 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
1014910159 if (!FunTmpl)
1015010160 continue ;
1015110161
10152- TemplateDeductionInfo Info (FailedCandidates .getLocation ());
10162+ TemplateDeductionInfo Info (FailedTemplateCandidates .getLocation ());
1015310163 FunctionDecl *Specialization = nullptr ;
1015410164 if (TemplateDeductionResult TDK = DeduceTemplateArguments (
1015510165 FunTmpl, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr ), R,
1015610166 Specialization, Info);
1015710167 TDK != TemplateDeductionResult::Success) {
1015810168 // Keep track of almost-matches.
10159- FailedCandidates .addCandidate ()
10160- . set ( P.getPair (), FunTmpl->getTemplatedDecl (),
10161- MakeDeductionFailureInfo (Context, TDK, Info));
10169+ FailedTemplateCandidates .addCandidate (). set (
10170+ P.getPair (), FunTmpl->getTemplatedDecl (),
10171+ MakeDeductionFailureInfo (Context, TDK, Info));
1016210172 (void )TDK;
1016310173 continue ;
1016410174 }
@@ -10172,7 +10182,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
1017210182 CUDA ().IdentifyTarget (Specialization,
1017310183 /* IgnoreImplicitHDAttr = */ true ) !=
1017410184 CUDA ().IdentifyTarget (D.getDeclSpec ().getAttributes ())) {
10175- FailedCandidates .addCandidate ().set (
10185+ FailedTemplateCandidates .addCandidate ().set (
1017610186 P.getPair (), FunTmpl->getTemplatedDecl (),
1017710187 MakeDeductionFailureInfo (
1017810188 Context, TemplateDeductionResult::CUDATargetMismatch, Info));
@@ -10182,12 +10192,40 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
1018210192 TemplateMatches.addDecl (Specialization, P.getAccess ());
1018310193 }
1018410194
10185- FunctionDecl *Specialization = NonTemplateMatch;
10195+ FunctionDecl *Specialization = nullptr ;
10196+ if (!NonTemplateMatches.empty ()) {
10197+ unsigned Msg = 0 ;
10198+ OverloadCandidateDisplayKind DisplayKind;
10199+ OverloadCandidateSet::iterator Best;
10200+ switch (NonTemplateMatches.BestViableFunction (*this , D.getIdentifierLoc (),
10201+ Best)) {
10202+ case OR_Success:
10203+ case OR_Deleted:
10204+ Specialization = cast<FunctionDecl>(Best->Function );
10205+ break ;
10206+ case OR_Ambiguous:
10207+ Msg = diag::err_explicit_instantiation_ambiguous;
10208+ DisplayKind = OCD_AmbiguousCandidates;
10209+ break ;
10210+ case OR_No_Viable_Function:
10211+ Msg = diag::err_explicit_instantiation_no_candidate;
10212+ DisplayKind = OCD_AllCandidates;
10213+ break ;
10214+ }
10215+ if (Msg) {
10216+ PartialDiagnostic Diag = PDiag (Msg) << Name;
10217+ NonTemplateMatches.NoteCandidates (
10218+ PartialDiagnosticAt (D.getIdentifierLoc (), Diag), *this , DisplayKind,
10219+ {});
10220+ return true ;
10221+ }
10222+ }
10223+
1018610224 if (!Specialization) {
1018710225 // Find the most specialized function template specialization.
1018810226 UnresolvedSetIterator Result = getMostSpecialized (
10189- TemplateMatches.begin (), TemplateMatches.end (), FailedCandidates,
10190- D.getIdentifierLoc (),
10227+ TemplateMatches.begin (), TemplateMatches.end (),
10228+ FailedTemplateCandidates, D.getIdentifierLoc (),
1019110229 PDiag (diag::err_explicit_instantiation_not_known) << Name,
1019210230 PDiag (diag::err_explicit_instantiation_ambiguous) << Name,
1019310231 PDiag (diag::note_explicit_instantiation_candidate));
0 commit comments