tbaeder created this revision. tbaeder added reviewers: aaron.ballman, cjdb. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Just putting this here because it's a pretty simple patch as it turns out. Caveats: 1. WIP, so I haven't fixed up or added any tests yet 2. We (probably) need a cmdline option to disable line numbers 3. With the default for `-fcaret-diagnostics-max-lines` being `1`, the line numbers don't make that much sense 4. caret, underline and fixits probably need a ` | ` prefix as well Sample output: ./array.cpp:98:1: error: static assertion failed due to requirement 'func()' 98 | static_assert( ^ 99 | // I wonder if this works. 100 | // Also, what if it doesn't? 101 | func()); ~~~~~~ 1 error generated. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D147875 Files: clang/include/clang/Frontend/TextDiagnostic.h clang/lib/Frontend/TextDiagnostic.cpp
Index: clang/lib/Frontend/TextDiagnostic.cpp =================================================================== --- clang/lib/Frontend/TextDiagnostic.cpp +++ clang/lib/Frontend/TextDiagnostic.cpp @@ -1121,6 +1121,24 @@ return FixItInsertionLine; } +static unsigned getNumDisplayWidth(unsigned N) { + if (N < 10) + return 1; + if (N < 100) + return 2; + if (N < 1'000) + return 3; + if (N < 10'000) + return 4; + if (N < 100'000) + return 5; + if (N < 1'000'000) + return 6; + if (N < 10'000'000) + return 7; + return 0; +} + /// Emit a code snippet and caret line. /// /// This routine emits a single line's code snippet and caret line.. @@ -1174,6 +1192,10 @@ if (auto OptionalRange = findLinesForRange(*I, FID, SM)) Lines = maybeAddRange(Lines, *OptionalRange, MaxLines); + unsigned MaxLineNoDisplayWidth = std::max(getNumDisplayWidth(Lines.first), + getNumDisplayWidth(Lines.second)); + unsigned HighlightIndent = MaxLineNoDisplayWidth + 4; + for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1; ++LineNo) { const char *BufStart = BufData.data(); const char *BufEnd = BufStart + BufData.size(); @@ -1249,9 +1271,12 @@ CaretLine.erase(CaretLine.end() - 1); // Emit what we have computed. - emitSnippet(SourceLine); + emitSnippet(SourceLine, MaxLineNoDisplayWidth, LineNo); if (!CaretLine.empty()) { + // Indent for line numbers + for (unsigned I = 0; I != HighlightIndent; ++I) + OS << ' '; if (DiagOpts->ShowColors) OS.changeColor(caretColor, true); OS << CaretLine << '\n'; @@ -1260,6 +1285,8 @@ } if (!FixItInsertionLine.empty()) { + for (unsigned I = 0; I != HighlightIndent; ++I) + OS << ' '; if (DiagOpts->ShowColors) // Print fixit line in color OS.changeColor(fixitColor, false); @@ -1275,7 +1302,8 @@ emitParseableFixits(Hints, SM); } -void TextDiagnostic::emitSnippet(StringRef line) { +void TextDiagnostic::emitSnippet(StringRef line, unsigned MaxLineNoDisplayWidth, + unsigned LineNo) { if (line.empty()) return; @@ -1284,6 +1312,16 @@ std::string to_print; bool print_reversed = false; + // Emit line number. + { + unsigned LineNoDisplayWidth = getNumDisplayWidth(LineNo); + OS << ' '; + for (unsigned I = LineNoDisplayWidth; I < MaxLineNoDisplayWidth; ++I) + OS << ' '; + OS << LineNo; + OS << " | "; + } + while (i<line.size()) { std::pair<SmallString<16>,bool> res = printableTextForNextCharacter(line, &i, DiagOpts->TabStop); Index: clang/include/clang/Frontend/TextDiagnostic.h =================================================================== --- clang/include/clang/Frontend/TextDiagnostic.h +++ clang/include/clang/Frontend/TextDiagnostic.h @@ -103,7 +103,8 @@ SmallVectorImpl<CharSourceRange> &Ranges, ArrayRef<FixItHint> Hints); - void emitSnippet(StringRef SourceLine); + void emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth, + unsigned LineNo); void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM); };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits