diff --git a/clang/include/clang/Basic/DiagnosticOptions.h b/clang/include/clang/Basic/DiagnosticOptions.h --- a/clang/include/clang/Basic/DiagnosticOptions.h +++ b/clang/include/clang/Basic/DiagnosticOptions.h @@ -11,6 +11,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/Option/ArgList.h" #include #include #include @@ -57,10 +58,19 @@ static_cast(LHS) & static_cast(RHS)); } -raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M); +raw_ostream &operator<<(raw_ostream &Out, DiagnosticLevelMask M); + +class DiagnosticsEngine; /// Options for controlling the compiler diagnostics engine. class DiagnosticOptions : public RefCountedBase{ + + friend bool ParseDiagnosticArgs(DiagnosticOptions &Opts, + llvm::opt::ArgList &Args, + DiagnosticsEngine *Diags, + bool DefaultDiagColor); + friend class CompilerInvocation; + public: enum TextDiagnosticFormat { Clang, MSVC, Vi }; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -382,6 +382,120 @@ } // Flags = [CC1Option, NoDriverOption] +// Diagnostic Options + +let IsDiagnosticsArg = 1 in { + +def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group, + Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">, + MarshallingInfoFlag<"ShowParseableFixits", "false">; +def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group, + Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">, + MarshallingInfoFlag<"UseANSIEscapeCodes", "false">; +def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">, + Group, Flags<[CC1Option]>, + HelpText<"Print source range spans in numeric form">, + MarshallingInfoFlag<"ShowSourceRanges", "false">; +def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">, + Group, Flags<[CC1Option]>, + HelpText<"Print a template comparison tree for differing templates">, + MarshallingInfoFlag<"ShowTemplateTree", "false">; +def fno_elide_type : Flag<["-"], "fno-elide-type">, Group, + Flags<[CC1Option]>, + HelpText<"Do not elide types when printing diagnostics">, + MarshallingInfoFlag<"ElideType", "true">, IsNegative; +def fdiagnostics_absolute_paths : Flag<["-"], "fdiagnostics-absolute-paths">, Group, + Flags<[CC1Option, CoreOption]>, HelpText<"Print absolute paths in diagnostics">, + MarshallingInfoFlag<"AbsolutePath", "false">; +def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group, Flags<[CC1Option]>, + MarshallingInfoFlag<"PedanticErrors", "false">; +def pedantic : Flag<["-", "--"], "pedantic">, Group, Flags<[CC1Option]>, + MarshallingInfoFlag<"Pedantic", "false">; +def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>, + MarshallingInfoFlag<"IgnoreWarnings", "false">; +def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group; +def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Flags<[CC1Option]>, + Group, MarshallingInfoFlag<"ShowCarets", "true">, IsNegative; +def fshow_column : Flag<["-"], "fshow-column">, Group; +def fno_show_column : Flag<["-"], "fno-show-column">, Flags<[CC1Option]>, + Group, HelpText<"Do not include column number on diagnostics">, + MarshallingInfoFlag<"ShowColumn", "true">, IsNegative; +def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group, + Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">, + MarshallingInfoFlag<"ShowFixits", "true">, IsNegative; +def fshow_source_location : Flag<["-"], "fshow-source-location">, Group; +def fno_show_source_location : Flag<["-"], "fno-show-source-location">, Group, + Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">, + MarshallingInfoFlag<"ShowLocation", "true">, IsNegative; +def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group, + HelpText<"Print option name with mappable diagnostics">; +def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group, Flags<[CC1Option]>, + MarshallingInfoFlag<"ShowOptionNames", "true">, IsNegative; +defm diagnostics_show_note_include_stack : BooleanMarshalledFFlag<"diagnostics-show-note-include-stack", + "ShowNoteIncludeStack", "false", "Display include stacks for diagnostic notes">, + Group, Flags<[CC1Option]>; + +def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group, Flags<[CC1Option]>, + HelpText<"Which overload candidates to show when overload resolution fails: " + "best|all; defaults to all">, Values<"best,all">, + MarshallingInfoString<"ShowOverloads", "Ovl_All">, + NormalizedValues<["Ovl_Best", "Ovl_All"]>, AutoNormalizeEnum; +def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group, Flags<[CC1Option]>, + HelpText<"Format message diagnostics so that they fit within N columns">, + MarshallingInfoStringInt<"MessageLength">; + +let Flags = [CC1Option, NoDriverOption] in { + +def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">, + HelpText<"Ignore #line directives when displaying diagnostic locations">, + MarshallingInfoFlag<"ShowPresumedLoc", "true">, IsNegative; +def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, + HelpText<"Silence ObjC rewriting warnings">, + MarshallingInfoFlag<"NoRewriteMacros", "false">; + +def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">, + HelpText<"Filename (or -) to log diagnostics to">, + MarshallingInfoString<"DiagnosticLogFile">; +def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">, + MetaVarName<"">, + HelpText<"File for serializing diagnostics in a binary format">, + MarshallingInfoString<"DiagnosticSerializationFile">; +def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, + HelpText<"Print diagnostic category">, Values<"none,id,name">, + MarshallingInfoString<"ShowCategories", "0">, + NormalizedValues<["0", "1", "2"]>, AutoNormalizeEnum; +def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, + HelpText<"Change diagnostic formatting to match IDE and command line tools">, + Values<"clang,msvc,msvc-fallback,vi">, NormalizedValuesScope<"DiagnosticOptions">, + MarshallingInfoString<"Format", "Clang">, + NormalizedValues<["Clang", "MSVC", "MSVC", "Vi"]>, AutoNormalizeEnum; +def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">, + MarshallingInfoStringInt<"ErrorLimit">; +def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">, + MarshallingInfoStringInt<"MacroBacktraceLimit", "DiagnosticOptions::DefaultMacroBacktraceLimit">; +def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">, + MarshallingInfoStringInt<"TemplateBacktraceLimit", "DiagnosticOptions::DefaultTemplateBacktraceLimit">; +def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">, + MarshallingInfoStringInt<"ConstexprBacktraceLimit", "DiagnosticOptions::DefaultConstexprBacktraceLimit">; +def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">, + MarshallingInfoStringInt<"SpellCheckingLimit", "DiagnosticOptions::DefaultSpellCheckingLimit">; +def fcaret_diagnostics_max_lines : + Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"">, + HelpText<"Set the maximum number of source lines to show in a caret diagnostic">, + MarshallingInfoStringInt<"SnippetLineLimit", "DiagnosticOptions::DefaultSnippetLineLimit">; +def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"">, + HelpText<"Set the tab stop distance.">, + MarshallingInfoStringInt<"TabStop", "DiagnosticOptions::DefaultTabStop">; + +} // Flags = [CC1Option, NoDriverOption] + +} // IsDiagnoticsArg = 1 + // Frontend Options def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">, @@ -2243,7 +2357,6 @@ def fbuiltin : Flag<["-"], "fbuiltin">, Group, Flags<[CoreOption]>; def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group, Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">; -defm caret_diagnostics : OptOutFFlag<"caret-diagnostics", "", "">; def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group, Flags<[CC1Option]>, MetaVarName<"">, Values<".,latest">, HelpText<"Attempt to match the ABI of Clang ">; @@ -2252,9 +2365,6 @@ def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group, Flags<[CoreOption, DriverOption]>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group; -def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group, - Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">, - MarshallingInfoFlag<"DiagnosticOpts->UseANSIEscapeCodes", "false">; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in as a documentation comment block command">, MetaVarName<"">; @@ -2281,20 +2391,8 @@ def fdepfile_entry : Joined<["-"], "fdepfile-entry=">, Group, Flags<[CC1Option]>; def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group; -def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group, - Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">; -def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">, - Group, Flags<[CC1Option]>, - HelpText<"Print source range spans in numeric form">; -def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group, - HelpText<"Print option name with mappable diagnostics">; -def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">, - Group, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">; def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group; def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group; -def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">, - Group, Flags<[CC1Option]>, - HelpText<"Print a template comparison tree for differing templates">; def fdeclspec : Flag<["-"], "fdeclspec">, Group, HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>; def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, Group, @@ -2305,9 +2403,6 @@ HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group; def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group; -def fno_elide_type : Flag<["-"], "fno-elide-type">, Group, - Flags<[CC1Option]>, - HelpText<"Do not elide types when printing diagnostics">; def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group; def femulated_tls : Flag<["-"], "femulated-tls">, Group, Flags<[CC1Option]>, HelpText<"Use emutls functions to access thread_local variables">; @@ -2577,8 +2672,6 @@ HelpText<"Perform ThinLTO importing using provided function summary index">; def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, Group, Flags<[DriverOption, CoreOption]>; -def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group, Flags<[CC1Option]>, - HelpText<"Format message diagnostics so that they fit within N columns">; def fms_extensions : Flag<["-"], "fms-extensions">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; def fmsc_version : Joined<["-"], "fmsc-version=">, Group, Flags<[DriverOption, CoreOption]>, @@ -2655,11 +2748,6 @@ HelpText<"Compile common globals like normal definitions">; def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group, Flags<[DriverOption]>; -def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group, - Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">; -def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group, Flags<[CC1Option]>; -def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, - Flags<[CC1Option]>, Group; def fdigraphs : Flag<["-"], "fdigraphs">, Group, Flags<[CC1Option]>, HelpText<"Enable alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:' (default)">; def fno_digraphs : Flag<["-"], "fno-digraphs">, Group, Flags<[CC1Option]>, @@ -2701,10 +2789,6 @@ def fno_operator_names : Flag<["-"], "fno-operator-names">, Group, HelpText<"Do not treat C++ operator name keywords as synonyms for operators">, Flags<[CC1Option]>; -def fno_show_source_location : Flag<["-"], "fno-show-source-location">, Group, - Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">; -def fdiagnostics_absolute_paths : Flag<["-"], "fdiagnostics-absolute-paths">, Group, - Flags<[CC1Option, CoreOption]>, HelpText<"Print absolute paths in diagnostics">; def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group, HelpText<"Disable the use of stack protectors">; def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group, @@ -2822,11 +2906,6 @@ HelpText<"Force wchar_t to be a short unsigned int">; def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group, HelpText<"Force wchar_t to be an unsigned int">; -def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group, Flags<[CC1Option]>, - HelpText<"Which overload candidates to show when overload resolution fails: " - "best|all; defaults to all">, Values<"best,all">; -defm show_column : OptOutFFlag<"show-column", "", "Do not include column number on diagnostics">; -def fshow_source_location : Flag<["-"], "fshow-source-location">, Group; def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group; def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group; defm signed_char : OptOutFFlag<"signed-char", "char is signed", "char is unsigned">; @@ -3612,8 +3691,6 @@ def object : Flag<["-"], "object">; def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">; def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; -def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group, Flags<[CC1Option]>; -def pedantic : Flag<["-", "--"], "pedantic">, Group, Flags<[CC1Option]>; def pipe : Flag<["-", "--"], "pipe">, HelpText<"Use pipes between commands, when possible">; def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules">; @@ -3755,7 +3832,6 @@ def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">; def whatsloaded : Flag<["-"], "whatsloaded">; def whyload : Flag<["-"], "whyload">; -def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>; def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>, HelpText<"Treat subsequent input files as having type ">, MetaVarName<"">; @@ -4545,33 +4621,6 @@ // Diagnostic Options //===----------------------------------------------------------------------===// -def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">, - HelpText<"Filename (or -) to log diagnostics to">; -def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">, - MetaVarName<"">, - HelpText<"File for serializing diagnostics in a binary format">; - -def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, - HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">; -def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, - HelpText<"Print diagnostic category">, Values<"none,id,name">; -def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">, - HelpText<"Ignore #line directives when displaying diagnostic locations">; -def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"">, - HelpText<"Set the tab stop distance.">; -def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"">, - HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; -def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"">, - HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">; -def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"">, - HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; -def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"">, - HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">; -def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"">, - HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">; -def fcaret_diagnostics_max_lines : - Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"">, - HelpText<"Set the maximum number of source lines to show in a caret diagnostic">; def verify_EQ : CommaJoined<["-"], "verify=">, MetaVarName<"">, HelpText<"Verify diagnostic output using comment directives that start with" @@ -4582,9 +4631,6 @@ HelpText<"Ignore unexpected diagnostic messages">; def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">, HelpText<"Ignore unexpected diagnostic messages">; -def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, - HelpText<"Silence ObjC rewriting warnings">; - //===----------------------------------------------------------------------===// // Frontend Options //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -129,13 +129,13 @@ static llvm::Optional normalizeSimpleFlag(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { return Args.hasArg(Opt); } static llvm::Optional normalizeSimpleNegativeFlag(OptSpecifier Opt, unsigned TableIndex, - const ArgList &Args, DiagnosticsEngine &Diags) { + const ArgList &Args, DiagnosticsEngine *Diags) { return !Args.hasArg(Opt); } @@ -151,7 +151,7 @@ template static llvm::Optional normalizeFlagToValue(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { if (Args.hasArg(Opt)) return Value; return None; @@ -161,7 +161,7 @@ OptSpecifier NegOpt, unsigned TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { if (const Arg *A = Args.getLastArg(PosOpt, NegOpt)) return A->getOption().matches(PosOpt); return None; @@ -180,7 +180,7 @@ static Optional normalizeString(OptSpecifier Opt, int TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { auto *Arg = Args.getLastArg(Opt); if (!Arg) return None; @@ -231,7 +231,7 @@ static llvm::Optional normalizeSimpleEnum(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { assert(TableIndex < SimpleEnumValueTablesSize); const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; @@ -243,8 +243,9 @@ if (auto MaybeEnumVal = findValueTableByName(Table, ArgValue)) return MaybeEnumVal->Value; - Diags.Report(diag::err_drv_invalid_value) - << Arg->getAsString(Args) << ArgValue; + if (Diags) + Diags->Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << ArgValue; return None; } @@ -269,21 +270,22 @@ template static Optional normalizeStringIntegral(OptSpecifier Opt, int TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { auto *Arg = Args.getLastArg(Opt); if (!Arg) return None; - IntTy Res; + IntTy Res = 0; if (StringRef(Arg->getValue()).getAsInteger(0, Res)) { - Diags.Report(diag::err_drv_invalid_int_value) - << Arg->getAsString(Args) << Arg->getValue(); + if (Diags) + Diags->Report(diag::err_drv_invalid_int_value) + << Arg->getAsString(Args) << Arg->getValue(); } return Res; } static Optional normalizeTriple(OptSpecifier Opt, int TableIndex, const ArgList &Args, - DiagnosticsEngine &Diags) { + DiagnosticsEngine *Diags) { auto *Arg = Args.getLastArg(Opt); if (!Arg) return None; @@ -311,7 +313,6 @@ static void FixupInvocation(const ArgList &Args, CompilerInvocation &Invocation, DiagnosticsEngine &Diags) { LangOptions &LangOpts = *Invocation.getLangOpts(); - DiagnosticOptions &DiagOpts = Invocation.getDiagnosticOpts(); CodeGenOptions &CodeGenOpts = Invocation.getCodeGenOpts(); FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); TargetOptions &TargetOpts = Invocation.getTargetOpts(); @@ -329,8 +330,6 @@ LangOpts.SpeculativeLoadHardening = CodeGenOpts.SpeculativeLoadHardening; LangOpts.CurrentModule = LangOpts.ModuleName; - llvm::sys::Process::UseANSIEscapeCodes(DiagOpts.UseANSIEscapeCodes); - if (LangOpts.AppleKext && !LangOpts.CPlusPlus) Diags.Report(diag::warn_c_kext); @@ -1259,83 +1258,52 @@ bool DefaultDiagColor) { bool Success = true; - Opts.DiagnosticLogFile = - std::string(Args.getLastArgValue(OPT_diagnostic_log_file)); - if (Arg *A = - Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags)) - Opts.DiagnosticSerializationFile = A->getValue(); - Opts.IgnoreWarnings = Args.hasArg(OPT_w); - Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros); - Opts.Pedantic = Args.hasArg(OPT_pedantic); - Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors); - Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics); - Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); - Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column); - Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info); - Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location); - Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths); - Opts.ShowOptionNames = !Args.hasArg(OPT_fno_diagnostics_show_option); - - // Default behavior is to not to show note include stacks. - Opts.ShowNoteIncludeStack = false; - if (Arg *A = Args.getLastArg(OPT_fdiagnostics_show_note_include_stack, - OPT_fno_diagnostics_show_note_include_stack)) - if (A->getOption().matches(OPT_fdiagnostics_show_note_include_stack)) - Opts.ShowNoteIncludeStack = true; - - StringRef ShowOverloads = - Args.getLastArgValue(OPT_fshow_overloads_EQ, "all"); - if (ShowOverloads == "best") - Opts.setShowOverloads(Ovl_Best); - else if (ShowOverloads == "all") - Opts.setShowOverloads(Ovl_All); - else { - Success = false; - if (Diags) - Diags->Report(diag::err_drv_invalid_value) - << Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args) - << ShowOverloads; - } - - StringRef ShowCategory = - Args.getLastArgValue(OPT_fdiagnostics_show_category, "none"); - if (ShowCategory == "none") - Opts.ShowCategories = 0; - else if (ShowCategory == "id") - Opts.ShowCategories = 1; - else if (ShowCategory == "name") - Opts.ShowCategories = 2; - else { - Success = false; - if (Diags) - Diags->Report(diag::err_drv_invalid_value) - << Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args) - << ShowCategory; - } - - StringRef Format = - Args.getLastArgValue(OPT_fdiagnostics_format, "clang"); - if (Format == "clang") - Opts.setFormat(DiagnosticOptions::Clang); - else if (Format == "msvc") - Opts.setFormat(DiagnosticOptions::MSVC); - else if (Format == "msvc-fallback") { - Opts.setFormat(DiagnosticOptions::MSVC); +#define DIAG_OPTION_WITH_MARSHALLING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + { \ + if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \ + Opts.KEYPATH = MERGER(Opts.KEYPATH, \ + static_cast(*MaybeValue)); \ + else \ + Opts.KEYPATH = MERGER(Opts.KEYPATH, DEFAULT_VALUE); \ + } + +#define DIAG_OPTION_WITH_MARSHALLING_BOOLEAN( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID, \ + NEG_SPELLING) \ + { \ + if (auto MaybeValue = \ + NORMALIZER(OPT_##ID, OPT_##NEG_ID, TABLE_INDEX, Args, Diags)) \ + Opts.KEYPATH = MERGER(Opts.KEYPATH, \ + static_cast(*MaybeValue)); \ + else \ + Opts.KEYPATH = MERGER(Opts.KEYPATH, DEFAULT_VALUE); \ + } + +#include "clang/Driver/Options.inc" +#undef DIAG_OPTION_WITH_MARSHALLING_BOOLEAN +#undef DIAG_OPTION_WITH_MARSHALLING + + llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes); + + if (Args.getLastArgValue(OPT_fdiagnostics_format) == "msvc-fallback") Opts.CLFallbackMode = true; - } else if (Format == "vi") - Opts.setFormat(DiagnosticOptions::Vi); - else { - Success = false; + + if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) { + Opts.TabStop = DiagnosticOptions::DefaultTabStop; if (Diags) - Diags->Report(diag::err_drv_invalid_value) - << Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args) - << Format; + Diags->Report(diag::warn_ignoring_ftabstop_value) + << Opts.TabStop << DiagnosticOptions::DefaultTabStop; } - Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info); - Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits); - Opts.ShowPresumedLoc = !Args.hasArg(OPT_fno_diagnostics_use_presumed_location); - Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ); + Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); + + Opts.VerifyDiagnostics = + Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ); Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ); if (Args.hasArg(OPT_verify)) Opts.VerifyPrefixes.push_back("expected"); @@ -1354,34 +1322,6 @@ if (Args.hasArg(OPT_verify_ignore_unexpected)) DiagMask = DiagnosticLevelMask::All; Opts.setVerifyIgnoreUnexpected(DiagMask); - Opts.ElideType = !Args.hasArg(OPT_fno_elide_type); - Opts.ShowTemplateTree = Args.hasArg(OPT_fdiagnostics_show_template_tree); - Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags); - Opts.MacroBacktraceLimit = - getLastArgIntValue(Args, OPT_fmacro_backtrace_limit, - DiagnosticOptions::DefaultMacroBacktraceLimit, Diags); - Opts.TemplateBacktraceLimit = getLastArgIntValue( - Args, OPT_ftemplate_backtrace_limit, - DiagnosticOptions::DefaultTemplateBacktraceLimit, Diags); - Opts.ConstexprBacktraceLimit = getLastArgIntValue( - Args, OPT_fconstexpr_backtrace_limit, - DiagnosticOptions::DefaultConstexprBacktraceLimit, Diags); - Opts.SpellCheckingLimit = getLastArgIntValue( - Args, OPT_fspell_checking_limit, - DiagnosticOptions::DefaultSpellCheckingLimit, Diags); - Opts.SnippetLineLimit = getLastArgIntValue( - Args, OPT_fcaret_diagnostics_max_lines, - DiagnosticOptions::DefaultSnippetLineLimit, Diags); - Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop, - DiagnosticOptions::DefaultTabStop, Diags); - if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) { - Opts.TabStop = DiagnosticOptions::DefaultTabStop; - if (Diags) - Diags->Report(diag::warn_ignoring_ftabstop_value) - << Opts.TabStop << DiagnosticOptions::DefaultTabStop; - } - Opts.MessageLength = - getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags); Opts.UndefPrefixes = Args.getAllArgValues(OPT_Wundef_prefix_EQ); @@ -2783,7 +2723,7 @@ HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ { \ - if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \ + if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, &Diags)) \ this->KEYPATH = MERGER( \ this->KEYPATH, static_castKEYPATH)>(*MaybeValue)); \ else \ @@ -2797,7 +2737,7 @@ NEG_SPELLING) \ { \ if (auto MaybeValue = \ - NORMALIZER(OPT_##ID, OPT_##NEG_ID, TABLE_INDEX, Args, Diags)) \ + NORMALIZER(OPT_##ID, OPT_##NEG_ID, TABLE_INDEX, Args, &Diags)) \ this->KEYPATH = MERGER( \ this->KEYPATH, static_castKEYPATH)>(*MaybeValue)); \ else \ @@ -3070,7 +3010,30 @@ DENORMALIZER(Args, SPELLING, NEG_SPELLING, SA, TABLE_INDEX, Extracted); \ } +#define DIAG_OPTION_WITH_MARSHALLING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + OPTION_WITH_MARSHALLING(PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, \ + ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, VALUES, \ + SPELLING, ALWAYS_EMIT, DiagnosticOpts->KEYPATH, \ + DEFAULT_VALUE, NORMALIZER, DENORMALIZER, MERGER, \ + EXTRACTOR, TABLE_INDEX) + +#define DIAG_OPTION_WITH_MARSHALLING_BOOLEAN( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID, \ + NEG_SPELLING) \ + OPTION_WITH_MARSHALLING_BOOLEAN( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + DiagnosticOpts->KEYPATH, DEFAULT_VALUE, NORMALIZER, DENORMALIZER, \ + MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID, NEG_SPELLING) + #include "clang/Driver/Options.inc" +#undef DIAG_OPTION_WITH_MARSHALLING_BOOLEAN +#undef DIAG_OPTION_WITH_MARSHALLING #undef OPTION_WITH_MARSHALLING_BOOLEAN #undef OPTION_WITH_MARSHALLING } diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td --- a/llvm/include/llvm/Option/OptParser.td +++ b/llvm/include/llvm/Option/OptParser.td @@ -98,6 +98,7 @@ Option Alias = ?; list AliasArgs = []; string MarshallingInfoKind = ?; + bit IsDiagnosticsArg = 0; code KeyPath = ?; code DefaultValue = ?; bit ShouldAlwaysEmit = 0; @@ -199,6 +200,7 @@ } class ValueMerger { code ValueMerger = merger; } class ValueExtractor { code ValueExtractor = extractor; } +class DiagnosticArg { bit IsDiagnosticArg = 1; } // Predefined options. diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp --- a/llvm/utils/TableGen/OptParserEmitter.cpp +++ b/llvm/utils/TableGen/OptParserEmitter.cpp @@ -156,6 +156,9 @@ MarshallingInfoBooleanFlag(const Record &Option, const Record &NegOption) : MarshallingInfo("OPTION_WITH_MARSHALLING_BOOLEAN", Option), NegOption(NegOption) {} + MarshallingInfoBooleanFlag(const char *MacroName, const Record &Option, + const Record &NegOption) + : MarshallingInfo(MacroName, Option), NegOption(NegOption) {} void emit(raw_ostream &OS) const override { MarshallingInfo::emit(OS); @@ -176,10 +179,18 @@ MarshallingInfo::Ptr Ret; StringRef KindString = R.getValueAsString("MarshallingInfoKind"); if (KindString == "Default") { - Ret = std::make_unique(R); + if (R.getValueAsBit("IsDiagnosticsArg")) + Ret = + std::make_unique("DIAG_OPTION_WITH_MARSHALLING", R); + else + Ret = std::make_unique(R); } else if (KindString == "BooleanFlag") { - Ret = std::make_unique( - R, *R.getValueAsDef("NegOption")); + const Record &NegOption = *R.getValueAsDef("NegOption"); + if (R.getValueAsBit("IsDiagnosticsArg")) + Ret = std::make_unique( + "DIAG_OPTION_WITH_MARSHALLING_BOOLEAN", R, NegOption); + else + Ret = std::make_unique(R, NegOption); } Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");