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

Gedare Bloom via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 11 12:57:24 PST 2024


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

>From 5e77775bec9fba56f34c7dd28ca866eef145035a 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/6] 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 ac9a0b70ed5daa..5dc7ad5298f83b 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5693,6 +5693,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 59732962caac65..f4e29df336b3a6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1102,6 +1102,8 @@ clang-format
   attributes (like ``nonatomic, strong, nullable``).
 - Add ``.clang-format-ignore`` files.
 - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``.
+- 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 5ffd63ee73fc36..95f15a3098044c 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4534,6 +4534,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
@@ -4567,17 +4573,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 ff5ed6c306f383..af4db7161be20b 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -752,6 +752,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);
@@ -1190,6 +1191,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 b31ecc840626f9..7f48042d064de4 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4005,10 +4005,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 18ecba270e3455..eed1a882badc2d 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);
@@ -632,19 +633,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 8f115fb8cbf0fb..58a36c7ba2fc26 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16821,6 +16821,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);
@@ -16895,6 +16896,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 912298798171a18d6962f997dbff18565e023082 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/6] 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 95f15a3098044c..ebc16c6f8d1292 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4525,6 +4525,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:
@@ -4536,10 +4546,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
@@ -4573,10 +4591,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),
@@ -4604,6 +4622,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 af4db7161be20b..9bcca72c1e2847 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -750,6 +750,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);
@@ -1191,7 +1199,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 7f48042d064de4..2e27eb7dfa9a4f 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4012,10 +4012,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 eed1a882badc2d..7fa1fb943b8595 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);
@@ -625,6 +624,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 = {};
@@ -633,23 +646,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 58a36c7ba2fc26..7c613b615e6dc0 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16821,7 +16821,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);
@@ -16896,11 +16897,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 53d7d27221c03062d2dd196b9ef63b7cbbdf9731 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/6] 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 9bcca72c1e2847..7f901f3382545f 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -750,8 +750,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);
@@ -1199,7 +1201,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 2e27eb7dfa9a4f..895b168dabb6b8 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4012,10 +4012,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 2d4e90dedb12da4a31aa1c12f5f999d001637ec6 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/6] 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 5dc7ad5298f83b..e1fc8164d97cee 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5678,6 +5678,7 @@ the configuration (without a prefix: ``Auto``).
     # Example of usage:
     SpacesInParens: Custom
     SpacesInParensOptions:
+      InAttributeSpecifiers: NonConsecutive
       InConditionalStatements: true
       InEmptyParentheses: true
 
@@ -5693,12 +5694,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...``).

>From 79b4c34eba3a96d869cf4bfc0f0d2ff358bf1b42 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 13:15:18 -0700
Subject: [PATCH 5/6] Use SIPCS for other sub-options

---
 clang/docs/ClangFormatStyleOptions.rst       | 111 ++++++++++++++++---
 clang/docs/ReleaseNotes.rst                  |   4 +
 clang/include/clang/Format/Format.h          |  80 +++++++++----
 clang/lib/Format/Format.cpp                  |  20 +++-
 clang/lib/Format/TokenAnnotator.cpp          |  18 +--
 clang/unittests/Format/ConfigParseTest.cpp   |  64 ++++++-----
 clang/unittests/Format/FormatTest.cpp        |  28 ++---
 clang/unittests/Format/FormatTestVerilog.cpp |   6 +-
 8 files changed, 244 insertions(+), 87 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index e1fc8164d97cee..9470ec31068096 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5679,7 +5679,7 @@ the configuration (without a prefix: ``Auto``).
     SpacesInParens: Custom
     SpacesInParensOptions:
       InAttributeSpecifiers: NonConsecutive
-      InConditionalStatements: true
+      InConditionalStatements: Always
       InEmptyParentheses: true
 
   Nested configuration flags:
@@ -5702,15 +5702,49 @@ the configuration (without a prefix: ``Auto``).
        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.
