diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Frontend/CompilerInvocation.h | 3 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 50 |
3 files changed, 61 insertions, 32 deletions
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index 6d964bda4c5..36d997fe9ce 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -47,7 +47,8 @@ class DiagnosticsEngine; /// When errors are encountered, return false and, if Diags is non-null, /// report the error(s). bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, - DiagnosticsEngine *Diags = nullptr); + DiagnosticsEngine *Diags = nullptr, + bool DefaultDiagColor = true); class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { void operator=(const CompilerInvocationBase &) = delete; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 95f0a80140d..1c6082e3c58 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -5589,43 +5589,27 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fno-diagnostics-show-note-include-stack"); } - // Color diagnostics are the default, unless the terminal doesn't support - // them. - // Support both clang's -f[no-]color-diagnostics and gcc's - // -f[no-]diagnostics-colors[=never|always|auto]. - enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto; - for (const auto &Arg : Args) { - const Option &O = Arg->getOption(); + // Color diagnostics are parsed by the driver directly from argv + // and later re-parsed to construct this job; claim any possible + // color diagnostic here to avoid warn_drv_unused_argument and + // diagnose bad OPT_fdiagnostics_color_EQ values. + for (Arg *A : Args) { + const Option &O = A->getOption(); if (!O.matches(options::OPT_fcolor_diagnostics) && !O.matches(options::OPT_fdiagnostics_color) && !O.matches(options::OPT_fno_color_diagnostics) && !O.matches(options::OPT_fno_diagnostics_color) && !O.matches(options::OPT_fdiagnostics_color_EQ)) continue; - - Arg->claim(); - if (O.matches(options::OPT_fcolor_diagnostics) || - O.matches(options::OPT_fdiagnostics_color)) { - ShowColors = Colors_On; - } else if (O.matches(options::OPT_fno_color_diagnostics) || - O.matches(options::OPT_fno_diagnostics_color)) { - ShowColors = Colors_Off; - } else { - assert(O.matches(options::OPT_fdiagnostics_color_EQ)); - StringRef value(Arg->getValue()); - if (value == "always") - ShowColors = Colors_On; - else if (value == "never") - ShowColors = Colors_Off; - else if (value == "auto") - ShowColors = Colors_Auto; - else + if (O.matches(options::OPT_fdiagnostics_color_EQ)) { + StringRef Value(A->getValue()); + if (Value != "always" && Value != "never" && Value != "auto") getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) - << ("-fdiagnostics-color=" + value).str(); + << ("-fdiagnostics-color=" + Value).str(); } + A->claim(); } - if (ShowColors == Colors_On || - (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors())) + if (D.getDiags().getDiagnosticOptions().ShowColors) CmdArgs.push_back("-fcolor-diagnostics"); if (Args.hasArg(options::OPT_fansi_escape_codes)) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index a37e1cecae8..3b4c50b8356 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -860,8 +860,51 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ModuleFiles.end()); } +static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) { + // Color diagnostics default to auto ("on" if terminal supports) in the driver + // but default to off in cc1, needing an explicit OPT_fdiagnostics_color. + // Support both clang's -f[no-]color-diagnostics and gcc's + // -f[no-]diagnostics-colors[=never|always|auto]. + enum { + Colors_On, + Colors_Off, + Colors_Auto + } ShowColors = DefaultColor ? Colors_Auto : Colors_Off; + for (Arg *A : Args) { + const Option &O = A->getOption(); + if (!O.matches(options::OPT_fcolor_diagnostics) && + !O.matches(options::OPT_fdiagnostics_color) && + !O.matches(options::OPT_fno_color_diagnostics) && + !O.matches(options::OPT_fno_diagnostics_color) && + !O.matches(options::OPT_fdiagnostics_color_EQ)) + continue; + + if (O.matches(options::OPT_fcolor_diagnostics) || + O.matches(options::OPT_fdiagnostics_color)) { + ShowColors = Colors_On; + } else if (O.matches(options::OPT_fno_color_diagnostics) || + O.matches(options::OPT_fno_diagnostics_color)) { + ShowColors = Colors_Off; + } else { + assert(O.matches(options::OPT_fdiagnostics_color_EQ)); + StringRef Value(A->getValue()); + if (Value == "always") + ShowColors = Colors_On; + else if (Value == "never") + ShowColors = Colors_Off; + else if (Value == "auto") + ShowColors = Colors_Auto; + } + } + if (ShowColors == Colors_On || + (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors())) + return true; + return false; +} + bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, - DiagnosticsEngine *Diags) { + DiagnosticsEngine *Diags, + bool DefaultDiagColor) { using namespace options; bool Success = true; @@ -874,7 +917,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.Pedantic = Args.hasArg(OPT_pedantic); Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors); Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics); - Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics); + Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); Opts.ShowColumn = Args.hasFlag(OPT_fshow_column, OPT_fno_show_column, /*Default=*/true); @@ -2240,7 +2283,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); - Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags); + Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, + false /*DefaultDiagColor*/); ParseCommentArgs(LangOpts.CommentOpts, Args); ParseFileSystemArgs(Res.getFileSystemOpts(), Args); // FIXME: We shouldn't have to pass the DashX option around here |