]> granicus.if.org Git - clang/commitdiff
[clang-format] Fix bug in block comment reflow that joins * and /
authorOwen Pan <owenpiano@gmail.com>
Fri, 3 May 2019 23:15:40 +0000 (23:15 +0000)
committerOwen Pan <owenpiano@gmail.com>
Fri, 3 May 2019 23:15:40 +0000 (23:15 +0000)
Fixes PR41213

Differential Revision: https://reviews.llvm.org/D61276

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359943 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/BreakableToken.cpp
lib/Format/BreakableToken.h
unittests/Format/FormatTest.cpp

index 5172c97f8afa045adfab20f174d31e6d4808b0ce..72886ed00736a1db3c6b7d755116914c8c8fbb73 100644 (file)
@@ -65,7 +65,8 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment,
 static BreakableToken::Split
 getCommentSplit(StringRef Text, unsigned ContentStartColumn,
                 unsigned ColumnLimit, unsigned TabWidth,
-                encoding::Encoding Encoding, const FormatStyle &Style) {
+                encoding::Encoding Encoding, const FormatStyle &Style,
+                bool DecorationEndsWithStar = false) {
   LLVM_DEBUG(llvm::dbgs() << "Comment split: \"" << Text
                           << "\", Column limit: " << ColumnLimit
                           << ", Content start: " << ContentStartColumn << "\n");
@@ -123,7 +124,10 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn,
     if (SpaceOffset == 1 && Text[SpaceOffset - 1] == '*')
       return BreakableToken::Split(StringRef::npos, 0);
     StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks);
-    StringRef AfterCut = Text.substr(SpaceOffset).ltrim(Blanks);
+    StringRef AfterCut = Text.substr(SpaceOffset);
+    // Don't trim the leading blanks if it would create a */ after the break.
+    if (!DecorationEndsWithStar || AfterCut.size() <= 1 || AfterCut[1] != '/')
+      AfterCut = AfterCut.ltrim(Blanks);
     return BreakableToken::Split(BeforeCut.size(),
                                  AfterCut.begin() - BeforeCut.end());
   }
@@ -452,6 +456,18 @@ BreakableBlockComment::BreakableBlockComment(
   });
 }
 
+BreakableToken::Split
+BreakableBlockComment::getSplit(unsigned LineIndex, unsigned TailOffset,
+                           unsigned ColumnLimit, unsigned ContentStartColumn,
+                           llvm::Regex &CommentPragmasRegex) const {
+  // Don't break lines matching the comment pragmas regex.
+  if (CommentPragmasRegex.match(Content[LineIndex]))
+    return Split(StringRef::npos, 0);
+  return getCommentSplit(Content[LineIndex].substr(TailOffset),
+                         ContentStartColumn, ColumnLimit, Style.TabWidth,
+                         Encoding, Style, Decoration.endswith("*"));
+}
+
 void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
                                              int IndentDelta) {
   // When in a preprocessor directive, the trailing backslash in a block comment
index dba763c6ad13560e74f61ae2335667fcb1abf747..72852d59f9c44a1ca64742626fa2f477bd9c5ae2 100644 (file)
@@ -361,6 +361,9 @@ public:
                         bool InPPDirective, encoding::Encoding Encoding,
                         const FormatStyle &Style, bool UseCRLF);
 
+  Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+                 unsigned ContentStartColumn,
+                 llvm::Regex &CommentPragmasRegex) const override;
   unsigned getRangeLength(unsigned LineIndex, unsigned Offset,
                           StringRef::size_type Length,
                           unsigned StartColumn) const override;
index ade52c753c43ea12e329afa1211f0cccc2501fc7..31f40b167081e3bdf77c27ee2a426c314d5a4ef4 100644 (file)
@@ -11150,6 +11150,24 @@ TEST_F(FormatTest, OptimizeBreakPenaltyVsExcess) {
   FormatStyle Style = getLLVMStyle();
   Style.ColumnLimit = 20;
 
+  // See PR41213
+  EXPECT_EQ("/*\n"
+            " *\t9012345\n"
+            " * /8901\n"
+            " */",
+            format("/*\n"
+                   " *\t9012345 /8901\n"
+                   " */",
+                   Style));
+  EXPECT_EQ("/*\n"
+            " *345678\n"
+            " *\t/8901\n"
+            " */",
+            format("/*\n"
+                   " *345678\t/8901\n"
+                   " */",
+                   Style));
+
   verifyFormat("int a; // the\n"
                "       // comment", Style);
   EXPECT_EQ("int a; /* first line\n"