aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-26 03:41:46 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-26 03:41:46 +0000
commitc5df30fe345613bacd6810f3d7ec02e4b9ac853f (patch)
treef1982a062d25796d7e67678289288f2c7e626de6
parentbb36ba488b7c6185546f8696447530ebfd296df7 (diff)
Use Sema::getMostSpecialized to eliminate a redundant implementation of the most-specialized function template
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82840 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplate.cpp69
1 files changed, 11 insertions, 58 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index e0c1afbf67..d5fb7e82a8 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -2953,65 +2953,18 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
}
}
- if (Candidates.empty()) {
- Diag(FD->getLocation(), diag::err_function_template_spec_no_match)
- << FD->getDeclName();
- // FIXME: Print the almost-ran candidates.
+ // Find the most specialized function template.
+ FunctionDecl *Specialization = getMostSpecialized(Candidates.data(),
+ Candidates.size(),
+ TPOC_Other,
+ FD->getLocation(),
+ PartialDiagnostic(diag::err_function_template_spec_no_match)
+ << FD->getDeclName(),
+ PartialDiagnostic(diag::err_function_template_spec_ambiguous)
+ << FD->getDeclName() << HasExplicitTemplateArgs,
+ PartialDiagnostic(diag::note_function_template_spec_matched));
+ if (!Specialization)
return true;
- }
-
- if (Candidates.size() > 1) {
- // C++ [temp.func.order]p1:
- // Partial ordering of overloaded function template declarations is used
- // [...] when [...] an explicit specialization (14.7.3) refers to a
- // function template specialization.
- CandidateSet::iterator Best = Candidates.begin();
- for (CandidateSet::iterator C = Best + 1, CEnd = Candidates.end();
- C != CEnd; ++C) {
- if (getMoreSpecializedTemplate((*Best)->getPrimaryTemplate(),
- (*C)->getPrimaryTemplate(),
- TPOC_Other)
- == (*C)->getPrimaryTemplate())
- Best = C;
- }
-
- bool Ambiguous = false;
- for (CandidateSet::iterator C = Candidates.begin(), CEnd = Candidates.end();
- C != CEnd; ++C) {
- if (C != Best &&
- getMoreSpecializedTemplate((*Best)->getPrimaryTemplate(),
- (*C)->getPrimaryTemplate(),
- TPOC_Other)
- != (*Best)->getPrimaryTemplate()) {
- Ambiguous = true;
- break;
- }
- }
-
- if (Ambiguous) {
- // Partial ordering was ambiguous.
- Diag(FD->getLocation(), diag::err_function_template_spec_ambiguous)
- << FD->getDeclName()
- << HasExplicitTemplateArgs;
-
- for (CandidateSet::iterator C = Candidates.begin(),
- CEnd = Candidates.end();
- C != CEnd; ++C)
- Diag((*C)->getLocation(), diag::note_function_template_spec_matched)
- << getTemplateArgumentBindingsText(
- (*C)->getPrimaryTemplate()->getTemplateParameters(),
- *(*C)->getTemplateSpecializationArgs());
-
- return true;
- }
-
- // Move the best candidate to the front of the candidates list.
- std::swap(*Best, Candidates.front());
- }
-
- // The first candidate is a prior declaration of the function template
- // specialization we're declared here, which we may have created above.
- FunctionDecl *Specialization = Candidates.front();
// FIXME: Check if the prior specialization has a point of instantiation.
// If so, we have run afoul of C++ [temp.expl.spec]p6.