|
@@ -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),
|