+
+
+  * ``SpacesInParensCustomStyle InConditionalStatements``
+    Put a space in parentheses only inside conditional statements
+    (``for/if/while/switch...``).
+
+    .. code-block:: c++
+
+       Always:
+       if ( ( a ) )  { ... }
+       while ( i < 5 )  { ... }
+
     .. code-block:: c++
 
       NonConsecutive:
-      _attribute__(( noreturn ))
+      if (( a )) { ... }
+      while ( i < 5 ) { ... }
 
     .. code-block:: c++
 
       Never:
-      _attribute__((noreturn))
+      if ((a)) { ... }
+      while (i < 5) { ... }
 
     Possible values:
 
@@ -5724,21 +5758,38 @@ the configuration (without a prefix: ``Auto``).
       Always put spaces in parens.
 
 
-  * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
-    (``for/if/while/switch...``).
+  * ``SpacesInParensCustomStyle InCStyleCasts``
+    Put a space in C style casts.
 
     .. code-block:: c++
 
-       true:                                  false:
-       if ( a )  { ... }              vs.     if (a) { ... }
-       while ( i < 5 )  { ... }               while (i < 5) { ... }
+      Always:                                  false:
+      x = ( int32 )y                 vs.     x = (int32)y
+      y = (( int (*)(int) )foo)(x);
+
+    .. code-block:: c++
 
-  * ``bool InCStyleCasts`` Put a space in C style casts.
+      NonConsecutive:
+      x = ( int32 )y
+      y = ((int (*)(int))foo)(x);
 
     .. code-block:: c++
 
-       true:                                  false:
-       x = ( int32 )y                 vs.     x = (int32)y
+      Never:
+      x = (int32)y
+      y = ((int (*)(int))foo)(x);
+
+    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 InEmptyParentheses`` Put a space in parentheses only if the parentheses are empty i.e. '()'
 
@@ -5752,12 +5803,44 @@ the configuration (without a prefix: ``Auto``).
          }                                    }
        }                                    }
 
-  * ``bool Other`` Put a space in parentheses not covered by preceding options.
+  * ``SpacesInParensCustomStyle Other``
+    Put a space in parentheses not covered by preceding options.
 
     .. code-block:: c++
 
-       true:                                  false:
-       t f( Deleted & ) & = delete;   vs.     t f(Deleted &) & = delete;
+      Always:
+      t f( Deleted & ) & = delete;
+      decltype( ( x ) )
+      x = ( (int32)y )
+      y = ( (int ( * )( int ))foo )( x );
+
+    .. code-block:: c++
+
+      NonConsecutive:
+      t f( Deleted & ) & = delete;
+      decltype(( x ))
+      x = ((int32))y
+      y = ((int ( * )( int ))foo)( x );
+
+    .. code-block:: c++
+
+      Never:
+      t f(Deleted &) & = delete;
+      decltype((x))
+      x = ((int32))y
+      y = ((int (*)(int))foo)(x);
+
+    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.
+
 
 
 .. _SpacesInParentheses:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f4e29df336b3a6..f0611c349a02de 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1104,6 +1104,10 @@ clang-format
 - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``.
 - Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions``
   to control addition of spaces after the ``__attribute__`` keyword.
