Index: llvm/include/llvm/Support/WithColor.h =================================================================== --- llvm/include/llvm/Support/WithColor.h +++ llvm/include/llvm/Support/WithColor.h @@ -33,11 +33,17 @@ Remark }; +enum class ColorMode { + Auto, + Enable, + Disable, +}; + /// An RAII object that temporarily switches an output stream to a specific /// color. class WithColor { raw_ostream &OS; - bool DisableColors; + ColorMode Mode; public: /// To be used like this: WithColor(OS, HighlightColor::String) << "text"; @@ -45,7 +51,8 @@ /// @param S Symbolic name for syntax element to color /// @param DisableColors Whether to ignore color changes regardless of -color /// and support in OS - WithColor(raw_ostream &OS, HighlightColor S, bool DisableColors = false); + WithColor(raw_ostream &OS, HighlightColor S, + ColorMode Mode = ColorMode::Auto); /// To be used like this: WithColor(OS, raw_ostream::Black) << "text"; /// @param OS The output stream /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to @@ -56,8 +63,9 @@ /// and support in OS WithColor(raw_ostream &OS, raw_ostream::Colors Color = raw_ostream::SAVEDCOLOR, - bool Bold = false, bool BG = false, bool DisableColors = false) - : OS(OS), DisableColors(DisableColors) { + bool Bold = false, bool BG = false, + ColorMode Mode = ColorMode::Auto) + : OS(OS), Mode(Mode) { changeColor(Color, Bold, BG); } ~WithColor(); Index: llvm/lib/Support/SourceMgr.cpp =================================================================== --- llvm/lib/Support/SourceMgr.cpp +++ llvm/lib/Support/SourceMgr.cpp @@ -450,8 +450,10 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors, bool ShowKindLabel) const { + ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable; + { - WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, !ShowColors); + WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, Mode); if (ProgName && ProgName[0]) S << ProgName << ": "; @@ -488,8 +490,7 @@ } } - WithColor(OS, raw_ostream::SAVEDCOLOR, true, false, !ShowColors) - << Message << '\n'; + WithColor(OS, raw_ostream::SAVEDCOLOR, true, false, Mode) << Message << '\n'; if (LineNo == -1 || ColumnNo == -1) return; @@ -536,7 +537,8 @@ printSourceLine(OS, LineContents); { - WithColor S(OS, raw_ostream::GREEN, true, false, !ShowColors); + ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable; + WithColor S(OS, raw_ostream::GREEN, true, false, Mode); // Print out the caret line, matching tabs in the source line. for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) { Index: llvm/lib/Support/WithColor.cpp =================================================================== --- llvm/lib/Support/WithColor.cpp +++ llvm/lib/Support/WithColor.cpp @@ -18,8 +18,8 @@ cl::desc("Use colors in output (default=autodetect)"), cl::init(cl::BOU_UNSET)); -WithColor::WithColor(raw_ostream &OS, HighlightColor Color, bool DisableColors) - : OS(OS), DisableColors(DisableColors) { +WithColor::WithColor(raw_ostream &OS, HighlightColor Color, ColorMode Mode) + : OS(OS), Mode(Mode) { // Detect color from terminal type unless the user passed the --color option. if (colorsEnabled()) { switch (Color) { @@ -69,7 +69,9 @@ bool DisableColors) { if (!Prefix.empty()) OS << Prefix << ": "; - return WithColor(OS, HighlightColor::Error, DisableColors).get() + return WithColor(OS, HighlightColor::Error, + DisableColors ? ColorMode::Disable : ColorMode::Auto) + .get() << "error: "; } @@ -77,7 +79,9 @@ bool DisableColors) { if (!Prefix.empty()) OS << Prefix << ": "; - return WithColor(OS, HighlightColor::Warning, DisableColors).get() + return WithColor(OS, HighlightColor::Warning, + DisableColors ? ColorMode::Disable : ColorMode::Auto) + .get() << "warning: "; } @@ -85,23 +89,33 @@ bool DisableColors) { if (!Prefix.empty()) OS << Prefix << ": "; - return WithColor(OS, HighlightColor::Note, DisableColors).get() << "note: "; + return WithColor(OS, HighlightColor::Note, + DisableColors ? ColorMode::Disable : ColorMode::Auto) + .get() + << "note: "; } raw_ostream &WithColor::remark(raw_ostream &OS, StringRef Prefix, bool DisableColors) { if (!Prefix.empty()) OS << Prefix << ": "; - return WithColor(OS, HighlightColor::Remark, DisableColors).get() + return WithColor(OS, HighlightColor::Remark, + DisableColors ? ColorMode::Disable : ColorMode::Auto) + .get() << "remark: "; } bool WithColor::colorsEnabled() { - if (DisableColors) + switch (Mode) { + case ColorMode::Enable: + return true; + case ColorMode::Disable: return false; - if (UseColor == cl::BOU_UNSET) - return OS.has_colors(); - return UseColor == cl::BOU_TRUE; + case ColorMode::Auto: + return UseColor == cl::BOU_UNSET ? OS.has_colors() + : UseColor == cl::BOU_TRUE; + } + llvm_unreachable("All cases handled above."); } WithColor &WithColor::changeColor(raw_ostream::Colors Color, bool Bold, Index: llvm/unittests/Support/CMakeLists.txt =================================================================== --- llvm/unittests/Support/CMakeLists.txt +++ llvm/unittests/Support/CMakeLists.txt @@ -82,6 +82,7 @@ UnicodeTest.cpp VersionTupleTest.cpp VirtualFileSystemTest.cpp + WithColorTest.cpp YAMLIOTest.cpp YAMLParserTest.cpp formatted_raw_ostream_test.cpp Index: llvm/unittests/Support/WithColorTest.cpp =================================================================== --- /dev/null +++ llvm/unittests/Support/WithColorTest.cpp @@ -0,0 +1,41 @@ +//===- WithColorTest.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/WithColor.h" +#include "gtest/gtest.h" + +using namespace llvm; + +TEST(WithColorTest, ColorMode) { + { + std::string S; + llvm::raw_string_ostream OS(S); + OS.enable_colors(true); + + WithColor(OS, HighlightColor::Error, ColorMode::Disable) << "test"; + EXPECT_EQ("test", OS.str()); + } + + { + std::string S; + llvm::raw_string_ostream OS(S); + OS.enable_colors(true); + + WithColor(OS, HighlightColor::Error, ColorMode::Auto) << "test"; + EXPECT_EQ("test", OS.str()); + } + + { + std::string S; + llvm::raw_string_ostream OS(S); + OS.enable_colors(true); + + WithColor(OS, HighlightColor::Error, ColorMode::Enable) << "test"; + EXPECT_EQ("\x1B[0;1;31mtest\x1B[0m", OS.str()); + } +}