Index: clang/include/clang/Frontend/TextDiagnostic.h =================================================================== --- clang/include/clang/Frontend/TextDiagnostic.h +++ clang/include/clang/Frontend/TextDiagnostic.h @@ -103,7 +103,8 @@ SmallVectorImpl &Ranges, ArrayRef Hints); - void emitSnippet(StringRef SourceLine); + void emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth, + unsigned LineNo); void emitParseableFixits(ArrayRef Hints, const SourceManager &SM); }; 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,bool> res = printableTextForNextCharacter(line, &i, DiagOpts->TabStop);