+- Add ``NonConsecutive`` sub-option for ``InAttributeSpecifiers``,
+  ``InConditionalStatements``, ``InCStyleCasts``, and ``Other`` options of
+  ``SpacesInParensOptions`` to control addition of spaces between consecutive
+  parentheses.
 
 libclang
 --------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index ebc16c6f8d1292..2a6ec4a2e0a772 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4550,28 +4550,49 @@ struct FormatStyle {
     ///    __attribute__( ( noreturn ) )
     /// \endcode
     /// \code
-    ///   NonConsecutive:
-    ///   _attribute__(( noreturn ))
+    ///    NonConsecutive:
+    ///    _attribute__(( noreturn ))
     /// \endcode
     /// \code
-    ///   Never:
-    ///   _attribute__((noreturn))
+    ///    Never:
+    ///    _attribute__((noreturn))
     /// \endcode
     SpacesInParensCustomStyle InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
-    ///    true:                                  false:
-    ///    if ( a )  { ... }              vs.     if (a) { ... }
-    ///    while ( i < 5 )  { ... }               while (i < 5) { ... }
+    ///    Always:
+    ///    if ( ( a ) )  { ... }
+    ///    while ( i < 5 )  { ... }
+    /// \endcode
+    /// \code
+    ///   NonConsecutive:
+    ///   if (( a )) { ... }
+    ///   while ( i < 5 ) { ... }
     /// \endcode
-    bool InConditionalStatements;
+    /// \code
+    ///   Never:
+    ///   if ((a)) { ... }
+    ///   while (i < 5) { ... }
+    /// \endcode
+    SpacesInParensCustomStyle InConditionalStatements;
     /// Put a space in C style casts.
     /// \code
-    ///    true:                                  false:
-    ///    x = ( int32 )y                 vs.     x = (int32)y
+    ///   Always:                                  false:
+    ///   x = ( int32 )y                 vs.     x = (int32)y
+    ///   y = (( int (*)(int) )foo)(x);
     /// \endcode
-    bool InCStyleCasts;
+    /// \code
+    ///   NonConsecutive:
+    ///   x = ( int32 )y
+    ///   y = ((int (*)(int))foo)(x);
+    /// \endcode
+    /// \code
+    ///   Never:
+    ///   x = (int32)y
+    ///   y = ((int (*)(int))foo)(x);
+    /// \endcode
+    SpacesInParensCustomStyle InCStyleCasts;
     /// Put a space in parentheses only if the parentheses are empty i.e. '()'
     /// \code
     ///    true:                                false:
@@ -4585,18 +4606,39 @@ struct FormatStyle {
     bool InEmptyParentheses;
     /// Put a space in parentheses not covered by preceding options.
     /// \code
-    ///    true:                                  false:
-    ///    t f( Deleted & ) & = delete;   vs.     t f(Deleted &) & = delete;
+    ///   Always:
+    ///   t f( Deleted & ) & = delete;
+    ///   decltype( ( x ) )
+    ///   x = ( (int32)y )
+    ///   y = ( (int ( * )( int ))foo )( x );
+    /// \endcode
+    /// \code
+    ///   NonConsecutive:
+    ///   t f( Deleted & ) & = delete;
+    ///   decltype(( x ))
+    ///   x = ((int32))y
+    ///   y = ((int ( * )( int ))foo)( x );
+    /// \endcode
+    /// \code
+    ///   Never:
+    ///   t f(Deleted &) & = delete;
+    ///   decltype((x))
+    ///   x = ((int32))y 
+    ///   y = ((int (*)(int))foo)(x);
     /// \endcode
-    bool Other;
+    SpacesInParensCustomStyle Other;
 
     SpacesInParensCustom()
-        : InAttributeSpecifiers(SIPCS_Never), InConditionalStatements(false),
-          InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
+        : InAttributeSpecifiers(SIPCS_Never),
+          InConditionalStatements(SIPCS_Never),
+          InCStyleCasts(SIPCS_Never), InEmptyParentheses(false),
+          Other(SIPCS_Never) {}
 
     SpacesInParensCustom(SpacesInParensCustomStyle InAttributeSpecifiers,
-                         bool InConditionalStatements, bool InCStyleCasts,
-                         bool InEmptyParentheses, bool Other)
+                         SpacesInParensCustomStyle InConditionalStatements,
+                         SpacesInParensCustomStyle InCStyleCasts,
+                         bool InEmptyParentheses,
+                         SpacesInParensCustomStyle Other)
         : InAttributeSpecifiers(InAttributeSpecifiers),
           InConditionalStatements(InConditionalStatements),
           InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
@@ -4623,7 +4665,7 @@ struct FormatStyle {
   ///   SpacesInParens: Custom
   ///   SpacesInParensOptions:
   ///     InAttributeSpecifiers: NonConsecutive
-  ///     InConditionalStatements: true
+  ///     InConditionalStatements: Always
   ///     InEmptyParentheses: true
   /// \endcode
   /// \version 17
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 7f901f3382545f..044e3d1b8de49e 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -757,6 +757,10 @@ struct ScalarEnumerationTraits<FormatStyle::SpacesInParensCustomStyle> {
     IO.enumCase(Value, "Never", FormatStyle::SIPCS_Never);
     IO.enumCase(Value, "NonConsecutive", FormatStyle::SIPCS_NonConsecutive);
     IO.enumCase(Value, "Always", FormatStyle::SIPCS_Always);
+
+    // For backward compatibility.
+    IO.enumCase(Value, "true", FormatStyle::SIPCS_Always);
+    IO.enumCase(Value, "false", FormatStyle::SIPCS_Never);
   }
 };
 
@@ -1198,23 +1202,27 @@ template <> struct MappingTraits<FormatStyle> {
     if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&
         (SpacesInParentheses || SpaceInEmptyParentheses ||
          SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
+      const auto CoerceBooleanToSIPCS = [](const bool enabled) {
+        return enabled ? FormatStyle::SIPCS_Always : FormatStyle::SIPCS_Never;
+      };
       if (SpacesInParentheses) {
         // set all options except InCStyleCasts and InEmptyParentheses
-        // to true for backward compatibility.
+        // to true/Always for backward compatibility.
         Style.SpacesInParensOptions.InAttributeSpecifiers =
             FormatStyle::SIPCS_Always;
-        Style.SpacesInParensOptions.InConditionalStatements = true;
+        Style.SpacesInParensOptions.InConditionalStatements =
+            FormatStyle::SIPCS_Always;
         Style.SpacesInParensOptions.InCStyleCasts =
-            SpacesInCStyleCastParentheses;
+            CoerceBooleanToSIPCS(SpacesInCStyleCastParentheses);
         Style.SpacesInParensOptions.InEmptyParentheses =
             SpaceInEmptyParentheses;
-        Style.SpacesInParensOptions.Other = true;
+        Style.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
       } else {
         Style.SpacesInParensOptions = {};
         Style.SpacesInParensOptions.InConditionalStatements =
-            SpacesInConditionalStatement;
+            CoerceBooleanToSIPCS(SpacesInConditionalStatement);
         Style.SpacesInParensOptions.InCStyleCasts =
-            SpacesInCStyleCastParentheses;
+            CoerceBooleanToSIPCS(SpacesInCStyleCastParentheses);
         Style.SpacesInParensOptions.InEmptyParentheses =
             SpaceInEmptyParentheses;
       }
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 895b168dabb6b8..6eddebea4eb63c 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3549,8 +3549,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
     const FormatToken *Prev = Current->Previous;
     if (Current->is(TT_LineComment)) {
       if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
-        Current->SpacesRequiredBefore =
-            (Style.Cpp11BracedListStyle && !Style.SpacesInParensOptions.Other)
+        Current->SpacesRequiredBefore = (Style.Cpp11BracedListStyle && Style.SpacesInParensOptions.Other ==            FormatStyle::SIPCS_Never)
                 ? 0
                 : 1;
       } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
@@ -3968,7 +3967,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
        Right.is(tok::r_brace) && Right.isNot(BK_Block))) {
     return Style.SpacesInParensOptions.InEmptyParentheses;
   }
-  if (Style.SpacesInParensOptions.InConditionalStatements) {
+  if (Style.SpacesInParensOptions.InConditionalStatements != FormatStyle::SIPCS_Never) {
+  // TODO: check consecutive parens
     const FormatToken *LeftParen = nullptr;
     if (Left.is(tok::l_paren))
       LeftParen = &Left;
@@ -4004,10 +4004,12 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     return true;
   }
 
+  // TODO: check consecutive parens
   if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
     if (Right.is(TT_CastRParen) ||
         (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) {
-      return Style.SpacesInParensOptions.InCStyleCasts;
+      return Style.SpacesInParensOptions.InCStyleCasts !=
+             FormatStyle::SIPCS_Never;
     }
     const auto isAttributeParen = [](const FormatToken *Paren) {
       return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
@@ -4020,7 +4022,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
       return Style.SpacesInParensOptions.InAttributeSpecifiers !=
              FormatStyle::SIPCS_Never;
     }
-    return Style.SpacesInParensOptions.Other;
+    return Style.SpacesInParensOptions.Other != FormatStyle::SIPCS_Never;
   }
   if (Right.isOneOf(tok::semi, tok::comma))
     return false;
@@ -4243,7 +4245,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||
       (Right.is(tok::r_brace) && Right.MatchingParen &&
        Right.MatchingParen->isNot(BK_Block))) {
-    return !Style.Cpp11BracedListStyle || Style.SpacesInParensOptions.Other;
+    return !Style.Cpp11BracedListStyle || (Style.SpacesInParensOptions.Other !=
+                                           FormatStyle::SIPCS_Never);
   }
   if (Left.is(TT_BlockComment)) {
     // No whitespace in x(/*foo=*/1), except for JavaScript.
@@ -4929,7 +4932,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
            !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
                           tok::kw___super, TT_TemplateOpener,
                           TT_TemplateCloser)) ||
