[clang] [clang-format] TableGen multi line string support. (PR #78032)

Björn Schäpers via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 14 12:02:42 PST 2024


================
@@ -778,45 +778,31 @@ void FormatTokenLexer::handleTableGenMultilineString() {
   if (MultiLineString->isNot(TT_TableGenMultiLineString))
     return;
 
-  bool PrevIsRBrace = false;
-  const char *FirstBreak = nullptr;
-  const char *LastBreak = nullptr;
-  const char *Begin = MultiLineString->TokenText.begin();
-  // Skip until }], the closer of multi line string found.
-  for (const char *Current = Begin, *End = Lex->getBuffer().end();
-       Current != End; ++Current) {
-    if (PrevIsRBrace && *Current == ']') {
-      // }] is the end of multi line string.
-      if (!FirstBreak)
-        FirstBreak = Current;
-      MultiLineString->TokenText = StringRef(Begin, Current - Begin + 1);
-      // ColumnWidth is only the width of the first line.
-      MultiLineString->ColumnWidth = encoding::columnWidthWithTabs(
-          StringRef(Begin, FirstBreak - Begin + 1),
-          MultiLineString->OriginalColumn, Style.TabWidth, Encoding);
-      if (LastBreak) {
-        // Set LastLineColumnWidth if multi line string has multiple lines.
-        MultiLineString->LastLineColumnWidth = encoding::columnWidthWithTabs(
-            StringRef(LastBreak + 1, Current - LastBreak),
-            MultiLineString->OriginalColumn, Style.TabWidth, Encoding);
-      }
-      resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(Current + 1)));
-      return;
-    }
-    PrevIsRBrace = false;
-    if (*Current == '\n') {
-      MultiLineString->IsMultiline = true;
-      // Assure LastBreak is not equal to FirstBreak.
-      if (!FirstBreak)
-        FirstBreak = Current;
-      LastBreak = Current;
-      continue;
-    }
-    if (*Current == '}') {
-      // Memorize '}'. If next character is ']', they are the closer.
-      PrevIsRBrace = true;
-      continue;
-    }
+  auto OpenOffset = Lex->getCurrentBufferOffset() - 2 /* "[{" */;
+  // "}]" is the end of multi line string.
+  auto CloseOffset = Lex->getBuffer().find("}]", OpenOffset);
+  if (CloseOffset == StringRef::npos)
+    return;
+  auto Text = Lex->getBuffer().substr(OpenOffset, CloseOffset + 2);
+  MultiLineString->TokenText = Text;
+  resetLexer(SourceMgr.getFileOffset(
+      Lex->getSourceLocation(Lex->getBufferLocation() - 2 + Text.size())));
+  // Set ColumnWidth and LastLineColumnWidth.
+  auto FirstLineText = Text;
+  auto FirstBreak = Text.find('\n');
+  if (FirstBreak != StringRef::npos) {
+    MultiLineString->IsMultiline = true;
+    FirstLineText = Text.substr(0, FirstBreak + 1);
+  }
+  // ColumnWidth holds only the width of the first line.
+  MultiLineString->ColumnWidth = encoding::columnWidthWithTabs(
+      FirstLineText, MultiLineString->OriginalColumn, Style.TabWidth, Encoding);
+  auto LastBreak = Text.rfind('\n');
+  if (LastBreak != StringRef::npos) {
+    // Set LastLineColumnWidth if it has multiple lines.
+    MultiLineString->LastLineColumnWidth = encoding::columnWidthWithTabs(
+        Text.substr(LastBreak + 1, Text.size()),
----------------
HazardyKnusperkeks wrote:

Is `Text.size()` correct? Or is this even needed? (I don't know the StringRef API, but for std::string_view you wouldn't need the 2nd argument if you want the remainder of the string.)

https://github.com/llvm/llvm-project/pull/78032


More information about the cfe-commits mailing list