[PATCH] D143099: [clang][lex] Expose findBeginningOfLine()

Kyle Edwards via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 1 12:10:37 PST 2023


KyleFromKitware created this revision.
KyleFromKitware added a reviewer: clang.
KyleFromKitware added a project: clang.
Herald added a project: All.
KyleFromKitware requested review of this revision.
Herald added a subscriber: cfe-commits.

And fix a few corner cases in which it returns the wrong answer.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143099

Files:
  clang/include/clang/Lex/Lexer.h
  clang/lib/Lex/Lexer.cpp
  clang/unittests/Lex/LexerTest.cpp


Index: clang/unittests/Lex/LexerTest.cpp
===================================================================
--- clang/unittests/Lex/LexerTest.cpp
+++ clang/unittests/Lex/LexerTest.cpp
@@ -660,4 +660,20 @@
   }
   EXPECT_TRUE(ToksView.empty());
 }
+
+TEST_F(LexerTest, FindBeginningOfLine) {
+  auto FindBeginningOfLineOffset = [](StringRef Buffer, unsigned int Offset) -> int {
+    return Lexer::findBeginningOfLine(Buffer, Offset) - Buffer.data();
+  };
+
+  EXPECT_EQ(FindBeginningOfLineOffset("int func();", 3), 0);
+  EXPECT_EQ(FindBeginningOfLineOffset("int func();", 0), 0);
+  EXPECT_EQ(FindBeginningOfLineOffset("int func1();\nint func2();", 13), 13);
+  EXPECT_EQ(FindBeginningOfLineOffset("int func1();\nint func2();", 12), 13);
+  EXPECT_EQ(FindBeginningOfLineOffset("int func1();\nint func2();", 11), 0);
+  EXPECT_EQ(FindBeginningOfLineOffset("int func1();\\\nint func2();", 14), 0);
+  EXPECT_EQ(FindBeginningOfLineOffset("int func1();\r\nint func2();", 13), 14);
+  EXPECT_EQ(FindBeginningOfLineOffset("\nint func();", 4), 1);
+  EXPECT_EQ(FindBeginningOfLineOffset("\\\nint func();", 5), 0);
+}
 } // anonymous namespace
Index: clang/lib/Lex/Lexer.cpp
===================================================================
--- clang/lib/Lex/Lexer.cpp
+++ clang/lib/Lex/Lexer.cpp
@@ -492,19 +492,22 @@
 
 /// Returns the pointer that points to the beginning of line that contains
 /// the given offset, or null if the offset if invalid.
-static const char *findBeginningOfLine(StringRef Buffer, unsigned Offset) {
+const char *Lexer::findBeginningOfLine(StringRef Buffer, unsigned Offset) {
   const char *BufStart = Buffer.data();
   if (Offset >= Buffer.size())
     return nullptr;
 
   const char *LexStart = BufStart + Offset;
-  for (; LexStart != BufStart; --LexStart) {
+  while (true) {
     if (isVerticalWhitespace(LexStart[0]) &&
         !Lexer::isNewLineEscaped(BufStart, LexStart)) {
       // LexStart should point at first character of logical line.
       ++LexStart;
       break;
     }
+    if (LexStart == BufStart)
+      break;
+    --LexStart;
   }
   return LexStart;
 }
@@ -525,7 +528,7 @@
   // Back up from the current location until we hit the beginning of a line
   // (or the buffer). We'll relex from that point.
   const char *StrData = Buffer.data() + LocInfo.second;
-  const char *LexStart = findBeginningOfLine(Buffer, LocInfo.second);
+  const char *LexStart = Lexer::findBeginningOfLine(Buffer, LocInfo.second);
   if (!LexStart || LexStart == StrData)
     return Loc;
 
Index: clang/include/clang/Lex/Lexer.h
===================================================================
--- clang/include/clang/Lex/Lexer.h
+++ clang/include/clang/Lex/Lexer.h
@@ -595,6 +595,10 @@
   static StringRef getIndentationForLine(SourceLocation Loc,
                                          const SourceManager &SM);
 
+  /// Returns the pointer that points to the beginning of line that contains
+  /// the given offset, or null if the offset if invalid.
+  static const char *findBeginningOfLine(StringRef Buffer, unsigned Offset);
+
   /// Check if this is the first time we're lexing the input file.
   bool isFirstTimeLexingFile() const { return IsFirstTimeLexingFile; }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143099.494030.patch
Type: text/x-patch
Size: 3217 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230201/0587a5e3/attachment-0001.bin>


More information about the cfe-commits mailing list