[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