/*static*/ void TextDiagnostic::printDiagnosticLevel(raw_ostream &OS, DiagnosticsEngine::Level Level, bool ShowColors) { if (ShowColors) { // Print diagnostic category in bold and color switch (Level) { case DiagnosticsEngine::Ignored: llvm_unreachable("Invalid diagnostic type"); case DiagnosticsEngine::Note: OS.changeColor(noteColor, true); break; case DiagnosticsEngine::Warning: OS.changeColor(warningColor, true); break; case DiagnosticsEngine::Error: OS.changeColor(errorColor, true); break; case DiagnosticsEngine::Fatal: OS.changeColor(fatalColor, true); break; } } switch (Level) { case DiagnosticsEngine::Ignored: llvm_unreachable("Invalid diagnostic type"); case DiagnosticsEngine::Note: OS << "note: "; break; case DiagnosticsEngine::Warning: OS << "warning: "; break; case DiagnosticsEngine::Error: OS << "error: "; break; case DiagnosticsEngine::Fatal: OS << "fatal error: "; break; } if (ShowColors) OS.resetColor(); }
/*static*/ void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS, DiagnosticsEngine::Level Level, StringRef Message, unsigned CurrentColumn, unsigned Columns, bool ShowColors) { if (ShowColors) { // Print warnings, errors and fatal errors in bold, no color switch (Level) { case DiagnosticsEngine::Warning: OS.changeColor(savedColor, true); break; case DiagnosticsEngine::Error: OS.changeColor(savedColor, true); break; case DiagnosticsEngine::Fatal: OS.changeColor(savedColor, true); break; default: break; //don't bold notes } } if (Columns) printWordWrapped(OS, Message, Columns, CurrentColumn); else OS << Message; if (ShowColors) OS.resetColor(); OS << '\n'; }
WithColor::WithColor(raw_ostream &OS, HighlightColor Color) : OS(OS) { // Detect color from terminal type unless the user passed the --color option. if (colorsEnabled(OS)) { switch (Color) { case HighlightColor::Address: OS.changeColor(raw_ostream::YELLOW); break; case HighlightColor::String: OS.changeColor(raw_ostream::GREEN); break; case HighlightColor::Tag: OS.changeColor(raw_ostream::BLUE); break; case HighlightColor::Attribute: OS.changeColor(raw_ostream::CYAN); break; case HighlightColor::Enumerator: OS.changeColor(raw_ostream::MAGENTA); break; case HighlightColor::Macro: OS.changeColor(raw_ostream::RED); break; case HighlightColor::Error: OS.changeColor(raw_ostream::RED, true); break; case HighlightColor::Warning: OS.changeColor(raw_ostream::MAGENTA, true); break; case HighlightColor::Note: OS.changeColor(raw_ostream::BLACK, true); break; } } }
/*static*/ void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS, DiagnosticsEngine::Level Level, StringRef Message, unsigned CurrentColumn, unsigned Columns, bool ShowColors) { bool Bold = false; if (ShowColors) { // Print warnings, errors and fatal errors in bold, no color switch (Level) { case DiagnosticsEngine::Warning: case DiagnosticsEngine::Error: case DiagnosticsEngine::Fatal: OS.changeColor(savedColor, true); Bold = true; break; default: break; //don't bold notes } } if (Columns) printWordWrapped(OS, Message, Columns, CurrentColumn, Bold); else { bool Normal = true; applyTemplateHighlighting(OS, Message, Normal, Bold); assert(Normal && "Formatting should have returned to normal"); } if (ShowColors) OS.resetColor(); OS << '\n'; }
/*static*/ void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental, StringRef Message, unsigned CurrentColumn, unsigned Columns, bool ShowColors) { bool Bold = false; if (ShowColors && !IsSupplemental) { // Print primary diagnostic messages in bold and without color, to visually // indicate the transition from continuation notes and other output. OS.changeColor(savedColor, true); Bold = true; } if (Columns) printWordWrapped(OS, Message, Columns, CurrentColumn, Bold); else { bool Normal = true; applyTemplateHighlighting(OS, Message, Normal, Bold); assert(Normal && "Formatting should have returned to normal"); } if (ShowColors) OS.resetColor(); OS << '\n'; }
/// \brief Add highlights to differences in template strings. static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str, bool &Normal, bool Bold) { for (unsigned i = 0, e = Str.size(); i < e; ++i) if (Str[i] != ToggleHighlight) { OS << Str[i]; } else { if (Normal) OS.changeColor(templateColor, true); else { OS.resetColor(); if (Bold) OS.changeColor(savedColor, true); } Normal = !Normal; } }
/// \brief Add highlights to differences in template strings. static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str, bool &Normal, bool Bold) { while (1) { size_t Pos = Str.find(ToggleHighlight); OS << Str.slice(0, Pos); if (Pos == StringRef::npos) break; Str = Str.substr(Pos + 1); if (Normal) OS.changeColor(templateColor, true); else { OS.resetColor(); if (Bold) OS.changeColor(savedColor, true); } Normal = !Normal; } }
/*static*/ void TextDiagnostic::printDiagnosticLevel(raw_ostream &OS, DiagnosticsEngine::Level Level, bool ShowColors, bool CLFallbackMode) { if (ShowColors) { // Print diagnostic category in bold and color switch (Level) { case DiagnosticsEngine::Ignored: llvm_unreachable("Invalid diagnostic type"); case DiagnosticsEngine::Note: OS.changeColor(noteColor, true); break; case DiagnosticsEngine::Remark: OS.changeColor(remarkColor, true); break; case DiagnosticsEngine::Warning: OS.changeColor(warningColor, true); break; case DiagnosticsEngine::Error: OS.changeColor(errorColor, true); break; case DiagnosticsEngine::Fatal: OS.changeColor(fatalColor, true); break; } } switch (Level) { case DiagnosticsEngine::Ignored: llvm_unreachable("Invalid diagnostic type"); case DiagnosticsEngine::Note: OS << "note"; break; case DiagnosticsEngine::Remark: OS << "remark"; break; case DiagnosticsEngine::Warning: OS << "warning"; break; case DiagnosticsEngine::Error: OS << "error"; break; case DiagnosticsEngine::Fatal: OS << "fatal error"; break; } // In clang-cl /fallback mode, print diagnostics as "error(clang):". This // makes it more clear whether a message is coming from clang or cl.exe, // and it prevents MSBuild from concluding that the build failed just because // there is an "error:" in the output. if (CLFallbackMode) OS << "(clang)"; OS << ": "; if (ShowColors) OS.resetColor(); }
WithColor::WithColor(raw_ostream &OS, enum HighlightColor Type) : OS(OS) { // Detect color from terminal type unless the user passed the --color option. if (UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE) { switch (Type) { case Address: OS.changeColor(raw_ostream::YELLOW); break; case String: OS.changeColor(raw_ostream::GREEN); break; case Tag: OS.changeColor(raw_ostream::BLUE); break; case Attribute: OS.changeColor(raw_ostream::CYAN); break; case Enumerator: OS.changeColor(raw_ostream::MAGENTA); break; case Macro: OS.changeColor(raw_ostream::RED); break; case Error: OS.changeColor(raw_ostream::RED, true); break; case Warning: OS.changeColor(raw_ostream::MAGENTA, true); break; case Note: OS.changeColor(raw_ostream::BLACK, true); break; } } }
void SourceCoverageView::renderLine(raw_ostream &OS, StringRef Line, ArrayRef<HighlightRange> Ranges) { if (Ranges.empty()) { OS << Line << "\n"; return; } if (Line.empty()) Line = " "; unsigned PrevColumnStart = 0; unsigned Start = 1; for (const auto &Range : Ranges) { if (PrevColumnStart == Range.ColumnStart) continue; // Show the unhighlighted part unsigned ColumnStart = PrevColumnStart = Range.ColumnStart; OS << Line.substr(Start - 1, ColumnStart - Start); // Show the highlighted part auto Color = Range.Kind == HighlightRange::NotCovered ? raw_ostream::RED : raw_ostream::CYAN; OS.changeColor(Color, false, true); unsigned ColumnEnd = std::min(Range.ColumnEnd, (unsigned)Line.size() + 1); OS << Line.substr(ColumnStart - 1, ColumnEnd - ColumnStart); Start = ColumnEnd; OS.resetColor(); } // Show the rest of the line OS << Line.substr(Start - 1, Line.size() - Start + 1); OS << "\n"; if (Options.Debug) { for (const auto &Range : Ranges) { errs() << "Highlighted line " << Range.Line << ", " << Range.ColumnStart << " -> "; if (Range.ColumnEnd == std::numeric_limits<unsigned>::max()) { errs() << "?\n"; } else { errs() << Range.ColumnEnd << "\n"; } } } }
void SchedulerStatistics::printSchedulerStats(raw_ostream &OS) const { OS << "\n\nSchedulers - " << "number of cycles where we saw N instructions issued:\n"; OS << "[# issued], [# cycles]\n"; const auto It = std::max_element(IssuedPerCycle.begin(), IssuedPerCycle.end()); unsigned Index = std::distance(IssuedPerCycle.begin(), It); bool HasColors = OS.has_colors(); for (unsigned I = 0, E = IssuedPerCycle.size(); I < E; ++I) { unsigned IPC = IssuedPerCycle[I]; if (!IPC) continue; if (I == Index && HasColors) OS.changeColor(raw_ostream::SAVEDCOLOR, true, false); OS << " " << I << ", " << IPC << " (" << format("%.1f", ((double)IPC / NumCycles) * 100) << "%)\n"; if (HasColors) OS.resetColor(); } }
void SMDiagnostic::print(const char *ProgName, raw_ostream &S, bool ShowColors, bool ShowKindLabel) const { // Display colors only if OS supports colors. ShowColors &= S.has_colors(); if (ShowColors) S.changeColor(raw_ostream::SAVEDCOLOR, true); if (ProgName && ProgName[0]) S << ProgName << ": "; if (!Filename.empty()) { if (Filename == "-") S << "<stdin>"; else S << Filename; if (LineNo != -1) { S << ':' << LineNo; if (ColumnNo != -1) S << ':' << (ColumnNo+1); } S << ": "; } if (ShowKindLabel) { switch (Kind) { case SourceMgr::DK_Error: if (ShowColors) S.changeColor(raw_ostream::RED, true); S << "error: "; break; case SourceMgr::DK_Warning: if (ShowColors) S.changeColor(raw_ostream::MAGENTA, true); S << "warning: "; break; case SourceMgr::DK_Note: if (ShowColors) S.changeColor(raw_ostream::BLACK, true); S << "note: "; break; } if (ShowColors) { S.resetColor(); S.changeColor(raw_ostream::SAVEDCOLOR, true); } } S << Message << '\n'; if (ShowColors) S.resetColor(); if (LineNo == -1 || ColumnNo == -1) return; // FIXME: If there are multibyte or multi-column characters in the source, all // our ranges will be wrong. To do this properly, we'll need a byte-to-column // map like Clang's TextDiagnostic. For now, we'll just handle tabs by // expanding them later, and bail out rather than show incorrect ranges and // misaligned fixits for any other odd characters. if (std::find_if(LineContents.begin(), LineContents.end(), isNonASCII) != LineContents.end()) { printSourceLine(S, LineContents); return; } size_t NumColumns = LineContents.size(); // Build the line with the caret and ranges. std::string CaretLine(NumColumns+1, ' '); // Expand any ranges. for (unsigned r = 0, e = Ranges.size(); r != e; ++r) { std::pair<unsigned, unsigned> R = Ranges[r]; std::fill(&CaretLine[R.first], &CaretLine[std::min((size_t)R.second, CaretLine.size())], '~'); } // Add any fix-its. // FIXME: Find the beginning of the line properly for multibyte characters. std::string FixItInsertionLine; buildFixItLine(CaretLine, FixItInsertionLine, FixIts, makeArrayRef(Loc.getPointer() - ColumnNo, LineContents.size())); // Finally, plop on the caret. if (unsigned(ColumnNo) <= NumColumns) CaretLine[ColumnNo] = '^'; else CaretLine[NumColumns] = '^'; // ... and remove trailing whitespace so the output doesn't wrap for it. We // know that the line isn't completely empty because it has the caret in it at // least. CaretLine.erase(CaretLine.find_last_not_of(' ')+1); printSourceLine(S, LineContents); if (ShowColors) S.changeColor(raw_ostream::GREEN, true); // Print out the caret line, matching tabs in the source line. for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) { if (i >= LineContents.size() || LineContents[i] != '\t') { S << CaretLine[i]; ++OutCol; continue; } // Okay, we have a tab. Insert the appropriate number of characters. do { S << CaretLine[i]; ++OutCol; } while ((OutCol % TabStop) != 0); } S << '\n'; if (ShowColors) S.resetColor(); // Print out the replacement line, matching tabs in the source line. if (FixItInsertionLine.empty()) return; for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) { if (i >= LineContents.size() || LineContents[i] != '\t') { S << FixItInsertionLine[i]; ++OutCol; continue; } // Okay, we have a tab. Insert the appropriate number of characters. do { S << FixItInsertionLine[i]; // FIXME: This is trying not to break up replacements, but then to re-sync // with the tabs between replacements. This will fail, though, if two // fix-it replacements are exactly adjacent, or if a fix-it contains a // space. Really we should be precomputing column widths, which we'll // need anyway for multibyte chars. if (FixItInsertionLine[i] != ' ') ++i; ++OutCol; } while (((OutCol % TabStop) != 0) && i != e); } S << '\n'; }
static int printICE(int Res, const char **Argv, raw_ostream &Err, bool insidebugreport, int argc, const char **argv, const sys::Path* orig_err) { Err << "Program arguments:"; while (*Argv) { Err << " " << Argv[0]; Argv++; } Err << "\n"; Err.changeColor(raw_ostream::RED, true); Err << "\nInternal compiler error: "; #ifdef LLVM_ON_UNIX Err << strsignal(Res); #else Err << " killed by signal " << Res; #endif Err << "!\n"; Err.resetColor(); Err.changeColor(raw_ostream::SAVEDCOLOR, true); if (insidebugreport) return 2; std::string prefix, prepath, tmperr, tarpath; prefix = getTmpDir(); if (prefix.empty()) { Err << "Cannot open locate location to store temporary files\n"; return 117; } tmperr = prefix + "/bugreport-preprocessed"; prepath = prefix + "/bugreport-tmperr"; tarpath = prefix + "/bugreport.tar"; sys::Path Tmp(prepath); sys::Path TmpErr(tmperr); sys::Path TmpOut(tarpath); std::string ErrMsg; ErrMsg.clear(); if (Tmp.createTemporaryFileOnDisk(true, &ErrMsg) || TmpErr.createTemporaryFileOnDisk(true, &ErrMsg) || TmpOut.createTemporaryFileOnDisk(true, &ErrMsg)) { Err << "Unable to create temporary file for bugreport: " << ErrMsg << "\n\n"; Err << "Please submit a bugreport at http://bugs.clamav.net\n" ; Err << "Please include the full sourcecode that caused this internal compiler error and the full error message!\n"; } else { ErrMsg.clear(); raw_fd_ostream TmpErrF(TmpErr.c_str(), ErrMsg); // Create version info for bugreport CompileFile(argc, argv, &Tmp, &TmpErr, TmpErrF, true, true); // Create preprocessed file for bugreport CompileFile(argc, argv, &Tmp, &TmpErr, TmpErrF, true); TmpErrF.close(); int fd = open(TmpOut.c_str(), O_WRONLY); if (fd < 0) { Err << "Cannot open file " << TmpOut.str() << ": " << strerror(errno) << "\n"; } else { chdir(orig_err->getDirname().str().c_str()); tar_addfile(fd, orig_err->getLast().str().c_str()); chdir(Tmp.getDirname().str().c_str()); tar_addfile(fd, Tmp.getLast().str().c_str()); chdir(TmpErr.getDirname().str().c_str()); tar_addfile(fd, TmpErr.getLast().str().c_str()); close(fd); } Tmp.eraseFromDisk(); TmpErr.eraseFromDisk(); Err << "Please submit a bugreport at http://bugs.clamav.net\n" ; Err << "Please compress and attach this file to the bugreport: " << TmpOut.str() << "\n"; } Err.resetColor(); return 42; }