Add an option -fshow-overloads=best|all to limit the number of overload
candidates printed. We default to 'all'. At the moment, 'best' prints only
the first 4 overloads, but we'll improve that over time.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105815 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 2fd985f..a2480b1 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -250,6 +250,7 @@
ErrorsAsFatal = false;
SuppressSystemWarnings = false;
SuppressAllDiagnostics = false;
+ ShowOverloads = Ovl_All;
ExtBehavior = Ext_Ignore;
ErrorOccurred = false;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index d45676d..d47efbc 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1381,6 +1381,9 @@
options::OPT_fno_show_source_location))
CmdArgs.push_back("-fno-show-source-location");
+ if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
+ A->render(Args, CmdArgs);
+
// -fdollars-in-identifiers default varies depending on platform and
// language; only pass if specified.
if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 9bc8b76..b2f1ec6 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -869,7 +869,18 @@
Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
-
+
+ llvm::StringRef ShowOverloads =
+ Args.getLastArgValue(OPT_fshow_overloads_EQ, "all");
+ if (ShowOverloads == "best")
+ Opts.ShowOverloads = Diagnostic::Ovl_Best;
+ else if (ShowOverloads == "all")
+ Opts.ShowOverloads = Diagnostic::Ovl_All;
+ else
+ Diags.Report(diag::err_drv_invalid_value)
+ << Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
+ << ShowOverloads;
+
llvm::StringRef ShowCategory =
Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
if (ShowCategory == "none")
diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp
index 84c4f5d..8cc5616 100644
--- a/lib/Frontend/Warnings.cpp
+++ b/lib/Frontend/Warnings.cpp
@@ -35,6 +35,8 @@
const DiagnosticOptions &Opts) {
Diags.setSuppressSystemWarnings(true); // Default to -Wno-system-headers
Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
+ Diags.setShowOverloads(
+ static_cast<Diagnostic::OverloadsShown>(Opts.ShowOverloads));
// Handle -ferror-limit
if (Opts.ErrorLimit)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 721c68f..eda7e7a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5689,7 +5689,10 @@
Cands.push_back(Cand);
else if (OCD == OCD_AllCandidates) {
CompleteNonViableCandidate(*this, Cand, Args, NumArgs);
- Cands.push_back(Cand);
+ if (Cand->Function || Cand->IsSurrogate)
+ Cands.push_back(Cand);
+ // Otherwise, this a non-viable builtin candidate. We do not, in general,
+ // want to list every possible builtin candidate.
}
}
@@ -5699,17 +5702,26 @@
bool ReportedAmbiguousConversions = false;
llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
+ const Diagnostic::OverloadsShown ShowOverloads = Diags.getShowOverloads();
+ unsigned CandsShown = 0;
for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
OverloadCandidate *Cand = *I;
+ // Set an arbitrary limit on the number of candidate functions we'll spam
+ // the user with. FIXME: This limit should depend on details of the
+ // candidate list.
+ if (CandsShown >= 4 && ShowOverloads == Diagnostic::Ovl_Best) {
+ break;
+ }
+ ++CandsShown;
+
if (Cand->Function)
NoteFunctionCandidate(*this, Cand, Args, NumArgs);
else if (Cand->IsSurrogate)
NoteSurrogateCandidate(*this, Cand);
-
- // This a builtin candidate. We do not, in general, want to list
- // every possible builtin candidate.
- else if (Cand->Viable) {
+ else {
+ assert(Cand->Viable &&
+ "Non-viable built-in candidates are not added to Cands.");
// Generally we only see ambiguities including viable builtin
// operators if overload resolution got screwed up by an
// ambiguous user-defined conversion.
@@ -5725,6 +5737,9 @@
NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand);
}
}
+
+ if (I != E)
+ Diag(OpLoc, diag::note_ovl_too_many_candidates) << E - I;
}
static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) {