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.

llvm-svn: 93583
This commit is contained in:
John McCall 2010-01-15 23:32:50 +00:00
parent 6394a6e285
commit 3712d9e391
1 changed files with 30 additions and 14 deletions

View File

@ -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;
assert(L->Viable == R->Viable);
// 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;
// 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;
// And builtins just come in a jumble.
return false;
// 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);
}
};