]> granicus.if.org Git - clang/commitdiff
Candidates with arity mismatches are extra-special non-viable and need to
authorJohn McCall <rjmccall@apple.com>
Fri, 15 Jan 2010 23:32:50 +0000 (23:32 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 15 Jan 2010 23:32:50 +0000 (23:32 +0000)
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

lib/Sema/SemaOverload.cpp

index 6ec4d1b600184e7723f38e86fef813370437480c..e4168eb7c8849bf1d476828f68e849fcb034c1e8 100644 (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;
-
-    // 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);
   }
 };