[clang] a0d83c3 - Revert "[clang][Diagnostics] Split source ranges into line ranges before..."
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 2 00:02:51 PDT 2023
Author: Timm Bäder
Date: 2023-06-02T09:02:34+02:00
New Revision: a0d83c3dc364688a223e0031d134e2a1bde4ba78
URL: https://github.com/llvm/llvm-project/commit/a0d83c3dc364688a223e0031d134e2a1bde4ba78
DIFF: https://github.com/llvm/llvm-project/commit/a0d83c3dc364688a223e0031d134e2a1bde4ba78.diff
LOG: Revert "[clang][Diagnostics] Split source ranges into line ranges before..."
This reverts commit fc1262bd58ac54ad0a0bfa9750254b81c742bbb5.
This causes build bot failures because of a parser test case:
https://lab.llvm.org/buildbot/#/builders/139/builds/41961
Added:
Modified:
clang/lib/Frontend/TextDiagnostic.cpp
clang/test/Misc/caret-diags-multiline.cpp
Removed:
################################################################################
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index c17508f37c7fd..ad5f1d45cb631 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -945,43 +945,87 @@ maybeAddRange(std::pair<unsigned, unsigned> A, std::pair<unsigned, unsigned> B,
return A;
}
-struct LineRange {
- unsigned LineNo;
- unsigned StartCol;
- unsigned EndCol;
-};
+/// Highlight a SourceRange (with ~'s) for any characters on LineNo.
+static void highlightRange(const CharSourceRange &R,
+ unsigned LineNo, FileID FID,
+ const SourceColumnMap &map,
+ std::string &CaretLine,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ if (!R.isValid()) return;
-/// Highlight \p R (with ~'s) on the current source line.
-static void highlightRange(const LineRange &R, const SourceColumnMap &Map,
- std::string &CaretLine) {
- // Pick the first non-whitespace column.
- unsigned StartColNo = R.StartCol;
- while (StartColNo < Map.getSourceLine().size() &&
- (Map.getSourceLine()[StartColNo] == ' ' ||
- Map.getSourceLine()[StartColNo] == '\t'))
- StartColNo = Map.startOfNextColumn(StartColNo);
-
- // Pick the last non-whitespace column.
- unsigned EndColNo =
- std::min(static_cast<size_t>(R.EndCol), Map.getSourceLine().size());
- while (EndColNo && (Map.getSourceLine()[EndColNo - 1] == ' ' ||
- Map.getSourceLine()[EndColNo - 1] == '\t'))
- EndColNo = Map.startOfPreviousColumn(EndColNo);
-
- // If the start/end passed each other, then we are trying to highlight a
- // range that just exists in whitespace. That most likely means we have
- // a multi-line highlighting range that covers a blank line.
- if (StartColNo > EndColNo)
- return;
+ SourceLocation Begin = R.getBegin();
+ SourceLocation End = R.getEnd();
+
+ unsigned StartLineNo = SM.getExpansionLineNumber(Begin);
+ if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
+ return; // No intersection.
+
+ unsigned EndLineNo = SM.getExpansionLineNumber(End);
+ if (EndLineNo < LineNo || SM.getFileID(End) != FID)
+ return; // No intersection.
+
+ // Compute the column number of the start.
+ unsigned StartColNo = 0;
+ if (StartLineNo == LineNo) {
+ StartColNo = SM.getExpansionColumnNumber(Begin);
+ if (StartColNo) --StartColNo; // Zero base the col #.
+ }
+
+ // Compute the column number of the end.
+ unsigned EndColNo = map.getSourceLine().size();
+ if (EndLineNo == LineNo) {
+ EndColNo = SM.getExpansionColumnNumber(End);
+ if (EndColNo) {
+ --EndColNo; // Zero base the col #.
+
+ // Add in the length of the token, so that we cover multi-char tokens if
+ // this is a token range.
+ if (R.isTokenRange())
+ EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts);
+ } else {
+ EndColNo = CaretLine.size();
+ }
+ }
+
+ assert(StartColNo <= EndColNo && "Invalid range!");
+
+ // Check that a token range does not highlight only whitespace.
+ if (R.isTokenRange()) {
+ // Pick the first non-whitespace column.
+ while (StartColNo < map.getSourceLine().size() &&
+ (map.getSourceLine()[StartColNo] == ' ' ||
+ map.getSourceLine()[StartColNo] == '\t'))
+ StartColNo = map.startOfNextColumn(StartColNo);
+
+ // Pick the last non-whitespace column.
+ if (EndColNo > map.getSourceLine().size())
+ EndColNo = map.getSourceLine().size();
+ while (EndColNo &&
+ (map.getSourceLine()[EndColNo-1] == ' ' ||
+ map.getSourceLine()[EndColNo-1] == '\t'))
+ EndColNo = map.startOfPreviousColumn(EndColNo);
+
+ // If the start/end passed each other, then we are trying to highlight a
+ // range that just exists in whitespace. That most likely means we have
+ // a multi-line highlighting range that covers a blank line.
+ if (StartColNo > EndColNo) {
+ assert(StartLineNo != EndLineNo && "trying to highlight whitespace");
+ StartColNo = EndColNo;
+ }
+ }
+
+ assert(StartColNo <= map.getSourceLine().size() && "Invalid range!");
+ assert(EndColNo <= map.getSourceLine().size() && "Invalid range!");
// Fill the range with ~'s.
- StartColNo = Map.byteToContainingColumn(StartColNo);
- EndColNo = Map.byteToContainingColumn(EndColNo);
+ StartColNo = map.byteToContainingColumn(StartColNo);
+ EndColNo = map.byteToContainingColumn(EndColNo);
assert(StartColNo <= EndColNo && "Invalid range!");
if (CaretLine.size() < EndColNo)
- CaretLine.resize(EndColNo, ' ');
- std::fill(CaretLine.begin() + StartColNo, CaretLine.begin() + EndColNo, '~');
+ CaretLine.resize(EndColNo,' ');
+ std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~');
}
static std::string buildFixItInsertionLine(FileID FID,
@@ -1056,57 +1100,6 @@ static unsigned getNumDisplayWidth(unsigned N) {
return L;
}
-/// Filter out invalid ranges, ranges that don't fit into the window of
-/// source lines we will print, and ranges from other files.
-///
-/// For the remaining ranges, convert them to simple LineRange structs,
-/// which only cover one line at a time.
-static SmallVector<LineRange>
-prepareAndFilterRanges(const SmallVectorImpl<CharSourceRange> &Ranges,
- const SourceManager &SM,
- const std::pair<unsigned, unsigned> &Lines, FileID FID,
- const LangOptions &LangOpts) {
- SmallVector<LineRange> LineRanges;
-
- for (const CharSourceRange &R : Ranges) {
- if (R.isInvalid())
- continue;
- SourceLocation Begin = R.getBegin();
- SourceLocation End = R.getEnd();
-
- unsigned StartLineNo = SM.getExpansionLineNumber(Begin);
- if (StartLineNo > Lines.second || SM.getFileID(Begin) != FID)
- continue;
-
- unsigned EndLineNo = SM.getExpansionLineNumber(End);
- if (EndLineNo < Lines.first || SM.getFileID(End) != FID)
- continue;
-
- unsigned StartColumn = SM.getExpansionColumnNumber(Begin);
- unsigned EndColumn = SM.getExpansionColumnNumber(End);
- if (R.isTokenRange())
- EndColumn += Lexer::MeasureTokenLength(End, SM, LangOpts);
-
- // Only a single line.
- if (StartLineNo == EndLineNo) {
- LineRanges.push_back({StartLineNo, StartColumn - 1, EndColumn - 1});
- continue;
- }
-
- // Start line.
- LineRanges.push_back({StartLineNo, StartColumn - 1, ~0u});
-
- // Middle lines.
- for (unsigned S = StartLineNo + 1; S != EndLineNo; ++S)
- LineRanges.push_back({S, 0, ~0u});
-
- // End line.
- LineRanges.push_back({EndLineNo, 0, EndColumn - 1});
- }
-
- return LineRanges;
-}
-
/// Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..
@@ -1173,9 +1166,6 @@ void TextDiagnostic::emitSnippetAndCaret(
OS.indent(MaxLineNoDisplayWidth + 2) << "| ";
};
- SmallVector<LineRange> LineRanges =
- prepareAndFilterRanges(Ranges, SM, Lines, FID, LangOpts);
-
for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1;
++LineNo, ++DisplayLineNo) {
// Rewind from the current position to the start of the line.
@@ -1207,10 +1197,8 @@ void TextDiagnostic::emitSnippetAndCaret(
std::string CaretLine;
// Highlight all of the characters covered by Ranges with ~ characters.
- for (const auto &LR : LineRanges) {
- if (LR.LineNo == LineNo)
- highlightRange(LR, sourceColMap, CaretLine);
- }
+ for (const auto &I : Ranges)
+ highlightRange(I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts);
// Next, insert the caret itself.
if (CaretLineNo == LineNo) {
diff --git a/clang/test/Misc/caret-diags-multiline.cpp b/clang/test/Misc/caret-diags-multiline.cpp
index 15368faa65b6f..baf8e5a219be3 100644
--- a/clang/test/Misc/caret-diags-multiline.cpp
+++ b/clang/test/Misc/caret-diags-multiline.cpp
@@ -14,9 +14,9 @@ void line(int);
// CHECK-NEXT: {{^}} if (cond) {
// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(1);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} } else {
-// CHECK-NEXT: {{^}} ~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~{{$}}
// CHECK-NEXT: note: initialize the variable
int f1(int cond) {
int a;
@@ -38,11 +38,11 @@ int f1(int cond) {
// CHECK-NEXT: {{^}} if (cond) {
// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(1);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(2);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} } else {
-// CHECK-NEXT: {{^}} ~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~{{$}}
// CHECK-NEXT: note: initialize the variable
int f2(int cond) {
int a;
@@ -65,13 +65,13 @@ int f2(int cond) {
// CHECK-NEXT: {{^}} if (cond) {
// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(1);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(2);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(3);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} } else {
-// CHECK-NEXT: {{^}} ~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~{{$}}
// CHECK-NEXT: note: initialize the variable
int f3(int cond) {
int a;
@@ -95,13 +95,13 @@ int f3(int cond) {
// CHECK-NEXT: {{^}} if (cond) {
// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(1);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(2);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(3);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(4);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: note: initialize the variable
int f4(int cond) {
int a;
@@ -126,13 +126,13 @@ int f4(int cond) {
// CHECK-NEXT: {{^}} if (cond) {
// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(1);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(2);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(3);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: {{^}} line(4);
-// CHECK-NEXT: {{^}} ~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
// CHECK-NEXT: note: initialize the variable
int f5(int cond) {
int a;
More information about the cfe-commits
mailing list