Index: clang-tidy/ClangTidy.cpp =================================================================== --- clang-tidy/ClangTidy.cpp +++ clang-tidy/ClangTidy.cpp @@ -96,7 +96,8 @@ DiagPrinter), SourceMgr(Diags, Files), Context(Context), ApplyFixes(ApplyFixes), TotalFixes(0), AppliedFixes(0), WarningsAsErrors(0) { - DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors(); + DiagOpts->ShowColors = Context.getOptions().ShowColor.getValueOr( + llvm::sys::Process::StandardOutHasColors()); DiagPrinter->BeginSourceFile(LangOpts); } Index: clang-tidy/ClangTidyOptions.h =================================================================== --- clang-tidy/ClangTidyOptions.h +++ clang-tidy/ClangTidyOptions.h @@ -89,6 +89,9 @@ /// See clang-format documentation for more about configuring format style. llvm::Optional FormatStyle; + /// \brief Show color diagnostics. + llvm::Optional ShowColor; + /// \brief Specifies the name or e-mail of the user running clang-tidy. /// /// This option is used, for example, to place the correct user name in TODO() Index: clang-tidy/ClangTidyOptions.cpp =================================================================== --- clang-tidy/ClangTidyOptions.cpp +++ clang-tidy/ClangTidyOptions.cpp @@ -88,6 +88,7 @@ IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex); IO.mapOptional("AnalyzeTemporaryDtors", Options.AnalyzeTemporaryDtors); IO.mapOptional("FormatStyle", Options.FormatStyle); + IO.mapOptional("ShowColor", Options.ShowColor); IO.mapOptional("User", Options.User); IO.mapOptional("CheckOptions", NOpts->Options); IO.mapOptional("ExtraArgs", Options.ExtraArgs); @@ -149,6 +150,7 @@ overrideValue(Result.SystemHeaders, Other.SystemHeaders); overrideValue(Result.AnalyzeTemporaryDtors, Other.AnalyzeTemporaryDtors); overrideValue(Result.FormatStyle, Other.FormatStyle); + overrideValue(Result.ShowColor, Other.ShowColor); overrideValue(Result.User, Other.User); mergeVectors(Result.ExtraArgs, Other.ExtraArgs); mergeVectors(Result.ExtraArgsBefore, Other.ExtraArgsBefore); Index: clang-tidy/tool/ClangTidyMain.cpp =================================================================== --- clang-tidy/tool/ClangTidyMain.cpp +++ clang-tidy/tool/ClangTidyMain.cpp @@ -146,6 +146,12 @@ cl::init("none"), cl::cat(ClangTidyCategory)); +static cl::opt ShowColor("show-color", cl::desc(R"( +Show color diagnostics. If not specified, +defaults to on when a color-capable terminal +is detected.)"), + cl::ValueOptional, cl::cat(ClangTidyCategory)); + static cl::opt ListChecks("list-checks", cl::desc(R"( List all enabled checks and exit. Use with -checks=* to list all available checks. @@ -304,6 +310,7 @@ DefaultOptions.SystemHeaders = SystemHeaders; DefaultOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors; DefaultOptions.FormatStyle = FormatStyle; + DefaultOptions.ShowColor = ShowColor; DefaultOptions.User = llvm::sys::Process::GetEnv("USER"); // USERNAME is used on Windows. if (!DefaultOptions.User) @@ -322,6 +329,8 @@ OverrideOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors; if (FormatStyle.getNumOccurrences() > 0) OverrideOptions.FormatStyle = FormatStyle; + if (ShowColor.getNumOccurrences() > 0) + OverrideOptions.ShowColor = ShowColor; if (!Config.empty()) { if (llvm::ErrorOr ParsedConfig = Index: test/clang-tidy/show-color.cpp =================================================================== --- /dev/null +++ test/clang-tidy/show-color.cpp @@ -0,0 +1,10 @@ +// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' -show-color %s -- | FileCheck --check-prefix=CHECK-COLOR %s +// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' -show-color=0 %s -- | FileCheck --check-prefix=CHECK-NO-COLOR %s +// REQUIRES: ansi-escape-sequences + +void test() { + int *value = 0; + // CHECK-COLOR: [[BOLD:.\[1m]]{{.*}}[[@LINE+2]]:10: [[RESET:.\[0m]][[MAGENTA:.\[0;1;35m]]warning: [[RESET]][[BOLD]]Dereference of null pointer (loaded from variable 'value') [clang-analyzer-core.NullDereference][[RESET]] + // CHECK-NO-COLOR: [[@LINE+1]]:10: warning: Dereference of null pointer (loaded from variable 'value') [clang-analyzer-core.NullDereference] + *value = 1; +}