-           (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
+           (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other !=
+                                     FormatStyle::SIPCS_Always);
   }
   if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
     return ShouldAddSpacesInAngles();
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 7fa1fb943b8595..f9720663a687c9 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -231,10 +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, InCStyleCasts);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
 }
 
 #undef CHECK_PARSE_BOOL
@@ -624,20 +620,32 @@ 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);
+#define CHECK_SPACES_IN_PARENS_OPTIONS(FIELD)                                  \
+  do {                                                                         \
+    Style.SpacesInParens = FormatStyle::SIPO_Custom;                           \
+    Style.SpacesInParensOptions.FIELD = FormatStyle::SIPCS_Never;              \
+    CHECK_PARSE("SpacesInParensOptions:\n  " #FIELD ": Always",                \
+                SpacesInParensOptions.FIELD, FormatStyle::SIPCS_Always);       \
+    CHECK_PARSE("SpacesInParensOptions:\n  " #FIELD ": Never",                 \
+                SpacesInParensOptions.FIELD, FormatStyle::SIPCS_Never);        \
+    CHECK_PARSE("SpacesInParensOptions:\n  " #FIELD ": NonConsecutive",        \
+                SpacesInParensOptions.FIELD,                                   \
+                FormatStyle::SIPCS_NonConsecutive);                            \
+    /* For backwards compatibility */                                          \
+    CHECK_PARSE("SpacesInParensOptions:\n  " #FIELD ": false",                 \
+                SpacesInParensOptions.FIELD, FormatStyle::SIPCS_Never);        \
+    CHECK_PARSE("SpacesInParensOptions:\n  " #FIELD ": true",                  \
+                SpacesInParensOptions.FIELD, FormatStyle::SIPCS_Always);       \
+  } while (false)
+
+  CHECK_SPACES_IN_PARENS_OPTIONS(InAttributeSpecifiers);
+  CHECK_SPACES_IN_PARENS_OPTIONS(InConditionalStatements);
+  CHECK_SPACES_IN_PARENS_OPTIONS(InCStyleCasts);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
+  CHECK_SPACES_IN_PARENS_OPTIONS(Other);
+
+#undef CHECK_SPACES_IN_PARENS_OPTIONS
+
   // For backward compatibility:
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
@@ -646,23 +654,27 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Always, true,
-                  false, false, true));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Always,
+              FormatStyle::SIPCS_Always, FormatStyle::SIPCS_Never, false,
+              FormatStyle::SIPCS_Always));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, true,
-                  false, false, false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never,
+              FormatStyle::SIPCS_Always, FormatStyle::SIPCS_Never, false,
+              FormatStyle::SIPCS_Never));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, false,
-                  true, false, false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never,
+              FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Always, false,
+              FormatStyle::SIPCS_Never));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, false,
-                  false, true, false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never,
+              FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Never, true,
+              FormatStyle::SIPCS_Never));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 7c613b615e6dc0..208be4746c0080 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -11166,14 +11166,14 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
   FormatStyle Spaces = getLLVMStyle();
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InCStyleCasts = true;
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
   verifyFormat("Deleted &operator=(const Deleted &) & = default;", Spaces);
   verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;", Spaces);
   verifyFormat("Deleted &operator=(const Deleted &) &;", Spaces);
   verifyFormat("SomeType MemberFunction(const Deleted &) &;", Spaces);
 
