diff options
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8485ecd3a3..35935f994c 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -8104,9 +8104,13 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, /// /// \param Previous the set of declarations that may be specialized by /// this function specialization. +/// +/// \param QualifiedFriend whether this is a lookup for a qualified friend +/// declaration with no explicit template argument list that might be +/// befriending a function template specialization. bool Sema::CheckFunctionTemplateSpecialization( FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs, - LookupResult &Previous) { + LookupResult &Previous, bool QualifiedFriend) { // The set of function template specializations that could match this // explicit function template specialization. UnresolvedSet<8> Candidates; @@ -8193,10 +8197,25 @@ bool Sema::CheckFunctionTemplateSpecialization( } } + // For a qualified friend declaration (with no explicit marker to indicate + // that a template specialization was intended), note all (template and + // non-template) candidates. + if (QualifiedFriend && Candidates.empty()) { + Diag(FD->getLocation(), diag::err_qualified_friend_no_match) + << FD->getDeclName() << FDLookupContext; + // FIXME: We should form a single candidate list and diagnose all + // candidates at once, to get proper sorting and limiting. + for (auto *OldND : Previous) { + if (auto *OldFD = dyn_cast<FunctionDecl>(OldND->getUnderlyingDecl())) + NoteOverloadCandidate(OldND, OldFD, FD->getType(), false); + } + FailedCandidates.NoteCandidates(*this, FD->getLocation()); + return true; + } + // Find the most specialized function template. UnresolvedSetIterator Result = getMostSpecialized( - Candidates.begin(), Candidates.end(), FailedCandidates, - FD->getLocation(), + Candidates.begin(), Candidates.end(), FailedCandidates, FD->getLocation(), PDiag(diag::err_function_template_spec_no_match) << FD->getDeclName(), PDiag(diag::err_function_template_spec_ambiguous) << FD->getDeclName() << (ExplicitTemplateArgs != nullptr), |