ak_nestednamespec, // NestedNameSpecifier *
ak_declcontext // DeclContext *
};
-
+
+ /// Specifies which overload candidates to display when overload resolution
+ /// fails.
+ enum OverloadsShown {
+ Ovl_All, ///< Show all overloads.
+ Ovl_Best ///< Show just the "best" overload candidates.
+ };
+
/// ArgumentValue - This typedef represents on argument value, which is a
/// union discriminated by ArgumentKind, with a value.
typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
bool ErrorsAsFatal; // Treat errors like fatal errors.
bool SuppressSystemWarnings; // Suppress warnings in system headers.
bool SuppressAllDiagnostics; // Suppress all diagnostics.
+ OverloadsShown ShowOverloads; // Which overload candidates to show.
unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
// 0 -> no limit.
}
bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
+ /// \brief Specify which overload candidates to show when overload resolution
+ /// fails. By default, we show all candidates.
+ void setShowOverloads(OverloadsShown Val) {
+ ShowOverloads = Val;
+ }
+ OverloadsShown getShowOverloads() const { return ShowOverloads; }
+
/// \brief Pretend that the last diagnostic issued was ignored. This can
/// be used by clients who suppress diagnostics themselves.
void setLastDiagnosticIgnored() {
"call to member function %0 is ambiguous">;
def err_ovl_deleted_member_call : Error<
"call to %select{unavailable|deleted}0 member function %1">;
+def note_ovl_too_many_candidates : Note<
+ "remaining %0 candidate%s0 omitted; "
+ "pass -fshow-overloads=all to show them">;
def note_ovl_candidate : Note<"candidate "
"%select{function|function|constructor|"
"function |function |constructor |"
HelpText<"Do not include column number on diagnostics">;
def fno_show_source_location : Flag<"-fno-show-source-location">,
HelpText<"Do not include source location information with diagnostics">;
+def fshow_overloads_EQ : Joined<"-fshow-overloads=">,
+ HelpText<"Which overload candidates to show when overload resolution fails: "
+ "best|all; defaults to all">;
def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
HelpText<"Do not include source line and caret with diagnostics">;
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
def fshort_enums : Flag<"-fshort-enums">, Group<clang_ignored_f_Group>;
def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
+def fshow_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>;
def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
#define LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
+#include "clang/Basic/Diagnostic.h"
+
#include <string>
#include <vector>
unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number,
/// 2 -> Full Name.
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
+ unsigned ShowOverloads : 1; /// Overload candidates to show. Values from
+ /// Diagnostic::OverloadsShown
unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
/// diagnostics, indicated by markers in the
/// input source file.
PedanticErrors = 0;
ShowCarets = 1;
ShowColors = 0;
+ ShowOverloads = Diagnostic::Ovl_All;
ShowColumn = 1;
ShowFixits = 1;
ShowLocation = 1;
ErrorsAsFatal = false;
SuppressSystemWarnings = false;
SuppressAllDiagnostics = false;
+ ShowOverloads = Ovl_All;
ExtBehavior = Ext_Ignore;
ErrorOccurred = false;
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,
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")
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)
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.
}
}
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.
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) {
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify %s
struct yes;
struct no;
void test_dr425(A a) {
// FIXME: lots of candidates here!
(void)(1.0f * a); // expected-error{{ambiguous}} \
- // expected-note 81{{candidate}}
+ // expected-note 4{{candidate}} \
+ // expected-note {{remaining 77 candidates omitted; pass -fshow-overloads=all to show them}}
}
// pr5432