-  Spaces.SpacesInParensOptions.InCStyleCasts = false;
-  Spaces.SpacesInParensOptions.Other = true;
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
+  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
   verifyFormat("Deleted &operator=( const Deleted & ) & = default;", Spaces);
   verifyFormat("SomeType MemberFunction( const Deleted & ) & = delete;",
                Spaces);
@@ -13739,7 +13739,7 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
   FormatStyle SpaceBetweenBraces = getLLVMStyle();
   SpaceBetweenBraces.SpacesInAngles = FormatStyle::SIAS_Always;
   SpaceBetweenBraces.SpacesInParens = FormatStyle::SIPO_Custom;
-  SpaceBetweenBraces.SpacesInParensOptions.Other = true;
+  SpaceBetweenBraces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
   SpaceBetweenBraces.SpacesInSquareBrackets = true;
   verifyFormat("vector< int > x{ 1, 2, 3, 4 };", SpaceBetweenBraces);
   verifyFormat("f( {}, { {}, {} }, MyMap[ { k, v } ] );", SpaceBetweenBraces);
@@ -16819,8 +16819,9 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.Other = true;
-  Spaces.SpacesInParensOptions.InConditionalStatements = true;
+  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_Always;
   Spaces.SpacesInParensOptions.InAttributeSpecifiers =
       FormatStyle::SIPCS_Always;
   verifyFormat("do_something( ::globalVar );", Spaces);
