[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)

Gedare Bloom via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 9 14:15:19 PST 2024


https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522

>From 80d04b253933496d6e6c016f09f0bb987f29b2d4 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Mon, 17 Jul 2023 18:24:30 -0600
Subject: [PATCH 1/4] Add SpaceInParensOption for __attribute__ keyword

The __attribute((specifier-list)) currently is formatted based on the
SpacesInParensOptions.Other (previously, SpacesInParentheses). This change
allows finer control over addition of spaces between the consecutive parens,
and between the inner parens and the list of attribute specifiers.

Differential Revision: https://reviews.llvm.org/D155529
---
 clang/docs/ClangFormatStyleOptions.rst     |  7 +++++++
 clang/docs/ReleaseNotes.rst                |  2 ++
 clang/include/clang/Format/Format.h        | 19 ++++++++++++++-----
 clang/lib/Format/Format.cpp                |  2 ++
 clang/lib/Format/TokenAnnotator.cpp        | 16 ++++++++++++----
 clang/unittests/Format/ConfigParseTest.cpp | 13 +++++++++----
 clang/unittests/Format/FormatTest.cpp      |  7 +++++++
 7 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 3d42571e82d8a0..bfd393eb033459 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5625,6 +5625,13 @@ the configuration (without a prefix: ``Auto``).
       InConditionalStatements: true
       Other: true
 
+  * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
+
+    .. code-block:: c++
+
+       true:                                  false:
+       __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+
   * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
     (``for/if/while/switch...``).
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ddeb1186d65ac8..4a23286c2b61a7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1079,6 +1079,8 @@ clang-format
 - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property
   attributes (like ``nonatomic, strong, nullable``).
 - Add ``.clang-format-ignore`` files.
+- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions``
+  to control addition of spaces after the ``__attribute__`` keyword.
 
 libclang
 --------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 8604dea689f937..c9f0617711157d 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4515,6 +4515,12 @@ struct FormatStyle {
   ///     Other: true
   /// \endcode
   struct SpacesInParensCustom {
+    /// Put a space in parentheses of attribute specifiers.
+    /// \code
+    ///    true:                                  false:
+    ///    __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+    /// \endcode
+    bool InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
@@ -4548,17 +4554,20 @@ struct FormatStyle {
     bool Other;
 
     SpacesInParensCustom()
-        : InConditionalStatements(false), InCStyleCasts(false),
-          InEmptyParentheses(false), Other(false) {}
+        : InAttributeSpecifiers(false), InConditionalStatements(false),
+          InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
 
-    SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts,
+    SpacesInParensCustom(bool InAttributeSpecifiers,
+                         bool InConditionalStatements, bool InCStyleCasts,
                          bool InEmptyParentheses, bool Other)
-        : InConditionalStatements(InConditionalStatements),
+        : InAttributeSpecifiers(InAttributeSpecifiers),
+          InConditionalStatements(InConditionalStatements),
           InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
           Other(Other) {}
 
     bool operator==(const SpacesInParensCustom &R) const {
-      return InConditionalStatements == R.InConditionalStatements &&
+      return InAttributeSpecifiers == R.InAttributeSpecifiers &&
+             InConditionalStatements == R.InConditionalStatements &&
              InCStyleCasts == R.InCStyleCasts &&
              InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
     }
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index f798d555bf9929..97a457f2733ade 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -753,6 +753,7 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
 
 template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
   static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
+    IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
     IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
     IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
     IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);
@@ -1191,6 +1192,7 @@ template <> struct MappingTraits<FormatStyle> {
       if (SpacesInParentheses) {
         // set all options except InCStyleCasts and InEmptyParentheses
         // to true for backward compatibility.
+        Style.SpacesInParensOptions.InAttributeSpecifiers = true;
         Style.SpacesInParensOptions.InConditionalStatements = true;
         Style.SpacesInParensOptions.InCStyleCasts =
             SpacesInCStyleCastParentheses;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 8b43438c72dfe1..7dbc0d8f31819c 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3999,10 +3999,18 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   }
 
   if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
-    return (Right.is(TT_CastRParen) ||
-            (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
-               ? Style.SpacesInParensOptions.InCStyleCasts
-               : Style.SpacesInParensOptions.Other;
+    if (Right.is(TT_CastRParen) ||
+        (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) {
+      return Style.SpacesInParensOptions.InCStyleCasts;
+    }
+    const auto isAttributeParen = [](const FormatToken *Paren) {
+      return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
+    };
+    if (isAttributeParen(&Left) || isAttributeParen(&Right) ||
+        isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
+      return Style.SpacesInParensOptions.InAttributeSpecifiers;
+    }
+    return Style.SpacesInParensOptions.Other;
   }
   if (Right.isOneOf(tok::semi, tok::comma))
     return false;
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 0c9f68f303d865..d537be9a11a910 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -231,6 +231,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
@@ -626,19 +627,23 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(true, false, false, true));
+              FormatStyle::SpacesInParensCustom(true, true, false, false,
+                  true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(true, false, false, false));
+              FormatStyle::SpacesInParensCustom(false, true, false, false,
+                  false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, true, false, false));
+              FormatStyle::SpacesInParensCustom(false, false, true, false,
+                  false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, true, false));
+              FormatStyle::SpacesInParensCustom(false, false, false, true,
+                  false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 25ef5c680af862..97f397410f0002 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16741,6 +16741,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.Other = true;
   Spaces.SpacesInParensOptions.InConditionalStatements = true;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
   verifyFormat("do_something( ::globalVar );", Spaces);
   verifyFormat("call( x, y, z );", Spaces);
   verifyFormat("call();", Spaces);
@@ -16815,6 +16816,12 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
 
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
+  verifyFormat("void f( ) __attribute__( ( asdf ) );", Spaces);
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
+
   // Run the first set of tests again with:
   Spaces.SpaceAfterCStyleCast = true;
   verifyFormat("call(x, y, z);", Spaces);

>From 77f9c1a47dd173ee2a43dc6a0f7016018ba50624 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Tue, 9 Jan 2024 15:11:05 -0700
Subject: [PATCH 2/4] Create suboption for spaces in parens custom for
 non-consecutive parens

---
 clang/include/clang/Format/Format.h        | 29 ++++++++++++++++----
 clang/lib/Format/Format.cpp                | 10 ++++++-
 clang/lib/Format/TokenAnnotator.cpp        |  8 +++---
 clang/unittests/Format/ConfigParseTest.cpp | 31 +++++++++++++++-------
 clang/unittests/Format/FormatTest.cpp      | 13 ++++++---
 5 files changed, 69 insertions(+), 22 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index c9f0617711157d..8f6a9d9fc8c57b 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4506,6 +4506,16 @@ struct FormatStyle {
   /// \version 17
   SpacesInParensStyle SpacesInParens;
 
+  /// Selective control over spaces in parens.
+  enum SpacesInParensCustomStyle : int8_t {
+    /// Never put spaces in parens.
+    SIPCS_Never,
+    /// Only put spaces in parens not followed by the same consecutive parens.
+    SIPCS_NonConsecutive,
+    /// Always put spaces in parens.
+    SIPCS_Always
+  };
+
   /// Precise control over the spacing in parentheses.
   /// \code
   ///   # Should be declared this way:
@@ -4517,10 +4527,18 @@ struct FormatStyle {
   struct SpacesInParensCustom {
     /// Put a space in parentheses of attribute specifiers.
     /// \code
-    ///    true:                                  false:
-    ///    __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+    ///    Always:
+    ///    __attribute__( ( noreturn ) )
+    /// \endcode
+    /// \code
+    ///   NonConsecutive:
+    ///   _attribute__(( noreturn ))
+    /// \endcode
+    /// \code
+    ///   Never:
+    ///   _attribute__((noreturn))
     /// \endcode
-    bool InAttributeSpecifiers;
+    SpacesInParensCustomStyle InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
@@ -4554,10 +4572,10 @@ struct FormatStyle {
     bool Other;
 
     SpacesInParensCustom()
-        : InAttributeSpecifiers(false), InConditionalStatements(false),
+        : InAttributeSpecifiers(SIPCS_Never), InConditionalStatements(false),
           InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
 
-    SpacesInParensCustom(bool InAttributeSpecifiers,
+    SpacesInParensCustom(SpacesInParensCustomStyle InAttributeSpecifiers,
                          bool InConditionalStatements, bool InCStyleCasts,
                          bool InEmptyParentheses, bool Other)
         : InAttributeSpecifiers(InAttributeSpecifiers),
@@ -4585,6 +4603,7 @@ struct FormatStyle {
   ///   # Example of usage:
   ///   SpacesInParens: Custom
   ///   SpacesInParensOptions:
+  ///     InAttributeSpecifiers: NonConsecutive
   ///     InConditionalStatements: true
   ///     InEmptyParentheses: true
   /// \endcode
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 97a457f2733ade..8411401061e495 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -751,6 +751,14 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
   }
 };
 
+template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInParensCustomStyle> {
+  static void enumeration(IO &IO, FormatStyle::SpacesInParensCustomStyle &Value) {
+    IO.enumCase(Value, "Never", FormatStyle::SIPCS_Never);
+    IO.enumCase(Value, "NonConsecutive", FormatStyle::SIPCS_NonConsecutive);
+    IO.enumCase(Value, "Always", FormatStyle::SIPCS_Always);
+  }
+};
+
 template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
   static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
     IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
@@ -1192,7 +1200,7 @@ template <> struct MappingTraits<FormatStyle> {
       if (SpacesInParentheses) {
         // set all options except InCStyleCasts and InEmptyParentheses
         // to true for backward compatibility.
-        Style.SpacesInParensOptions.InAttributeSpecifiers = true;
+        Style.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Always;
         Style.SpacesInParensOptions.InConditionalStatements = true;
         Style.SpacesInParensOptions.InCStyleCasts =
             SpacesInCStyleCastParentheses;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 7dbc0d8f31819c..c2022e751bbb63 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4006,10 +4006,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     const auto isAttributeParen = [](const FormatToken *Paren) {
       return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
     };
-    if (isAttributeParen(&Left) || isAttributeParen(&Right) ||
-        isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
-      return Style.SpacesInParensOptions.InAttributeSpecifiers;
-    }
+    if (isAttributeParen(&Left) || isAttributeParen(&Right))
+      return Style.SpacesInParensOptions.InAttributeSpecifiers == FormatStyle::SIPCS_Always;
+    if (isAttributeParen(Left.Previous) || isAttributeParen(Right.Next))
+      return Style.SpacesInParensOptions.InAttributeSpecifiers != FormatStyle::SIPCS_Never;
     return Style.SpacesInParensOptions.Other;
   }
   if (Right.isOneOf(tok::semi, tok::comma))
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index d537be9a11a910..2d34ef9c7a9547 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -231,7 +231,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
@@ -619,6 +618,20 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               SpaceBeforeParensOptions.AfterPlacementOperator,
               FormatStyle::SpaceBeforeParensCustom::APO_Leave);
 
+  Style.SpacesInParens = FormatStyle::SIPO_Custom;
+  Style.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
+  CHECK_PARSE("SpacesInParensOptions:\n"
+              "  InAttributeSpecifiers: Always",
+              SpacesInParensOptions.InAttributeSpecifiers,
+              FormatStyle::SIPCS_Always);
+  CHECK_PARSE("SpacesInParensOptions:\n"
+              "  InAttributeSpecifiers: Never",
+              SpacesInParensOptions.InAttributeSpecifiers,
+              FormatStyle::SIPCS_Never);
+  CHECK_PARSE("SpacesInParensOptions:\n"
+              "  InAttributeSpecifiers: NonConsecutive",
+              SpacesInParensOptions.InAttributeSpecifiers,
+              FormatStyle::SIPCS_NonConsecutive);
   // For backward compatibility:
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
@@ -627,23 +640,23 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(true, true, false, false,
-                  true));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Always, true,
+                  false, false, true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, true, false, false,
-                  false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, true,
+                  false, false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, true, false,
-                  false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, false,
+                  true, false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, false, true,
-                  false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, false,
+                  false, true, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 97f397410f0002..898662bcd0e715 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16741,7 +16741,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.Other = true;
   Spaces.SpacesInParensOptions.InConditionalStatements = true;
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
+      FormatStyle::SIPCS_Always;
   verifyFormat("do_something( ::globalVar );", Spaces);
   verifyFormat("call( x, y, z );", Spaces);
   verifyFormat("call();", Spaces);
@@ -16816,11 +16817,17 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
 
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
+      FormatStyle::SIPCS_Always;
   verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
   verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__( ( asdf ) );", Spaces);
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
+      FormatStyle::SIPCS_NonConsecutive;
+  verifyFormat("SomeType *__attribute__(( attr )) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__(( naked )) foo(int bar)", Spaces);
+  verifyFormat("void f( ) __attribute__(( asdf ));", Spaces); 
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
 
   // Run the first set of tests again with:
   Spaces.SpaceAfterCStyleCast = true;

>From c5f103d2653b8569b24562d42891dbdf3ecb88c2 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Tue, 9 Jan 2024 15:14:44 -0700
Subject: [PATCH 3/4] Fix style problems

---
 clang/lib/Format/Format.cpp         |  9 ++++++---
 clang/lib/Format/TokenAnnotator.cpp | 12 ++++++++----
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 8411401061e495..35cd0e888617ff 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -751,8 +751,10 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
   }
 };
 
-template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInParensCustomStyle> {
-  static void enumeration(IO &IO, FormatStyle::SpacesInParensCustomStyle &Value) {
+template <>
+struct ScalarEnumerationTraits<FormatStyle::SpacesInParensCustomStyle> {
+  static void enumeration(IO &IO,
+                          FormatStyle::SpacesInParensCustomStyle &Value) {
     IO.enumCase(Value, "Never", FormatStyle::SIPCS_Never);
     IO.enumCase(Value, "NonConsecutive", FormatStyle::SIPCS_NonConsecutive);
     IO.enumCase(Value, "Always", FormatStyle::SIPCS_Always);
@@ -1200,7 +1202,8 @@ template <> struct MappingTraits<FormatStyle> {
       if (SpacesInParentheses) {
         // set all options except InCStyleCasts and InEmptyParentheses
         // to true for backward compatibility.
-        Style.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Always;
+        Style.SpacesInParensOptions.InAttributeSpecifiers =
+            FormatStyle::SIPCS_Always;
         Style.SpacesInParensOptions.InConditionalStatements = true;
         Style.SpacesInParensOptions.InCStyleCasts =
             SpacesInCStyleCastParentheses;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index c2022e751bbb63..d906987f50bbae 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4006,10 +4006,14 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     const auto isAttributeParen = [](const FormatToken *Paren) {
       return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
     };
-    if (isAttributeParen(&Left) || isAttributeParen(&Right))
-      return Style.SpacesInParensOptions.InAttributeSpecifiers == FormatStyle::SIPCS_Always;
-    if (isAttributeParen(Left.Previous) || isAttributeParen(Right.Next))
-      return Style.SpacesInParensOptions.InAttributeSpecifiers != FormatStyle::SIPCS_Never;
+    if (isAttributeParen(&Left) || isAttributeParen(&Right)) {
+      return Style.SpacesInParensOptions.InAttributeSpecifiers ==
+             FormatStyle::SIPCS_Always;
+    }
+    if (isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
+      return Style.SpacesInParensOptions.InAttributeSpecifiers !=
+             FormatStyle::SIPCS_Never;
+    }
     return Style.SpacesInParensOptions.Other;
   }
   if (Right.isOneOf(tok::semi, tok::comma))

>From 70850ae6ef8bc5a52f7d2ee7f19ed4340d1ec243 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Tue, 9 Jan 2024 15:15:06 -0700
Subject: [PATCH 4/4] dump format style

---
 clang/docs/ClangFormatStyleOptions.rst | 30 +++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index bfd393eb033459..42c4892a4d1894 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5610,6 +5610,7 @@ the configuration (without a prefix: ``Auto``).
     # Example of usage:
     SpacesInParens: Custom
     SpacesInParensOptions:
+      InAttributeSpecifiers: NonConsecutive
       InConditionalStatements: true
       InEmptyParentheses: true
 
@@ -5625,12 +5626,35 @@ the configuration (without a prefix: ``Auto``).
       InConditionalStatements: true
       Other: true
 
-  * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
+  * ``SpacesInParensCustomStyle InAttributeSpecifiers``
+    Put a space in parentheses of attribute specifiers.
 
     .. code-block:: c++
 
-       true:                                  false:
-       __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+       Always:
+       __attribute__( ( noreturn ) )
+
+    .. code-block:: c++
+
+      NonConsecutive:
+      _attribute__(( noreturn ))
+
+    .. code-block:: c++
+
+      Never:
+      _attribute__((noreturn))
+
+    Possible values:
+
+    * ``SIPCS_Never`` (in configuration: ``Never``)
+      Never put spaces in parens.
+
+    * ``SIPCS_NonConsecutive`` (in configuration: ``NonConsecutive``)
+      Only put spaces in parens not followed by the same consecutive parens.
+
+    * ``SIPCS_Always`` (in configuration: ``Always``)
+      Always put spaces in parens.
+
 
   * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
     (``for/if/while/switch...``).



More information about the cfe-commits mailing list