diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 935264cb8cc..dd116326711 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -8003,17 +8003,34 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, // the correct context. DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext(); LookupResult::Filter F = Previous.makeFilter(); + enum DiscardReason { NotAFunctionTemplate, NotAMemberOfEnclosing }; + SmallVector<std::pair<DiscardReason, Decl *>, 8> DiscardedCandidates; while (F.hasNext()) { NamedDecl *D = F.next()->getUnderlyingDecl(); - if (!isa<FunctionTemplateDecl>(D) || - !FDLookupContext->InEnclosingNamespaceSetOf( - D->getDeclContext()->getRedeclContext())) + if (!isa<FunctionTemplateDecl>(D)) { F.erase(); + DiscardedCandidates.push_back(std::make_pair(NotAFunctionTemplate, D)); + continue; + } + + if (!FDLookupContext->InEnclosingNamespaceSetOf( + D->getDeclContext()->getRedeclContext())) { + F.erase(); + DiscardedCandidates.push_back(std::make_pair(NotAMemberOfEnclosing, D)); + continue; + } } F.done(); - // Should this be diagnosed here? - if (Previous.empty()) return true; + if (Previous.empty()) { + Diag(FD->getLocation(), + diag::err_dependent_function_template_spec_no_match); + for (auto &P : DiscardedCandidates) + Diag(P.second->getLocation(), + diag::note_dependent_function_template_spec_discard_reason) + << P.first; + return true; + } FD->setDependentTemplateSpecialization(Context, Previous.asUnresolvedSet(), ExplicitTemplateArgs); |