@@ -16855,7 +16856,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InCStyleCasts = true;
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
   verifyFormat("Type *A = ( Type * )P;", Spaces);
   verifyFormat("Type *A = ( vector<Type *, int *> )P;", Spaces);
   verifyFormat("x = ( int32 )y;", Spaces);
@@ -16869,7 +16870,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.InEmptyParentheses = true;
-  Spaces.SpacesInParensOptions.InCStyleCasts = true;
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
   verifyFormat("call(x, y, z);", Spaces);
   verifyFormat("call( );", Spaces);
   verifyFormat("std::function<void(int, int)> callback;", Spaces);
@@ -16945,7 +16946,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
 
   // Run subset of tests again with:
-  Spaces.SpacesInParensOptions.InCStyleCasts = false;
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
   Spaces.SpaceAfterCStyleCast = true;
   verifyFormat("while ((bool) 1)\n"
                "  continue;",
@@ -24052,10 +24053,10 @@ TEST_F(FormatTest, AtomicQualifier) {
   verifyFormat("vector<_Atomic(uint64_t)* attr> x;", Style);
 
   Style.SpacesInParens = FormatStyle::SIPO_Custom;
-  Style.SpacesInParensOptions.InCStyleCasts = true;
+  Style.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
   verifyFormat("x = ( _Atomic(uint64_t) )*a;", Style);
-  Style.SpacesInParensOptions.InCStyleCasts = false;
-  Style.SpacesInParensOptions.Other = true;
+  Style.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
+  Style.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
   verifyFormat("x = (_Atomic( uint64_t ))*a;", Style);
   verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);
 }
