aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-01-15 23:32:50 +0000
committerJohn McCall <rjmccall@apple.com>2010-01-15 23:32:50 +0000
commit1b77e73ef6b7ed886abbc79b89fcb59b0e5c69a1 (patch)
tree6d9fca57d187470b2d2b1de97a9aa8bb9f666cea /lib/Sema/SemaOverload.cpp
parent8eae0907c5094b8af61e26b8b809baf3c1ba75c8 (diff)
Candidates with arity mismatches are extra-special non-viable and need to
stand at the back of the line. Thanks to Oliver Hunt for reminding me to do this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93583 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp48
1 files changed, 32 insertions, 16 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6ec4d1b600..e4168eb7c8 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4582,6 +4582,14 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
}
}
+SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {
+ if (Cand->Function)
+ return Cand->Function->getLocation();
+ if (Cand->Surrogate)
+ return Cand->Surrogate->getLocation();
+ return SourceLocation();
+}
+
struct CompareOverloadCandidatesForDisplay {
Sema &S;
CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {}
@@ -4600,22 +4608,30 @@ struct CompareOverloadCandidatesForDisplay {
} else if (R->Viable)
return false;
- // Put declared functions first.
- if (L->Function) {
- if (!R->Function) return true;
- return S.SourceMgr.isBeforeInTranslationUnit(L->Function->getLocation(),
- R->Function->getLocation());
- } else if (R->Function) return false;
-
- // Then surrogates.
- if (L->IsSurrogate) {
- if (!R->IsSurrogate) return true;
- return S.SourceMgr.isBeforeInTranslationUnit(L->Surrogate->getLocation(),
- R->Surrogate->getLocation());
- } else if (R->IsSurrogate) return false;
-
- // And builtins just come in a jumble.
- return false;
+ assert(L->Viable == R->Viable);
+
+ // Criteria by which we can sort non-viable candidates:
+ if (!L->Viable) {
+ // 1. Arity mismatches come after other candidates.
+ if (L->FailureKind == ovl_fail_too_many_arguments ||
+ L->FailureKind == ovl_fail_too_few_arguments)
+ return false;
+ if (R->FailureKind == ovl_fail_too_many_arguments ||
+ R->FailureKind == ovl_fail_too_few_arguments)
+ return true;
+
+ // TODO: others?
+ }
+
+ // Sort everything else by location.
+ SourceLocation LLoc = GetLocationForCandidate(L);
+ SourceLocation RLoc = GetLocationForCandidate(R);
+
+ // Put candidates without locations (e.g. builtins) at the end.
+ if (LLoc.isInvalid()) return false;
+ if (RLoc.isInvalid()) return true;
+
+ return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc);
}
};