diff options
author | John McCall <rjmccall@apple.com> | 2010-01-15 23:32:50 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-01-15 23:32:50 +0000 |
commit | 1b77e73ef6b7ed886abbc79b89fcb59b0e5c69a1 (patch) | |
tree | 6d9fca57d187470b2d2b1de97a9aa8bb9f666cea /lib/Sema/SemaOverload.cpp | |
parent | 8eae0907c5094b8af61e26b8b809baf3c1ba75c8 (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.cpp | 48 |
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); } }; |