[clang] [clang-format] Option to insert spaces before the closing */ (PR #162105)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 6 08:31:42 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-format

Author: Men-cotton (Men-cotton)

<details>
<summary>Changes</summary>

#<!-- -->160682 

---
Full diff: https://github.com/llvm/llvm-project/pull/162105.diff


6 Files Affected:

- (modified) clang/docs/ClangFormatStyleOptions.rst (+11) 
- (modified) clang/include/clang/Format/Format.h (+10) 
- (modified) clang/lib/Format/Format.cpp (+3) 
- (modified) clang/lib/Format/FormatTokenLexer.cpp (+19) 
- (modified) clang/lib/Format/FormatTokenLexer.h (+3) 
- (modified) clang/unittests/Format/FormatTestComments.cpp (+11) 


``````````diff
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index b746df5dab264..70582b6c40980 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6343,6 +6343,17 @@ the configuration (without a prefix: ``Auto``).
       case 1 : break;                         case 1: break;
     }                                       }
 
+.. _SpaceBeforeClosingBlockComment:
+
+**SpaceBeforeClosingBlockComment** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ <SpaceBeforeClosingBlockComment>`
+  If ``true``, a space is inserted immediately before the closing ``*/`` in
+  block comments that contain content.
+
+  .. code-block:: c++
+
+     true:                                  false:
+     /* comment */                  vs.     /* comment*/
+
 .. _SpaceBeforeCpp11BracedList:
 
 **SpaceBeforeCpp11BracedList** (``Boolean``) :versionbadge:`clang-format 7` :ref:`¶ <SpaceBeforeCpp11BracedList>`
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 3df5b92654094..7136fd2c5a4f8 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4684,6 +4684,15 @@ struct FormatStyle {
   /// \version 17
   bool SpaceBeforeJsonColon;
 
+  /// If ``true``, a space is inserted immediately before the closing ``*/`` in
+  /// block comments that contain content.
+  /// \code
+  ///    true:                                  false:
+  ///    /* comment */                  vs.     /* comment*/
+  /// \endcode
+  /// \version 21
+  bool SpaceBeforeClosingBlockComment;
+
   /// Different ways to put a space before opening parentheses.
   enum SpaceBeforeParensStyle : int8_t {
     /// This is **deprecated** and replaced by ``Custom`` below, with all
@@ -5611,6 +5620,7 @@ struct FormatStyle {
            SpaceAroundPointerQualifiers == R.SpaceAroundPointerQualifiers &&
            SpaceBeforeRangeBasedForLoopColon ==
                R.SpaceBeforeRangeBasedForLoopColon &&
+           SpaceBeforeClosingBlockComment == R.SpaceBeforeClosingBlockComment &&
            SpaceBeforeSquareBrackets == R.SpaceBeforeSquareBrackets &&
            SpaceInEmptyBraces == R.SpaceInEmptyBraces &&
            SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 686e54128d372..06292c75f27e0 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1222,6 +1222,8 @@ template <> struct MappingTraits<FormatStyle> {
     IO.mapOptional("SpaceBeforeInheritanceColon",
                    Style.SpaceBeforeInheritanceColon);
     IO.mapOptional("SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
+    IO.mapOptional("SpaceBeforeClosingBlockComment",
+                   Style.SpaceBeforeClosingBlockComment);
     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
     IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
     IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
@@ -1717,6 +1719,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.SpaceBeforeCtorInitializerColon = true;
   LLVMStyle.SpaceBeforeInheritanceColon = true;
   LLVMStyle.SpaceBeforeJsonColon = false;
+  LLVMStyle.SpaceBeforeClosingBlockComment = false;
   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
   LLVMStyle.SpaceBeforeParensOptions = {};
   LLVMStyle.SpaceBeforeParensOptions.AfterControlStatements = true;
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 86a5185a92a52..b48d1b7a82026 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -18,8 +18,11 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Format/Format.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Regex.h"
 
+#include <algorithm>
+
 namespace clang {
 namespace format {
 
@@ -1386,6 +1389,22 @@ FormatToken *FormatTokenLexer::getNextToken() {
     StringRef UntrimmedText = FormatTok->TokenText;
     FormatTok->TokenText = FormatTok->TokenText.rtrim(" \t\v\f");
     TrailingWhitespace = UntrimmedText.size() - FormatTok->TokenText.size();
+    if (Style.SpaceBeforeClosingBlockComment &&
+        FormatTok->TokenText.starts_with("/*") &&
+        FormatTok->TokenText.ends_with("*/")) {
+      StringRef Body = FormatTok->TokenText.drop_front(2).drop_back(2);
+      if (!Body.empty()) {
+        const char BeforeClosing = Body.back();
+        if (!isWhitespace(static_cast<unsigned char>(BeforeClosing))) {
+          llvm::SmallString<64> Adjusted(FormatTok->TokenText);
+          Adjusted.insert(Adjusted.end() - 2, ' ');
+          char *Storage = CommentTextAllocator.Allocate<char>(Adjusted.size());
+          std::copy(Adjusted.begin(), Adjusted.end(), Storage);
+          FormatTok->TokenText = StringRef(Storage, Adjusted.size());
+          FormatTok->Tok.setLength(FormatTok->TokenText.size());
+        }
+      }
+    }
   } else if (FormatTok->is(tok::raw_identifier)) {
     IdentifierInfo &Info = IdentTable.get(FormatTok->TokenText);
     FormatTok->Tok.setIdentifierInfo(&Info);
diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h
index 57c572af3defd..65b1199c1501c 100644
--- a/clang/lib/Format/FormatTokenLexer.h
+++ b/clang/lib/Format/FormatTokenLexer.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Allocator.h"
 
 #include <stack>
 
@@ -130,6 +131,8 @@ class FormatTokenLexer {
   unsigned FirstInLineIndex;
   SmallVector<FormatToken *, 16> Tokens;
 
+  llvm::BumpPtrAllocator CommentTextAllocator;
+
   llvm::SmallMapVector<IdentifierInfo *, TokenType, 8> Macros;
 
   llvm::SmallPtrSet<IdentifierInfo *, 8> MacrosSkippedByRemoveParentheses,
diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp
index 69026bce98705..e12e17c0e12a8 100644
--- a/clang/unittests/Format/FormatTestComments.cpp
+++ b/clang/unittests/Format/FormatTestComments.cpp
@@ -332,6 +332,17 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) {
   verifyNoCrash(StringRef("/*\\\0\n/", 6));
 }
 
+TEST_F(FormatTestComments, InsertsSpaceBeforeClosingBlockComment) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SpaceBeforeClosingBlockComment = true;
+
+  verifyFormat("foo(/* comment */);", "foo(/* comment*/);", Style);
+  verifyFormat("foo(/*Logger= */nullptr);", "foo(/*Logger=*/nullptr);", Style);
+  verifyFormat("/* comment */", Style);
+  verifyFormat("/* leading */\nint x;", Style);
+  verifyFormat("/* multiline\n */", Style);
+}
+
 TEST_F(FormatTestComments, KeepsParameterWithTrailingCommentsOnTheirOwnLine) {
   EXPECT_EQ("SomeFunction(a,\n"
             "             b, // comment\n"

``````````

</details>


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


More information about the cfe-commits mailing list