diff options
-rw-r--r-- | clang/include/clang/Frontend/TextDiagnosticPrinter.h | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/TextDiagnosticPrinter.cpp | 56 | ||||
-rw-r--r-- | clang/tools/clang-cc/clang-cc.cpp | 12 |
3 files changed, 71 insertions, 4 deletions
diff --git a/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/clang/include/clang/Frontend/TextDiagnosticPrinter.h index 3c9dcb8d9c1..f8408bdbd74 100644 --- a/clang/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/clang/include/clang/Frontend/TextDiagnosticPrinter.h @@ -40,6 +40,7 @@ class TextDiagnosticPrinter : public DiagnosticClient { bool PrintDiagnosticOption; bool PrintFixItInfo; unsigned MessageLength; + bool UseColors; public: TextDiagnosticPrinter(llvm::raw_ostream &os, @@ -48,14 +49,16 @@ public: bool printRangeInfo = true, bool printDiagnosticOption = true, bool printFixItInfo = true, - unsigned messageLength = 0) + unsigned messageLength = 0, + bool useColors = false) : OS(os), LangOpts(0), LastCaretDiagnosticWasNote(false), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics), ShowLocation(showLocation), PrintRangeInfo(printRangeInfo), PrintDiagnosticOption(printDiagnosticOption), PrintFixItInfo(printFixItInfo), - MessageLength(messageLength) {} + MessageLength(messageLength), + UseColors(useColors) {} void setLangOptions(const LangOptions *LO) { LangOpts = LO; diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp index b1c05336c23..6699c65f52d 100644 --- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -20,6 +20,20 @@ #include <algorithm> using namespace clang; +static const enum llvm::raw_ostream::Colors noteColor = + llvm::raw_ostream::BLACK; +static const enum llvm::raw_ostream::Colors fixitColor = + llvm::raw_ostream::GREEN; +static const enum llvm::raw_ostream::Colors caretColor = + llvm::raw_ostream::GREEN; +static const enum llvm::raw_ostream::Colors warningColor = + llvm::raw_ostream::MAGENTA; +static const enum llvm::raw_ostream::Colors errorColor = llvm::raw_ostream::RED; +static const enum llvm::raw_ostream::Colors fatalColor = llvm::raw_ostream::RED; +// used for changing only the bold attribute +static const enum llvm::raw_ostream::Colors savedColor = + llvm::raw_ostream::SAVEDCOLOR; + /// \brief Number of spaces to indent when word-wrapping. const unsigned WordWrapIndentation = 6; @@ -396,12 +410,22 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, // Emit what we have computed. OS << SourceLine << '\n'; + + if (UseColors) + OS.changeColor(caretColor, true); OS << CaretLine << '\n'; + if (UseColors) + OS.resetColor(); if (!FixItInsertionLine.empty()) { + if (UseColors) + // Print fixit line in color + OS.changeColor(fixitColor, false); if (PrintRangeInfo) OS << ' '; OS << FixItInsertionLine << '\n'; + if (UseColors) + OS.resetColor(); } } @@ -598,6 +622,8 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // Compute the column number. if (ShowLocation) { + if (UseColors) + OS.changeColor(savedColor, true); OS << PLoc.getFilename() << ':' << LineNo << ':'; if (ShowColumn) if (unsigned ColNo = PLoc.getColumn()) @@ -638,6 +664,19 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OS << ':'; } OS << ' '; + if (UseColors) + OS.resetColor(); + } + } + + if (UseColors) { + // Print diagnostic category in bold and color + switch (Level) { + case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); + case Diagnostic::Note: OS.changeColor(noteColor, true); break; + case Diagnostic::Warning: OS.changeColor(warningColor, true); break; + case Diagnostic::Error: OS.changeColor(errorColor, true); break; + case Diagnostic::Fatal: OS.changeColor(fatalColor, true); break; } } @@ -648,7 +687,10 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, case Diagnostic::Error: OS << "error: "; break; case Diagnostic::Fatal: OS << "fatal error: "; break; } - + + if (UseColors) + OS.resetColor(); + llvm::SmallString<100> OutStr; Info.FormatDiagnostic(OutStr); @@ -659,6 +701,16 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OutStr += ']'; } + if (UseColors) { + // Print warnings, errors and fatal errors in bold, no color + switch (Level) { + case Diagnostic::Warning: OS.changeColor(savedColor, true); break; + case Diagnostic::Error: OS.changeColor(savedColor, true); break; + case Diagnostic::Fatal: OS.changeColor(savedColor, true); break; + default: break; //don't bold notes + } + } + if (MessageLength) { // We will be word-wrapping the error message, so compute the // column number where we currently are (after printing the @@ -669,6 +721,8 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OS.write(OutStr.begin(), OutStr.size()); } OS << '\n'; + if (UseColors) + OS.resetColor(); // If caret diagnostics are enabled and we have location, we want to // emit the caret. However, we only do this if the location moved diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index 0e0a0727589..9e6afdd9463 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -328,6 +328,11 @@ MessageLength("fmessage-length", "within N columns or fewer, when possible."), llvm::cl::value_desc("N")); +static llvm::cl::opt<bool> +NoColorDiagnostic("fno-color-diagnostic", + llvm::cl::desc("Don't use colors when showing diagnostics " + "(automatically turned off if output is not a " + "terminal).")); //===----------------------------------------------------------------------===// // C++ Visualization. //===----------------------------------------------------------------------===// @@ -2150,6 +2155,10 @@ int main(int argc, char **argv) { if (MessageLength.getNumOccurrences() == 0) MessageLength.setValue(llvm::sys::Process::StandardErrColumns()); + if (!NoColorDiagnostic) { + NoColorDiagnostic.setValue(!llvm::sys::Process::StandardErrHasColors()); + } + DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), !NoShowColumn, !NoCaretDiagnostics, @@ -2157,7 +2166,8 @@ int main(int argc, char **argv) { PrintSourceRangeInfo, PrintDiagnosticOption, !NoDiagnosticsFixIt, - MessageLength)); + MessageLength, + !NoColorDiagnostic)); } else { DiagClient.reset(CreateHTMLDiagnosticClient(HTMLDiag)); } |