From: Rui Ueyama Date: Fri, 2 Aug 2019 04:48:30 +0000 (+0000) Subject: Improve raw_ostream so that you can "write" colors using operator<< X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9ead55fa15c1b85098f0948a737db177556433fe;p=clang Improve raw_ostream so that you can "write" colors using operator<< 1. raw_ostream supports ANSI colors so that you can write messages to the termina with colors. Previously, in order to change and reset color, you had to call `changeColor` and `resetColor` functions, respectively. So, if you print out "error: " in red, for example, you had to do something like this: OS.changeColor(raw_ostream::RED); OS << "error: "; OS.resetColor(); With this patch, you can write the same code as follows: OS << raw_ostream::RED << "error: " << raw_ostream::RESET; 2. Add a boolean flag to raw_ostream so that you can disable colored output. If you disable colors, changeColor, operator<<(Color), resetColor and other color-related functions have no effect. Most LLVM tools automatically prints out messages using colors, and you can disable it by passing a flag such as `--disable-colors`. This new flag makes it easy to write code that works that way. Differential Revision: https://reviews.llvm.org/D65564 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@367649 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h index 55a085449a..3dd4f9c081 100644 --- a/include/clang/AST/ASTDumperUtils.h +++ b/include/clang/AST/ASTDumperUtils.h @@ -27,7 +27,7 @@ enum ASTDumpOutputFormat { // Do not use bold yellow for any text. It is hard to read on white screens. struct TerminalColor { - llvm::raw_ostream::Colors Color; + llvm::raw_ostream::Color Color; bool Bold; }; diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 0ed1e988a1..5db15077ce 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -5509,7 +5509,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg, if (print_edges) { // Print the predecessors of this block. if (!B.pred_empty()) { - const raw_ostream::Colors Color = raw_ostream::BLUE; + const raw_ostream::Color Color = raw_ostream::BLUE; if (ShowColors) OS.changeColor(Color); OS << " Preds " ; @@ -5546,7 +5546,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg, // Print the successors of this block. if (!B.succ_empty()) { - const raw_ostream::Colors Color = raw_ostream::MAGENTA; + const raw_ostream::Color Color = raw_ostream::MAGENTA; if (ShowColors) OS.changeColor(Color); OS << " Succs "; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 6bf4fbcbb2..d9bbe25381 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1491,6 +1491,10 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, OPT_fno_diagnostics_show_option, DefaultShowOpt); llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes)); + if (Opts.ShowColors) { + llvm::outs().enable_colors(); + llvm::errs().enable_colors(); + } // Default behavior is to not to show note include stacks. Opts.ShowNoteIncludeStack = false; diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp index d6e75a9180..d066ce0671 100644 --- a/lib/Frontend/TextDiagnostic.cpp +++ b/lib/Frontend/TextDiagnostic.cpp @@ -23,23 +23,16 @@ using namespace clang; -static const enum raw_ostream::Colors noteColor = - raw_ostream::BLACK; -static const enum raw_ostream::Colors remarkColor = - raw_ostream::BLUE; -static const enum raw_ostream::Colors fixitColor = - raw_ostream::GREEN; -static const enum raw_ostream::Colors caretColor = - raw_ostream::GREEN; -static const enum raw_ostream::Colors warningColor = - raw_ostream::MAGENTA; -static const enum raw_ostream::Colors templateColor = - raw_ostream::CYAN; -static const enum raw_ostream::Colors errorColor = raw_ostream::RED; -static const enum raw_ostream::Colors fatalColor = raw_ostream::RED; +static const raw_ostream::Color noteColor = raw_ostream::BLACK; +static const raw_ostream::Color remarkColor = raw_ostream::BLUE; +static const raw_ostream::Color fixitColor = raw_ostream::GREEN; +static const raw_ostream::Color caretColor = raw_ostream::GREEN; +static const raw_ostream::Color warningColor = raw_ostream::MAGENTA; +static const raw_ostream::Color templateColor = raw_ostream::CYAN; +static const raw_ostream::Color errorColor = raw_ostream::RED; +static const raw_ostream::Color fatalColor = raw_ostream::RED; // Used for changing only the bold attribute. -static const enum raw_ostream::Colors savedColor = - raw_ostream::SAVEDCOLOR; +static const raw_ostream::Color savedColor = raw_ostream::SAVEDCOLOR; /// Add highlights to differences in template strings. static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str, diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp index 154c52a485..9bb710775d 100644 --- a/tools/diagtool/TreeView.cpp +++ b/tools/diagtool/TreeView.cpp @@ -20,29 +20,16 @@ DEF_DIAGTOOL("tree", "Show warning flags in a tree view", TreeView) using namespace clang; using namespace diagtool; -static bool hasColors(const llvm::raw_ostream &out) { - if (&out != &llvm::errs() && &out != &llvm::outs()) - return false; - return llvm::errs().is_displayed() && llvm::outs().is_displayed(); -} - class TreePrinter { + using Color = llvm::raw_ostream::Color; + public: llvm::raw_ostream &out; - const bool ShowColors; bool Internal; - TreePrinter(llvm::raw_ostream &out) - : out(out), ShowColors(hasColors(out)), Internal(false) {} - - void setColor(llvm::raw_ostream::Colors Color) { - if (ShowColors) - out << llvm::sys::Process::OutputColor(Color, false, false); - } - - void resetColor() { - if (ShowColors) - out << llvm::sys::Process::ResetColor(); + TreePrinter(llvm::raw_ostream &out) : out(out), Internal(false) { + if (&out != &llvm::errs() && &out != &llvm::outs()) + out.disable_colors(); } static bool isIgnored(unsigned DiagID) { @@ -70,12 +57,11 @@ public: out.indent(Indent * 2); if (enabledByDefault(Group)) - setColor(llvm::raw_ostream::GREEN); + out << Color::GREEN; else - setColor(llvm::raw_ostream::YELLOW); + out << Color::YELLOW; - out << "-W" << Group.getName() << "\n"; - resetColor(); + out << "-W" << Group.getName() << "\n" << Color::RESET; ++Indent; for (const GroupRecord &GR : Group.subgroups()) { @@ -84,12 +70,10 @@ public: if (Internal) { for (const DiagnosticRecord &DR : Group.diagnostics()) { - if (ShowColors && !isIgnored(DR.DiagID)) - setColor(llvm::raw_ostream::GREEN); + if (!isIgnored(DR.DiagID)) + out << Color::GREEN; out.indent(Indent * 2); - out << DR.getName(); - resetColor(); - out << "\n"; + out << DR.getName() << Color::RESET << "\n"; } } } @@ -135,13 +119,9 @@ public: } void showKey() { - if (ShowColors) { - out << '\n'; - setColor(llvm::raw_ostream::GREEN); - out << "GREEN"; - resetColor(); - out << " = enabled by default\n\n"; - } + out << '\n' + << Color::GREEN << "GREEN" << Color::RESET + << " = enabled by default\n\n"; } };