@@ -24119,7 +24120,8 @@ TEST_F(FormatTest, SpacesInConditionalStatement) {
   Spaces.IfMacros.clear();
   Spaces.IfMacros.push_back("MYIF");
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
-  Spaces.SpacesInParensOptions.InConditionalStatements = true;
+  Spaces.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_Always;
   verifyFormat("for ( int i = 0; i; i++ )\n  continue;", Spaces);
   verifyFormat("if ( !a )\n  return;", Spaces);
   verifyFormat("if ( a )\n  return;", Spaces);
diff --git a/clang/unittests/Format/FormatTestVerilog.cpp b/clang/unittests/Format/FormatTestVerilog.cpp
index fcda05df182687..af3632dcc5d62f 100644
--- a/clang/unittests/Format/FormatTestVerilog.cpp
+++ b/clang/unittests/Format/FormatTestVerilog.cpp
@@ -874,7 +874,8 @@ TEST_F(FormatTestVerilog, If) {
                "    x = x;",
                Style);
   Style.SpacesInParens = FormatStyle::SIPO_Custom;
-  Style.SpacesInParensOptions.InConditionalStatements = true;
+  Style.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_Always;
   verifyFormat("if ( x )\n"
                "  x = x;\n"
                "else if ( x )\n"
@@ -971,7 +972,8 @@ TEST_F(FormatTestVerilog, Loop) {
                "end");
   auto Style = getDefaultStyle();
   Style.SpacesInParens = FormatStyle::SIPO_Custom;
-  Style.SpacesInParensOptions.InConditionalStatements = true;
+  Style.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_Always;
   verifyFormat("foreach ( x[x] )\n"
                "  x = x;",
                Style);

>From e161b13aa3a3fb3e7da698741aac967b27dcae4d Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 13:57:05 -0700
Subject: [PATCH 6/6] fix local formatting

---
 clang/lib/Format/TokenAnnotator.cpp | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 6eddebea4eb63c..fc924912ec1fbb 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3549,7 +3549,9 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
     const FormatToken *Prev = Current->Previous;
     if (Current->is(TT_LineComment)) {
       if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
-        Current->SpacesRequiredBefore = (Style.Cpp11BracedListStyle && Style.SpacesInParensOptions.Other ==            FormatStyle::SIPCS_Never)
+        Current->SpacesRequiredBefore =
+            (Style.Cpp11BracedListStyle &&
+             Style.SpacesInParensOptions.Other == FormatStyle::SIPCS_Never)
                 ? 0
                 : 1;
       } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
@@ -3967,8 +3969,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
        Right.is(tok::r_brace) && Right.isNot(BK_Block))) {
     return Style.SpacesInParensOptions.InEmptyParentheses;
   }
-  if (Style.SpacesInParensOptions.InConditionalStatements != FormatStyle::SIPCS_Never) {
-  // TODO: check consecutive parens
+  if (Style.SpacesInParensOptions.InConditionalStatements !=
+      FormatStyle::SIPCS_Never) {
+    // TODO: check consecutive parens
     const FormatToken *LeftParen = nullptr;
     if (Left.is(tok::l_paren))
       LeftParen = &Left;
@@ -4245,8 +4248,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||
       (Right.is(tok::r_brace) && Right.MatchingParen &&
        Right.MatchingParen->isNot(BK_Block))) {
-    return !Style.Cpp11BracedListStyle || (Style.SpacesInParensOptions.Other !=
-                                           FormatStyle::SIPCS_Never);
+    return !Style.Cpp11BracedListStyle ||
+           (Style.SpacesInParensOptions.Other != FormatStyle::SIPCS_Never);
   }
   if (Left.is(TT_BlockComment)) {
     // No whitespace in x(/*foo=*/1), except for JavaScript.
@@ -4932,8 +4935,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
            !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
                           tok::kw___super, TT_TemplateOpener,
                           TT_TemplateCloser)) ||
-           (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other !=
-                                     FormatStyle::SIPCS_Always);
+           (Left.is(tok::l_paren) &&
+            Style.SpacesInParensOptions.Other != FormatStyle::SIPCS_Always);
   }
   if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
     return ShouldAddSpacesInAngles();



More information about the cfe-commits mailing list