[clang] [clang-format] Add SpacesInParensOption for filtering repeated parens (PR #77522)

Gedare Bloom via cfe-commits cfe-commits at lists.llvm.org
Fri May 31 11:43:37 PDT 2024


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

>From 992ab357f5dd8908bffd2f7a74f90d8871a12ecf 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 01/31] 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 6d092219877f9..e3cb63f2e5de4 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6221,6 +6221,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 7af5869d21768..b28ed8daff819 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -895,6 +895,8 @@ clang-format
 - Handles Java ``switch`` expressions.
 - Adds ``AllowShortCaseExpressionOnASingleLine`` option.
 - Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``.
+- 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 74893f23210cd..a246909333c8f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4648,6 +4648,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
@@ -4681,17 +4687,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 52005a6c881f3..f4fb3b93994c4 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -720,6 +720,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);
@@ -1176,6 +1177,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 7c4c76a91f2c5..73d9789f63f30 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4385,10 +4385,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 82e72f08ffb5e..e7425c47ac552 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -235,6 +235,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
   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);
@@ -620,19 +621,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 6f57f10e12e88..fb9a1a918cd2d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17085,6 +17085,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);
@@ -17159,6 +17160,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 e270a377ee48cc6fa2c13d3dc9062876a593e5d6 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 02/31] 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 | 49 ++++++++++++++++++----
 clang/unittests/Format/FormatTest.cpp      | 13 ++++--
 5 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index a246909333c8f..85ee30aa76ee0 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4639,6 +4639,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:
@@ -4650,10 +4660,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
@@ -4687,10 +4705,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),
@@ -4718,6 +4736,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 f4fb3b93994c4..7dd74b8c311da 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -718,6 +718,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);
@@ -1177,7 +1185,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 73d9789f63f30..5eeccc3c8fef3 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4392,10 +4392,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 e7425c47ac552..609df79705296 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -235,7 +235,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
   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);
@@ -613,6 +612,38 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               SpaceBeforeParens,
               FormatStyle::SBPO_ControlStatementsExceptControlMacros);
 
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Custom;
+  Style.SpaceBeforeParensOptions.AfterPlacementOperator =
+      FormatStyle::SpaceBeforeParensCustom::APO_Always;
+  CHECK_PARSE("SpaceBeforeParensOptions:\n"
+              "  AfterPlacementOperator: Never",
+              SpaceBeforeParensOptions.AfterPlacementOperator,
+              FormatStyle::SpaceBeforeParensCustom::APO_Never);
+
+  CHECK_PARSE("SpaceBeforeParensOptions:\n"
+              "  AfterPlacementOperator: Always",
+              SpaceBeforeParensOptions.AfterPlacementOperator,
+              FormatStyle::SpaceBeforeParensCustom::APO_Always);
+
+  CHECK_PARSE("SpaceBeforeParensOptions:\n"
+              "  AfterPlacementOperator: Leave",
+              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 = {};
@@ -621,23 +652,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 fb9a1a918cd2d..847f2e09ee90a 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17085,7 +17085,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);
@@ -17160,11 +17161,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 280725082c8d4de3d81e1634d8240210f49a2143 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 03/31] 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 7dd74b8c311da..b445db512b9a2 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -718,8 +718,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);
@@ -1185,7 +1187,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 5eeccc3c8fef3..e0a40407fcc92 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4392,10 +4392,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 40e86b7135de702387bf427583ce3910bca1ee0e 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 04/31] 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 e3cb63f2e5de4..380f2c3b8c5cd 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6206,6 +6206,7 @@ the configuration (without a prefix: ``Auto``).
     # Example of usage:
     SpacesInParens: Custom
     SpacesInParensOptions:
+      InAttributeSpecifiers: NonConsecutive
       InConditionalStatements: true
       InEmptyParentheses: true
 
@@ -6221,12 +6222,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 ceb45b773fbfcdad41731855691cd917e952c3b4 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 05/31] 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 380f2c3b8c5cd..e71cc8deaf8e9 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6207,7 +6207,7 @@ the configuration (without a prefix: ``Auto``).
     SpacesInParens: Custom
     SpacesInParensOptions:
       InAttributeSpecifiers: NonConsecutive
-      InConditionalStatements: true
+      InConditionalStatements: Always
       InEmptyParentheses: true
 
   Nested configuration flags:
@@ -6230,15 +6230,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:
 
@@ -6252,21 +6286,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. '()'
 
@@ -6280,12 +6331,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 b28ed8daff819..3b0ecb5168092 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -897,6 +897,10 @@ clang-format
 - Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``.
 - 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 85ee30aa76ee0..7fb67c6674dc0 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4664,28 +4664,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:
@@ -4699,18 +4720,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),
@@ -4737,7 +4779,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 b445db512b9a2..109cc61adc58f 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -725,6 +725,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);
   }
 };
 
@@ -1184,23 +1188,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 e0a40407fcc92..80c66debdd906 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3923,8 +3923,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)) {
@@ -4346,7 +4345,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;
@@ -4384,10 +4384,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);
@@ -4400,7 +4402,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;
@@ -4630,7 +4632,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.
@@ -5347,7 +5350,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 609df79705296..aed757aabca62 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -235,10 +235,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
   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
@@ -630,20 +626,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 = {};
@@ -652,23 +660,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 847f2e09ee90a..60e5df110694d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -11381,14 +11381,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);
@@ -13993,7 +13993,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);
@@ -17083,8 +17083,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);
@@ -17119,7 +17120,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);
@@ -17133,7 +17134,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);
@@ -17209,7 +17210,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;",
@@ -24401,10 +24402,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);
 }
@@ -24477,7 +24478,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 abebf9f7d4c78..5078cbe3b66d4 100644
--- a/clang/unittests/Format/FormatTestVerilog.cpp
+++ b/clang/unittests/Format/FormatTestVerilog.cpp
@@ -885,7 +885,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"
@@ -982,7 +983,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 e6ff3b6a01c8d29cac82aedf8c9c5f9a21f7cc86 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 06/31] 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 80c66debdd906..cf5ce8a638fb5 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3923,7 +3923,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)) {
@@ -4345,8 +4347,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;
@@ -4632,8 +4635,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.
@@ -5350,8 +5353,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();

>From c40e95449881e1d104433bf866031a4cc4ab8f94 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 15:06:22 -0700
Subject: [PATCH 07/31] add test cases

---
 clang/unittests/Format/FormatTest.cpp | 191 ++++++++++++++++++++++++++
 1 file changed, 191 insertions(+)

diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 60e5df110694d..0af4c02a1afa4 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17080,6 +17080,23 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f() __attribute__((asdf));", Spaces);
+  verifyFormat("x = (int32)y;", Spaces);
+  verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
+  verifyFormat("decltype(x) y = 42;", Spaces);
+  verifyFormat("decltype((x)) y = z;", Spaces);
+  verifyFormat("decltype((foo())) a = foo();", Spaces);
+  verifyFormat("decltype((bar(10))) a = bar(11);", Spaces);
+  verifyFormat("if ((x - y) && (a ^ b))\n"
+               "  f();\n",
+               Spaces);
+  verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
+               "  foo(i);",
+               Spaces);
+  verifyFormat("switch (x * (y + z)) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
@@ -17117,6 +17134,23 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
   verifyFormat("void __attribute__( ( naked ) ) foo( int bar )", Spaces);
   verifyFormat("void f() __attribute__( ( asdf ) );", Spaces);
+  verifyFormat("x = (int32)y;", Spaces);
+  verifyFormat("y = ( (int (*)(int))foo )( x );", Spaces);
+  verifyFormat("decltype( x ) y = 42;", Spaces);
+  verifyFormat("decltype( ( x ) ) y = z;", Spaces);
+  verifyFormat("decltype( ( foo() ) ) a = foo();", Spaces);
+  verifyFormat("decltype( ( bar( 10 ) ) ) a = bar( 11 );", Spaces);
+  verifyFormat("if ( ( x - y ) && ( a ^ b ) )\n"
+               "  f();\n",
+               Spaces);
+  verifyFormat("for ( int i = 0; i < 10; i = ( i+1 ) )\n"
+               "  foo( i );",
+               Spaces);
+  verifyFormat("switch ( x * ( y + z ) ) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
@@ -17129,6 +17163,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("#define AA(X) sizeof((( X * )NULL)->a)", Spaces);
   verifyFormat("my_int a = ( my_int )sizeof(int);", Spaces);
   verifyFormat("#define x (( int )-1)", Spaces);
+  verifyFormat("y = (( int (*)(int) )foo)(x);", Spaces);
 
   // Run the first set of tests again with:
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
@@ -17161,7 +17196,27 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
+  verifyFormat("x = ( int32 )y;", Spaces);
+  verifyFormat("y = (( int (*)(int) )foo)(x);", Spaces);
+  verifyFormat("decltype(x) y = 42;", Spaces);
+  verifyFormat("decltype((x)) y = z;", Spaces);
+  verifyFormat("decltype((foo( ))) a = foo( );", Spaces);
+  verifyFormat("decltype((bar(10))) a = bar(11);", Spaces);
+  verifyFormat("if ((x - y) && (a ^ b))\n"
+               "  f( );\n",
+               Spaces);
+  verifyFormat("for (int i = 0; i < 10; i = (i+1))\n"
+               "  foo(i);",
+               Spaces);
+  verifyFormat("switch (x * (y + z)) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
 
+  // Check NonConsecutive spaces
+  Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
+  Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.InAttributeSpecifiers =
       FormatStyle::SIPCS_Always;
   verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
@@ -17174,6 +17229,142 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void f( ) __attribute__(( asdf ));", Spaces); 
   Spaces.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
 
+  Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
+  Spaces.SpacesInParensOptions = {};
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
+  verifyFormat("x = ( int32 )y;", Spaces);
+  verifyFormat("y = (( int (*)(int) )foo)(x);", Spaces);
+  Spaces.SpacesInParensOptions.InCStyleCasts =
+      FormatStyle::SIPCS_NonConsecutive;
+  verifyFormat("x = ( int32 )y;", Spaces);
+  verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
+  verifyFormat("x = (int32)y;", Spaces);
+  verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
+
+  Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
+  Spaces.SpacesInParensOptions = {}; 
+  Spaces.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_Always;
+  verifyFormat("while ( (bool)1 )\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("for ( ;; )\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("if ( true )\n"
+               "  f();\n"
+               "else if ( true )\n"
+               "  f();",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int)i);\n"
+               "} while ( something() );",
+               Spaces);
+  verifyFormat("switch ( x ) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+  verifyFormat("if ( (x - y) && (a ^ b) )\n"
+               "  f();\n",
+               Spaces);
+  verifyFormat("for ( int i = 0; i < 10; i = (i+1) )\n"
+               "  foo(i);",
+               Spaces);
+  verifyFormat("switch ( x * (y + z) ) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+  Spaces.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_NonConsecutive;
+  verifyFormat("while ((bool)1)\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("for ( ;; )\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("if ( true )\n"
+               "  f();\n"
+               "else if ( true )\n"
+               "  f();",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int)i);\n"
+               "} while (something());",
+               Spaces);
+  verifyFormat("switch ( x ) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+  verifyFormat("if ((x - y) && (a ^ b))\n"
+               "  f();\n",
+               Spaces);
+  verifyFormat("for (int i = 0; i < 10; i = (i+1))\n"
+               "  foo(i);",
+               Spaces);
+  verifyFormat("switch (x * (y + z)) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+  Spaces.SpacesInParensOptions.InConditionalStatements =
+      FormatStyle::SIPCS_Never;
+  verifyFormat("while ((bool)1)\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("for (;;)\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("if (true)\n"
+               "  f();\n"
+               "else if (true)\n"
+               "  f();",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int)i);\n"
+               "} while (something());",
+               Spaces);
+  verifyFormat("switch (x) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+  verifyFormat("if ((x - y) && (a ^ b))\n"
+               "  f();\n",
+               Spaces);
+  verifyFormat("for (int i = 0; i < 10; i = (i+1))\n"
+               "  foo(i);",
+               Spaces);
+  verifyFormat("switch (x * (y + z)) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+
+  Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
+  Spaces.SpacesInParensOptions = {}; 
+  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+  verifyFormat("decltype( x ) y = 42;", Spaces);
+  verifyFormat("decltype( ( x ) ) y = z;", Spaces);
+  verifyFormat("decltype( ( foo() ) ) a = foo();", Spaces);
+  verifyFormat("decltype( ( bar( 10 ) ) ) a = bar( 11 );", Spaces);
+  verifyFormat("x = foo( ( a * ( b - c ) ) );", Spaces);
+  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_NonConsecutive;
+  verifyFormat("decltype( x ) y = 42;", Spaces);
+  verifyFormat("decltype(( x )) y = z;", Spaces);
+  verifyFormat("decltype((foo())) a = foo();", Spaces);
+  verifyFormat("decltype((bar( 10 ))) a = bar( 11 );", Spaces);
+  verifyFormat("x = foo((a * ( b - c )));", Spaces);
+  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Never;
+  verifyFormat("decltype(x) y = 42;", Spaces);
+  verifyFormat("decltype((x)) y = z;", Spaces);
+  verifyFormat("decltype((foo())) a = foo();", Spaces);
+  verifyFormat("decltype((bar(10))) a = bar( 11 );", Spaces);
+  verifyFormat("x = foo((a * (b - c)));", Spaces);
+
   // Run the first set of tests again with:
   Spaces.SpaceAfterCStyleCast = true;
   verifyFormat("call(x, y, z);", Spaces);

>From ff669da38b0fcf2d3908c19c35dd47d5f6dc3a7e Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 16:05:54 -0700
Subject: [PATCH 08/31] fix tests and add initial support for conditionals

---
 clang/lib/Format/TokenAnnotator.cpp   |  18 +-
 clang/unittests/Format/FormatTest.cpp | 245 +++++++++++++-------------
 2 files changed, 137 insertions(+), 126 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index cf5ce8a638fb5..169a525e34d89 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4356,10 +4356,20 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     else if (Right.is(tok::r_paren) && Right.MatchingParen)
       LeftParen = Right.MatchingParen;
     if (LeftParen) {
-      if (LeftParen->is(TT_ConditionLParen))
-        return true;
-      if (LeftParen->Previous && isKeywordWithCondition(*LeftParen->Previous))
-        return true;
+      if (LeftParen->is(TT_ConditionLParen) || (LeftParen->Previous &&
+              isKeywordWithCondition(*LeftParen->Previous))) {
+        if (Style.SpacesInParensOptions.InConditionalStatements ==
+            FormatStyle::SIPCS_Always) {
+          return true;
+        }
+        const FormatToken *RightParen = LeftParen->MatchingParen;
+        if (LeftParen->Next && LeftParen->Next->isNot(tok::l_paren))
+          return true;
+        if (RightParen && RightParen->Previous &&
+            RightParen->Previous->isNot(tok::r_paren)) {
+          return true;
+        }
+      }
     }
   }
 
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 0af4c02a1afa4..642c6900c116a 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17092,7 +17092,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
                "  foo(i);",
                Spaces);
-  verifyFormat("switch (x * (y + z)) {\n"
+  verifyFormat("switch (x / (y + z)) {\n"
                "default:\n"
                "  break;\n"
                "}",
@@ -17135,7 +17135,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void __attribute__( ( naked ) ) foo( int bar )", Spaces);
   verifyFormat("void f() __attribute__( ( asdf ) );", Spaces);
   verifyFormat("x = (int32)y;", Spaces);
-  verifyFormat("y = ( (int (*)(int))foo )( x );", Spaces);
+  verifyFormat("y = ( (int ( * )( int ))foo )( x );", Spaces);
   verifyFormat("decltype( x ) y = 42;", Spaces);
   verifyFormat("decltype( ( x ) ) y = z;", Spaces);
   verifyFormat("decltype( ( foo() ) ) a = foo();", Spaces);
@@ -17143,10 +17143,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ( ( x - y ) && ( a ^ b ) )\n"
                "  f();\n",
                Spaces);
-  verifyFormat("for ( int i = 0; i < 10; i = ( i+1 ) )\n"
+  verifyFormat("for ( int i = 0; i < 10; i = ( i + 1 ) )\n"
                "  foo( i );",
                Spaces);
-  verifyFormat("switch ( x * ( y + z ) ) {\n"
+  verifyFormat("switch ( x / ( y + z ) ) {\n"
                "default:\n"
                "  break;\n"
                "}",
@@ -17205,28 +17205,136 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ((x - y) && (a ^ b))\n"
                "  f( );\n",
                Spaces);
-  verifyFormat("for (int i = 0; i < 10; i = (i+1))\n"
+  verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
                "  foo(i);",
                Spaces);
-  verifyFormat("switch (x * (y + z)) {\n"
+  verifyFormat("switch (x / (y + z)) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Spaces);
+
+  // Run the first set of tests again with:
+  Spaces.SpaceAfterCStyleCast = true;
+  verifyFormat("call(x, y, z);", Spaces);
+  verifyFormat("call( );", Spaces);
+  verifyFormat("std::function<void(int, int)> callback;", Spaces);
+  verifyFormat("while (( bool ) 1)\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("for (;;)\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("if (true)\n"
+               "  f( );\n"
+               "else if (true)\n"
+               "  f( );",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something(( int ) i);\n"
+               "} while (something( ));",
+               Spaces);
+  verifyFormat("switch (x) {\n"
                "default:\n"
                "  break;\n"
                "}",
                Spaces);
+  verifyFormat("#define CONF_BOOL(x) ( bool * ) ( void * ) (x)", Spaces);
+  verifyFormat("#define CONF_BOOL(x) ( bool * ) (x)", Spaces);
+  verifyFormat("#define CONF_BOOL(x) ( bool ) (x)", Spaces);
+  verifyFormat("bool *y = ( bool * ) ( void * ) (x);", Spaces);
+  verifyFormat("bool *y = ( bool * ) (x);", Spaces);
+  verifyFormat("throw ( int32 ) x;", Spaces);
+  verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
+  verifyFormat("void f( ) __attribute__((asdf));", Spaces);
+
+  // Run subset of tests again with:
+  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
+  Spaces.SpaceAfterCStyleCast = true;
+  verifyFormat("while ((bool) 1)\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int) i);\n"
+               "} while (something( ));",
+               Spaces);
+
+  verifyFormat("size_t idx = (size_t) (ptr - ((char *) file));", Spaces);
+  verifyFormat("size_t idx = (size_t) a;", Spaces);
+  verifyFormat("size_t idx = (size_t) (a - 1);", Spaces);
+  verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
+  verifyFormat("#define CONF_BOOL(x) (bool *) (void *) (x)", Spaces);
+  verifyFormat("#define CONF_BOOL(x) (bool *) (void *) (int) (x)", Spaces);
+  verifyFormat("bool *y = (bool *) (void *) (x);", Spaces);
+  verifyFormat("bool *y = (bool *) (void *) (int) (x);", Spaces);
+  verifyFormat("bool *y = (bool *) (void *) (int) foo(x);", Spaces);
+  verifyFormat("throw (int32) x;", Spaces);
+  verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
+  verifyFormat("void f( ) __attribute__((asdf));", Spaces);
+
+  Spaces.ColumnLimit = 80;
+  Spaces.IndentWidth = 4;
+  Spaces.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
+  verifyFormat("void foo( ) {\n"
+               "    size_t foo = (*(function))(\n"
+               "        Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, "
+               "BarrrrrrrrrrrrLong,\n"
+               "        FoooooooooLooooong);\n"
+               "}",
+               Spaces);
+  Spaces.SpaceAfterCStyleCast = false;
+  verifyFormat("size_t idx = (size_t)(ptr - ((char *)file));", Spaces);
+  verifyFormat("size_t idx = (size_t)a;", Spaces);
+  verifyFormat("size_t idx = (size_t)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
+
+  verifyFormat("void foo( ) {\n"
+               "    size_t foo = (*(function))(\n"
+               "        Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, "
+               "BarrrrrrrrrrrrLong,\n"
+               "        FoooooooooLooooong);\n"
+               "}",
+               Spaces);
+
+  Spaces.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent;
+  verifyFormat("void foo( ) {\n"
+               "    size_t foo = (*(function))(\n"
+               "        Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, "
+               "BarrrrrrrrrrrrLong,\n"
+               "        FoooooooooLooooong\n"
+               "    );\n"
+               "}",
+               Spaces);
+  verifyFormat("size_t idx = (size_t)(ptr - ((char *)file));", Spaces);
+  verifyFormat("size_t idx = (size_t)a;", Spaces);
+  verifyFormat("size_t idx = (size_t)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
+  verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
 
   // Check NonConsecutive spaces
+  Spaces.IndentWidth = 2;
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
   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);
+  verifyFormat("void f() __attribute__( ( asdf ) );", Spaces);
   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); 
+  verifyFormat("void f() __attribute__(( asdf ));", Spaces); 
   Spaces.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
@@ -17269,10 +17377,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ( (x - y) && (a ^ b) )\n"
                "  f();\n",
                Spaces);
-  verifyFormat("for ( int i = 0; i < 10; i = (i+1) )\n"
+  verifyFormat("for ( int i = 0; i < 10; i = (i + 1) )\n"
                "  foo(i);",
                Spaces);
-  verifyFormat("switch ( x * (y + z) ) {\n"
+  verifyFormat("switch ( x / (y + z) ) {\n"
                "default:\n"
                "  break;\n"
                "}",
@@ -17302,10 +17410,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ((x - y) && (a ^ b))\n"
                "  f();\n",
                Spaces);
-  verifyFormat("for (int i = 0; i < 10; i = (i+1))\n"
+  verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
                "  foo(i);",
                Spaces);
-  verifyFormat("switch (x * (y + z)) {\n"
+  verifyFormat("switch (x / (y + z)) {\n"
                "default:\n"
                "  break;\n"
                "}",
@@ -17335,10 +17443,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ((x - y) && (a ^ b))\n"
                "  f();\n",
                Spaces);
-  verifyFormat("for (int i = 0; i < 10; i = (i+1))\n"
+  verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
                "  foo(i);",
                Spaces);
-  verifyFormat("switch (x * (y + z)) {\n"
+  verifyFormat("switch (x / (y + z)) {\n"
                "default:\n"
                "  break;\n"
                "}",
@@ -17362,115 +17470,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("decltype(x) y = 42;", Spaces);
   verifyFormat("decltype((x)) y = z;", Spaces);
   verifyFormat("decltype((foo())) a = foo();", Spaces);
-  verifyFormat("decltype((bar(10))) a = bar( 11 );", Spaces);
+  verifyFormat("decltype((bar(10))) a = bar(11);", Spaces);
   verifyFormat("x = foo((a * (b - c)));", Spaces);
-
-  // Run the first set of tests again with:
-  Spaces.SpaceAfterCStyleCast = true;
-  verifyFormat("call(x, y, z);", Spaces);
-  verifyFormat("call( );", Spaces);
-  verifyFormat("std::function<void(int, int)> callback;", Spaces);
-  verifyFormat("while (( bool ) 1)\n"
-               "  continue;",
-               Spaces);
-  verifyFormat("for (;;)\n"
-               "  continue;",
-               Spaces);
-  verifyFormat("if (true)\n"
-               "  f( );\n"
-               "else if (true)\n"
-               "  f( );",
-               Spaces);
-  verifyFormat("do {\n"
-               "  do_something(( int ) i);\n"
-               "} while (something( ));",
-               Spaces);
-  verifyFormat("switch (x) {\n"
-               "default:\n"
-               "  break;\n"
-               "}",
-               Spaces);
-  verifyFormat("#define CONF_BOOL(x) ( bool * ) ( void * ) (x)", Spaces);
-  verifyFormat("#define CONF_BOOL(x) ( bool * ) (x)", Spaces);
-  verifyFormat("#define CONF_BOOL(x) ( bool ) (x)", Spaces);
-  verifyFormat("bool *y = ( bool * ) ( void * ) (x);", Spaces);
-  verifyFormat("bool *y = ( bool * ) (x);", Spaces);
-  verifyFormat("throw ( int32 ) x;", Spaces);
-  verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
-  verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
-  verifyFormat("void f( ) __attribute__((asdf));", Spaces);
-
-  // Run subset of tests again with:
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
-  Spaces.SpaceAfterCStyleCast = true;
-  verifyFormat("while ((bool) 1)\n"
-               "  continue;",
-               Spaces);
-  verifyFormat("do {\n"
-               "  do_something((int) i);\n"
-               "} while (something( ));",
-               Spaces);
-
-  verifyFormat("size_t idx = (size_t) (ptr - ((char *) file));", Spaces);
-  verifyFormat("size_t idx = (size_t) a;", Spaces);
-  verifyFormat("size_t idx = (size_t) (a - 1);", Spaces);
-  verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
-  verifyFormat("#define CONF_BOOL(x) (bool *) (void *) (x)", Spaces);
-  verifyFormat("#define CONF_BOOL(x) (bool *) (void *) (int) (x)", Spaces);
-  verifyFormat("bool *y = (bool *) (void *) (x);", Spaces);
-  verifyFormat("bool *y = (bool *) (void *) (int) (x);", Spaces);
-  verifyFormat("bool *y = (bool *) (void *) (int) foo(x);", Spaces);
-  verifyFormat("throw (int32) x;", Spaces);
-  verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
-  verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
-  verifyFormat("void f( ) __attribute__((asdf));", Spaces);
-
-  Spaces.ColumnLimit = 80;
-  Spaces.IndentWidth = 4;
-  Spaces.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
-  verifyFormat("void foo( ) {\n"
-               "    size_t foo = (*(function))(\n"
-               "        Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, "
-               "BarrrrrrrrrrrrLong,\n"
-               "        FoooooooooLooooong);\n"
-               "}",
-               Spaces);
-  Spaces.SpaceAfterCStyleCast = false;
-  verifyFormat("size_t idx = (size_t)(ptr - ((char *)file));", Spaces);
-  verifyFormat("size_t idx = (size_t)a;", Spaces);
-  verifyFormat("size_t idx = (size_t)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
-
-  verifyFormat("void foo( ) {\n"
-               "    size_t foo = (*(function))(\n"
-               "        Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, "
-               "BarrrrrrrrrrrrLong,\n"
-               "        FoooooooooLooooong);\n"
-               "}",
-               Spaces);
-
-  Spaces.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent;
-  verifyFormat("void foo( ) {\n"
-               "    size_t foo = (*(function))(\n"
-               "        Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, "
-               "BarrrrrrrrrrrrLong,\n"
-               "        FoooooooooLooooong\n"
-               "    );\n"
-               "}",
-               Spaces);
-  verifyFormat("size_t idx = (size_t)(ptr - ((char *)file));", Spaces);
-  verifyFormat("size_t idx = (size_t)a;", Spaces);
-  verifyFormat("size_t idx = (size_t)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
-  verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
 }
 
 TEST_F(FormatTest, ConfigurableSpacesInSquareBrackets) {

>From 6fad3cbc93c16899bb5659bd8f555e0418b305b0 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 16:11:33 -0700
Subject: [PATCH 09/31] fix conditionals logic to catch repeated parens on
 right

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

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 169a525e34d89..0fc29b6242871 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4349,7 +4349,6 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   }
   if (Style.SpacesInParensOptions.InConditionalStatements !=
       FormatStyle::SIPCS_Never) {
-    // TODO: check consecutive parens
     const FormatToken *LeftParen = nullptr;
     if (Left.is(tok::l_paren))
       LeftParen = &Left;
@@ -4362,10 +4361,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
             FormatStyle::SIPCS_Always) {
           return true;
         }
+        // check for non-repeated parens
         const FormatToken *RightParen = LeftParen->MatchingParen;
-        if (LeftParen->Next && LeftParen->Next->isNot(tok::l_paren))
-          return true;
-        if (RightParen && RightParen->Previous &&
+        if (LeftParen->Next && LeftParen->Next->isNot(tok::l_paren) &&
+            RightParen && RightParen->Previous &&
             RightParen->Previous->isNot(tok::r_paren)) {
           return true;
         }

>From 7a677f5c0ec072660801f7977c190d726490009c Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 17:42:45 -0700
Subject: [PATCH 10/31] Add support for SpacesInParens NonConsecutive options

---
 clang/lib/Format/TokenAnnotator.cpp | 71 ++++++++++++++---------------
 1 file changed, 33 insertions(+), 38 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 0fc29b6242871..6459b3ff534c0 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4347,30 +4347,6 @@ 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) {
-    const FormatToken *LeftParen = nullptr;
-    if (Left.is(tok::l_paren))
-      LeftParen = &Left;
-    else if (Right.is(tok::r_paren) && Right.MatchingParen)
-      LeftParen = Right.MatchingParen;
-    if (LeftParen) {
-      if (LeftParen->is(TT_ConditionLParen) || (LeftParen->Previous &&
-              isKeywordWithCondition(*LeftParen->Previous))) {
-        if (Style.SpacesInParensOptions.InConditionalStatements ==
-            FormatStyle::SIPCS_Always) {
-          return true;
-        }
-        // check for non-repeated parens
-        const FormatToken *RightParen = LeftParen->MatchingParen;
-        if (LeftParen->Next && LeftParen->Next->isNot(tok::l_paren) &&
-            RightParen && RightParen->Previous &&
-            RightParen->Previous->isNot(tok::r_paren)) {
-          return true;
-        }
-      }
-    }
-  }
 
   // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
   if (Left.is(tok::kw_auto) && Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
@@ -4396,26 +4372,45 @@ 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 !=
-             FormatStyle::SIPCS_Never;
+    const FormatToken *LeftParen =
+        Left.is(tok::l_paren) ? &Left : Right.MatchingParen;
+    const FormatToken *RightParen =
+        LeftParen ? LeftParen->MatchingParen : nullptr;
+
+    auto NotConsecutiveParens = [&](auto *Left, auto *Right) {
+      return Left && Left->Next && Left->Next->isNot(tok::l_paren) && Right &&
+             Right->Previous && Right->Previous->isNot(tok::r_paren);
+    };
+    const auto AddSpace = [&](FormatStyle::SpacesInParensCustomStyle Option) {
+      if (Option == FormatStyle::SIPCS_Always)
+        return true;
+      if (Option == FormatStyle::SIPCS_NonConsecutive) {
+        if (NotConsecutiveParens(LeftParen, RightParen))
+          return true;
+      }
+      return false;
+    };
+
+    if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||
+                      (LeftParen->Previous &&
+                       isKeywordWithCondition(*LeftParen->Previous)))) {
+      return AddSpace(Style.SpacesInParensOptions.InConditionalStatements);
     }
-    const auto isAttributeParen = [](const FormatToken *Paren) {
+    if (RightParen && RightParen->is(TT_CastRParen))
+      return AddSpace(Style.SpacesInParensOptions.InCStyleCasts);
+    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(LeftParen) || IsAttributeParen(RightParen))
+      return AddSpace(Style.SpacesInParensOptions.InAttributeSpecifiers);
+    if ((LeftParen && IsAttributeParen(LeftParen->Previous)) ||
+        (RightParen && IsAttributeParen(RightParen->Next))) {
+      return AddSpace(Style.SpacesInParensOptions.InAttributeSpecifiers);
     }
-    if (isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
-      return Style.SpacesInParensOptions.InAttributeSpecifiers !=
-             FormatStyle::SIPCS_Never;
-    }
-    return Style.SpacesInParensOptions.Other != FormatStyle::SIPCS_Never;
+    return AddSpace(Style.SpacesInParensOptions.Other);
   }
+
   if (Right.isOneOf(tok::semi, tok::comma))
     return false;
   if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {

>From 740fbe206605b2c335b4986db787f95f48a07905 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 17:49:37 -0700
Subject: [PATCH 11/31] Minor fix in Format.h documentation and redump

---
 clang/docs/ClangFormatStyleOptions.rst | 4 ++--
 clang/include/clang/Format/Format.h    | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index e71cc8deaf8e9..17a9688069c35 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6291,8 +6291,8 @@ the configuration (without a prefix: ``Auto``).
 
     .. code-block:: c++
 
-      Always:                                  false:
-      x = ( int32 )y                 vs.     x = (int32)y
+      Always:
+      x = ( int32 )y
       y = (( int (*)(int) )foo)(x);
 
     .. code-block:: c++
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 7fb67c6674dc0..6d7bc41cffe35 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4692,8 +4692,8 @@ struct FormatStyle {
     SpacesInParensCustomStyle InConditionalStatements;
     /// Put a space in C style casts.
     /// \code
-    ///   Always:                                  false:
-    ///   x = ( int32 )y                 vs.     x = (int32)y
+    ///   Always:
+    ///   x = ( int32 )y
     ///   y = (( int (*)(int) )foo)(x);
     /// \endcode
     /// \code

>From bb46e6166065d3ff990db4911fcdd6a04666c92f Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 17:58:10 -0700
Subject: [PATCH 12/31] FormatTest: fix whitespace problems

---
 clang/unittests/Format/FormatTest.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 642c6900c116a..d19c90dc55617 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17334,7 +17334,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
       FormatStyle::SIPCS_NonConsecutive;
   verifyFormat("SomeType *__attribute__(( attr )) *a = NULL;", Spaces);
   verifyFormat("void __attribute__(( naked )) foo(int bar)", Spaces);
-  verifyFormat("void f() __attribute__(( asdf ));", Spaces); 
+  verifyFormat("void f() __attribute__(( asdf ));", Spaces);
   Spaces.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
@@ -17351,7 +17351,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
-  Spaces.SpacesInParensOptions = {}; 
+  Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.InConditionalStatements =
       FormatStyle::SIPCS_Always;
   verifyFormat("while ( (bool)1 )\n"
@@ -17453,7 +17453,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
-  Spaces.SpacesInParensOptions = {}; 
+  Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
   verifyFormat("decltype( x ) y = 42;", Spaces);
   verifyFormat("decltype( ( x ) ) y = z;", Spaces);

>From 4465fb91be908abce79ce7ffd0f834cfb68d2236 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 18:01:47 -0700
Subject: [PATCH 13/31] Format.h: whitespace

---
 clang/include/clang/Format/Format.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 6d7bc41cffe35..f5c2c43ccdef9 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4737,7 +4737,7 @@ struct FormatStyle {
     ///   Never:
     ///   t f(Deleted &) & = delete;
     ///   decltype((x))
-    ///   x = ((int32))y 
+    ///   x = ((int32))y
     ///   y = ((int (*)(int))foo)(x);
     /// \endcode
     SpacesInParensCustomStyle Other;

>From acfd68b52a5b77e3ec3d6548c5bbd59a651b18a2 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Thu, 11 Jan 2024 18:05:55 -0700
Subject: [PATCH 14/31] Remember to run clang-format locally

---
 clang/include/clang/Format/Format.h        |  5 ++---
 clang/unittests/Format/ConfigParseTest.cpp | 24 +++++++++++-----------
 2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index f5c2c43ccdef9..71bd4d1b59d96 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4744,9 +4744,8 @@ struct FormatStyle {
 
     SpacesInParensCustom()
         : InAttributeSpecifiers(SIPCS_Never),
-          InConditionalStatements(SIPCS_Never),
-          InCStyleCasts(SIPCS_Never), InEmptyParentheses(false),
-          Other(SIPCS_Never) {}
+          InConditionalStatements(SIPCS_Never), InCStyleCasts(SIPCS_Never),
+          InEmptyParentheses(false), Other(SIPCS_Never) {}
 
     SpacesInParensCustom(SpacesInParensCustomStyle InAttributeSpecifiers,
                          SpacesInParensCustomStyle InConditionalStatements,
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index aed757aabca62..dfa8e02f90586 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -660,27 +660,27 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Always,
-              FormatStyle::SIPCS_Always, FormatStyle::SIPCS_Never, false,
-              FormatStyle::SIPCS_Always));
+              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,
-              FormatStyle::SIPCS_Always, FormatStyle::SIPCS_Never, false,
-              FormatStyle::SIPCS_Never));
+              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,
-              FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Always, false,
-              FormatStyle::SIPCS_Never));
+              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,
-              FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Never, true,
-              FormatStyle::SIPCS_Never));
+              FormatStyle::SpacesInParensCustom(
+                  FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Never,
+                  FormatStyle::SIPCS_Never, true, FormatStyle::SIPCS_Never));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 

>From d046670c6c50ca62b26a51511594581f53059116 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 12 Jan 2024 14:50:46 -0700
Subject: [PATCH 15/31] Address review requests

---
 clang/lib/Format/TokenAnnotator.cpp   | 6 +++---
 clang/unittests/Format/FormatTest.cpp | 8 +++++++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 6459b3ff534c0..df1f7f3cc821b 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4385,9 +4385,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     const auto AddSpace = [&](FormatStyle::SpacesInParensCustomStyle Option) {
       if (Option == FormatStyle::SIPCS_Always)
         return true;
-      if (Option == FormatStyle::SIPCS_NonConsecutive) {
-        if (NotConsecutiveParens(LeftParen, RightParen))
-          return true;
+      if (Option == FormatStyle::SIPCS_NonConsecutive &&
+          NotConsecutiveParens(LeftParen, RightParen)) {
+        return true;
       }
       return false;
     };
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index d19c90dc55617..d99618de66c18 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17330,22 +17330,24 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   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_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;
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
   verifyFormat("x = ( int32 )y;", Spaces);
   verifyFormat("y = (( int (*)(int) )foo)(x);", Spaces);
+
   Spaces.SpacesInParensOptions.InCStyleCasts =
       FormatStyle::SIPCS_NonConsecutive;
   verifyFormat("x = ( int32 )y;", Spaces);
   verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
+
   Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
   verifyFormat("x = (int32)y;", Spaces);
   verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
@@ -17385,6 +17387,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                "  break;\n"
                "}",
                Spaces);
+
   Spaces.SpacesInParensOptions.InConditionalStatements =
       FormatStyle::SIPCS_NonConsecutive;
   verifyFormat("while ((bool)1)\n"
@@ -17418,6 +17421,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                "  break;\n"
                "}",
                Spaces);
+
   Spaces.SpacesInParensOptions.InConditionalStatements =
       FormatStyle::SIPCS_Never;
   verifyFormat("while ((bool)1)\n"
@@ -17460,12 +17464,14 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("decltype( ( foo() ) ) a = foo();", Spaces);
   verifyFormat("decltype( ( bar( 10 ) ) ) a = bar( 11 );", Spaces);
   verifyFormat("x = foo( ( a * ( b - c ) ) );", Spaces);
+
   Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_NonConsecutive;
   verifyFormat("decltype( x ) y = 42;", Spaces);
   verifyFormat("decltype(( x )) y = z;", Spaces);
   verifyFormat("decltype((foo())) a = foo();", Spaces);
   verifyFormat("decltype((bar( 10 ))) a = bar( 11 );", Spaces);
   verifyFormat("x = foo((a * ( b - c )));", Spaces);
+
   Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Never;
   verifyFormat("decltype(x) y = 42;", Spaces);
   verifyFormat("decltype((x)) y = z;", Spaces);

>From 227e2833f9d46aa219bc4bfce955d66f36277739 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Mon, 22 Jan 2024 22:11:39 -0700
Subject: [PATCH 16/31] Only filter doubled parens situationally like
 RemoveParentheses

---
 clang/docs/ClangFormatStyleOptions.rst       | 114 +++--------
 clang/docs/ReleaseNotes.rst                  |   7 +-
 clang/include/clang/Format/Format.h          |  94 ++++-----
 clang/lib/Format/Format.cpp                  |  36 +---
 clang/lib/Format/TokenAnnotator.cpp          |  53 +++--
 clang/unittests/Format/ConfigParseTest.cpp   |  54 ++----
 clang/unittests/Format/FormatTest.cpp        | 193 ++++++++++++++-----
 clang/unittests/Format/FormatTestVerilog.cpp |   6 +-
 8 files changed, 271 insertions(+), 286 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 17a9688069c35..fa6fcef83d8c2 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6206,8 +6206,8 @@ the configuration (without a prefix: ``Auto``).
     # Example of usage:
     SpacesInParens: Custom
     SpacesInParensOptions:
-      InAttributeSpecifiers: NonConsecutive
-      InConditionalStatements: Always
+      InAttributeSpecifiers: false
+      InConditionalStatements: true
       InEmptyParentheses: true
 
   Nested configuration flags:
@@ -6222,103 +6222,60 @@ the configuration (without a prefix: ``Auto``).
       InConditionalStatements: true
       Other: true
 
-  * ``SpacesInParensCustomStyle InAttributeSpecifiers``
-    Put a space in parentheses of attribute specifiers.
+  * ``bool ExceptDoubleParentheses`` Override any of the following options to prevent addition of space
+    between the first two parentheses in situations where a pair of
+    parentheses have been used.
 
     .. code-block:: c++
 
-       Always:
-       __attribute__( ( noreturn ) )
+      true:
+      __attribute__(( noreturn ))
+      __decltype__(( x ))
+      if (( a = b ))
+     false:
+       Uses the applicable option.
+
+  * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
 
     .. code-block:: c++
 
-       NonConsecutive:
-       _attribute__(( noreturn ))
+       true:
+       __attribute__( ( noreturn ) )
 
     .. code-block:: c++
 
-       Never:
+       false:
        _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
+  * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
     (``for/if/while/switch...``).
 
     .. code-block:: c++
 
-       Always:
+       true:
        if ( ( a ) )  { ... }
        while ( i < 5 )  { ... }
 
     .. code-block:: c++
 
-      NonConsecutive:
-      if (( a )) { ... }
-      while ( i < 5 ) { ... }
-
-    .. code-block:: c++
-
-      Never:
+      false:
       if ((a)) { ... }
       while (i < 5) { ... }
 
-    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 InCStyleCasts``
-    Put a space in C style casts.
+  * ``bool InCStyleCasts`` Put a space in C style casts.
 
     .. code-block:: c++
 
-      Always:
+      true:
       x = ( int32 )y
       y = (( int (*)(int) )foo)(x);
 
     .. code-block:: c++
 
-      NonConsecutive:
-      x = ( int32 )y
-      y = ((int (*)(int))foo)(x);
-
-    .. code-block:: c++
-
-      Never:
+      false:
       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. '()'
 
     .. code-block:: c++
@@ -6331,12 +6288,11 @@ the configuration (without a prefix: ``Auto``).
          }                                    }
        }                                    }
 
-  * ``SpacesInParensCustomStyle Other``
-    Put a space in parentheses not covered by preceding options.
+  * ``bool Other`` Put a space in parentheses not covered by preceding options.
 
     .. code-block:: c++
 
-      Always:
+      true:
       t f( Deleted & ) & = delete;
       decltype( ( x ) )
       x = ( (int32)y )
@@ -6344,32 +6300,12 @@ the configuration (without a prefix: ``Auto``).
 
     .. code-block:: c++
 
-      NonConsecutive:
-      t f( Deleted & ) & = delete;
-      decltype(( x ))
-      x = ((int32))y
-      y = ((int ( * )( int ))foo)( x );
-
-    .. code-block:: c++
-
-      Never:
+      false:
       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 3b0ecb5168092..8e088b7f9cafd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -897,10 +897,9 @@ clang-format
 - Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``.
 - 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.
+- Add ``ExceptDoubleParentheses`` sub-option for ``SpacesInParensOptions``
+  to override addition of spaces between multiple, non-redundant parentheses
+  similar to the rules used for ``RemoveParentheses``.
 
 libclang
 --------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 71bd4d1b59d96..43be98e9cb1e7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4639,16 +4639,6 @@ 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:
@@ -4658,55 +4648,53 @@ struct FormatStyle {
   ///     Other: true
   /// \endcode
   struct SpacesInParensCustom {
-    /// Put a space in parentheses of attribute specifiers.
+    /// Override any of the following options to prevent addition of space
+    /// between the first two parentheses in situations where a pair of
+    /// parentheses have been used.
     /// \code
-    ///    Always:
-    ///    __attribute__( ( noreturn ) )
+    ///   true:
+    ///   __attribute__(( noreturn ))
+    ///   __decltype__(( x ))
+    ///   if (( a = b ))
     /// \endcode
+    ///  false:
+    ///    Uses the applicable option.
+    bool ExceptDoubleParentheses;
+    /// Put a space in parentheses of attribute specifiers.
     /// \code
-    ///    NonConsecutive:
-    ///    _attribute__(( noreturn ))
+    ///    true:
+    ///    __attribute__( ( noreturn ) )
     /// \endcode
     /// \code
-    ///    Never:
+    ///    false:
     ///    _attribute__((noreturn))
     /// \endcode
-    SpacesInParensCustomStyle InAttributeSpecifiers;
+    bool InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
-    ///    Always:
+    ///    true:
     ///    if ( ( a ) )  { ... }
     ///    while ( i < 5 )  { ... }
     /// \endcode
     /// \code
-    ///   NonConsecutive:
-    ///   if (( a )) { ... }
-    ///   while ( i < 5 ) { ... }
-    /// \endcode
-    /// \code
-    ///   Never:
+    ///   false:
     ///   if ((a)) { ... }
     ///   while (i < 5) { ... }
     /// \endcode
-    SpacesInParensCustomStyle InConditionalStatements;
+    bool InConditionalStatements;
     /// Put a space in C style casts.
     /// \code
-    ///   Always:
+    ///   true:
     ///   x = ( int32 )y
     ///   y = (( int (*)(int) )foo)(x);
     /// \endcode
     /// \code
-    ///   NonConsecutive:
-    ///   x = ( int32 )y
-    ///   y = ((int (*)(int))foo)(x);
-    /// \endcode
-    /// \code
-    ///   Never:
+    ///   false:
     ///   x = (int32)y
     ///   y = ((int (*)(int))foo)(x);
     /// \endcode
-    SpacesInParensCustomStyle InCStyleCasts;
+    bool InCStyleCasts;
     /// Put a space in parentheses only if the parentheses are empty i.e. '()'
     /// \code
     ///    true:                                false:
@@ -4720,45 +4708,39 @@ struct FormatStyle {
     bool InEmptyParentheses;
     /// Put a space in parentheses not covered by preceding options.
     /// \code
-    ///   Always:
+    ///   true:
     ///   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:
+    ///   false:
     ///   t f(Deleted &) & = delete;
     ///   decltype((x))
     ///   x = ((int32))y
     ///   y = ((int (*)(int))foo)(x);
     /// \endcode
-    SpacesInParensCustomStyle Other;
+    bool Other;
 
     SpacesInParensCustom()
-        : InAttributeSpecifiers(SIPCS_Never),
-          InConditionalStatements(SIPCS_Never), InCStyleCasts(SIPCS_Never),
-          InEmptyParentheses(false), Other(SIPCS_Never) {}
-
-    SpacesInParensCustom(SpacesInParensCustomStyle InAttributeSpecifiers,
-                         SpacesInParensCustomStyle InConditionalStatements,
-                         SpacesInParensCustomStyle InCStyleCasts,
-                         bool InEmptyParentheses,
-                         SpacesInParensCustomStyle Other)
-        : InAttributeSpecifiers(InAttributeSpecifiers),
+        : ExceptDoubleParentheses(false), InAttributeSpecifiers(false),
+          InConditionalStatements(false), InCStyleCasts(false),
+          InEmptyParentheses(false), Other(false) {}
+
+    SpacesInParensCustom(bool ExceptDoubleParentheses,
+                         bool InAttributeSpecifiers,
+                         bool InConditionalStatements, bool InCStyleCasts,
+                         bool InEmptyParentheses, bool Other)
+        : ExceptDoubleParentheses(ExceptDoubleParentheses),
+          InAttributeSpecifiers(InAttributeSpecifiers),
           InConditionalStatements(InConditionalStatements),
           InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
           Other(Other) {}
 
     bool operator==(const SpacesInParensCustom &R) const {
-      return InAttributeSpecifiers == R.InAttributeSpecifiers &&
+      return ExceptDoubleParentheses == R.ExceptDoubleParentheses &&
+             InAttributeSpecifiers == R.InAttributeSpecifiers &&
              InConditionalStatements == R.InConditionalStatements &&
              InCStyleCasts == R.InCStyleCasts &&
              InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
@@ -4777,8 +4759,8 @@ struct FormatStyle {
   ///   # Example of usage:
   ///   SpacesInParens: Custom
   ///   SpacesInParensOptions:
-  ///     InAttributeSpecifiers: NonConsecutive
-  ///     InConditionalStatements: Always
+  ///     InAttributeSpecifiers: false
+  ///     InConditionalStatements: true
   ///     InEmptyParentheses: true
   /// \endcode
   /// \version 17
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 109cc61adc58f..e5b5518b19329 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -718,22 +718,9 @@ 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);
-
-    // For backward compatibility.
-    IO.enumCase(Value, "true", FormatStyle::SIPCS_Always);
-    IO.enumCase(Value, "false", FormatStyle::SIPCS_Never);
-  }
-};
-
 template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
   static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
+    IO.mapOptional("ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);
     IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
     IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
     IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
@@ -1188,27 +1175,22 @@ 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/Always for backward compatibility.
-        Style.SpacesInParensOptions.InAttributeSpecifiers =
-            FormatStyle::SIPCS_Always;
-        Style.SpacesInParensOptions.InConditionalStatements =
-            FormatStyle::SIPCS_Always;
+        // for backward compatibility.
+        Style.SpacesInParensOptions.ExceptDoubleParentheses = false;
+        Style.SpacesInParensOptions.InAttributeSpecifiers = true;
+        Style.SpacesInParensOptions.InConditionalStatements = true;
         Style.SpacesInParensOptions.InCStyleCasts =
-            CoerceBooleanToSIPCS(SpacesInCStyleCastParentheses);
+            SpacesInCStyleCastParentheses;
         Style.SpacesInParensOptions.InEmptyParentheses =
             SpaceInEmptyParentheses;
-        Style.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+        Style.SpacesInParensOptions.Other = true;
       } else {
         Style.SpacesInParensOptions = {};
         Style.SpacesInParensOptions.InConditionalStatements =
-            CoerceBooleanToSIPCS(SpacesInConditionalStatement);
+            SpacesInConditionalStatement;
         Style.SpacesInParensOptions.InCStyleCasts =
-            CoerceBooleanToSIPCS(SpacesInCStyleCastParentheses);
+            SpacesInCStyleCastParentheses;
         Style.SpacesInParensOptions.InEmptyParentheses =
             SpaceInEmptyParentheses;
       }
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index df1f7f3cc821b..fbcf2d0b3b4f7 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3924,8 +3924,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
     if (Current->is(TT_LineComment)) {
       if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
         Current->SpacesRequiredBefore =
-            (Style.Cpp11BracedListStyle &&
-             Style.SpacesInParensOptions.Other == FormatStyle::SIPCS_Never)
+            (Style.Cpp11BracedListStyle && !Style.SpacesInParensOptions.Other)
                 ? 0
                 : 1;
       } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
@@ -4377,19 +4376,36 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
         Left.is(tok::l_paren) ? &Left : Right.MatchingParen;
     const FormatToken *RightParen =
         LeftParen ? LeftParen->MatchingParen : nullptr;
-
-    auto NotConsecutiveParens = [&](auto *Left, auto *Right) {
-      return Left && Left->Next && Left->Next->isNot(tok::l_paren) && Right &&
-             Right->Previous && Right->Previous->isNot(tok::r_paren);
+    const auto IsAttributeParen = [](const FormatToken *Paren) {
+      return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
     };
-    const auto AddSpace = [&](FormatStyle::SpacesInParensCustomStyle Option) {
-      if (Option == FormatStyle::SIPCS_Always)
-        return true;
-      if (Option == FormatStyle::SIPCS_NonConsecutive &&
-          NotConsecutiveParens(LeftParen, RightParen)) {
-        return true;
-      }
-      return false;
+    auto AddSpaceInDoubleParens = [&]() {
+      const auto *RPrev = RightParen ? RightParen->Previous : nullptr;
+      const auto *LNext = LeftParen->Next;
+      const auto *LPrev = LeftParen->Previous;
+      const bool DoubleParens =
+          RPrev && RPrev->is(tok::r_paren) && LNext && LNext->is(tok::l_paren);
+      auto HasEqualBeforeNextParen = [&]() {
+        auto *Tok = LNext;
+        if (!Tok || !Tok->is(tok::l_paren))
+          return false;
+        while ((Tok = Tok->Next) && !Tok->isOneOf(tok::l_paren, tok::r_paren))
+          if (Tok->is(tok::equal))
+            return true;
+        return false;
+      };
+      const bool SuppressSpace =
+          IsAttributeParen(LeftParen) ||
+          (LPrev && (LPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
+                     (HasEqualBeforeNextParen() &&
+                      (LPrev->isOneOf(tok::kw_if, tok::kw_while) ||
+                       LPrev->endsSequence(tok::kw_constexpr, tok::kw_if)))));
+      return !(DoubleParens && SuppressSpace);
+    };
+    const auto AddSpace = [&](bool Option) {
+      if (Style.SpacesInParensOptions.ExceptDoubleParentheses && Option)
+        return AddSpaceInDoubleParens();
+      return Option;
     };
 
     if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||
@@ -4399,9 +4415,6 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     }
     if (RightParen && RightParen->is(TT_CastRParen))
       return AddSpace(Style.SpacesInParensOptions.InCStyleCasts);
-    const auto IsAttributeParen = [](const FormatToken *Paren) {
-      return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
-    };
     if (IsAttributeParen(LeftParen) || IsAttributeParen(RightParen))
       return AddSpace(Style.SpacesInParensOptions.InAttributeSpecifiers);
     if ((LeftParen && IsAttributeParen(LeftParen->Previous)) ||
@@ -4639,8 +4652,7 @@ 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;
   }
   if (Left.is(TT_BlockComment)) {
     // No whitespace in x(/*foo=*/1), except for JavaScript.
@@ -5357,8 +5369,7 @@ 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);
   }
   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 dfa8e02f90586..00e8e196b6631 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -235,6 +235,12 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, ExceptDoubleParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
+  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
@@ -626,32 +632,6 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               SpaceBeforeParensOptions.AfterPlacementOperator,
               FormatStyle::SpaceBeforeParensCustom::APO_Leave);
 
-#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 = {};
@@ -659,28 +639,24 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               FormatStyle::SIPO_Custom);
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
-  CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(
-                  FormatStyle::SIPCS_Always, FormatStyle::SIPCS_Always,
-                  FormatStyle::SIPCS_Never, false, FormatStyle::SIPCS_Always));
+  CHECK_PARSE(
+      "SpacesInParentheses: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, true, true, false, false, true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(
-                  FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Always,
-                  FormatStyle::SIPCS_Never, false, FormatStyle::SIPCS_Never));
+              FormatStyle::SpacesInParensCustom(false, false, true, false,
+                                                false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(
-                  FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Never,
-                  FormatStyle::SIPCS_Always, false, FormatStyle::SIPCS_Never));
+              FormatStyle::SpacesInParensCustom(false, false, false, true,
+                                                false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(
-                  FormatStyle::SIPCS_Never, FormatStyle::SIPCS_Never,
-                  FormatStyle::SIPCS_Never, true, FormatStyle::SIPCS_Never));
+              FormatStyle::SpacesInParensCustom(false, 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 d99618de66c18..e410e864835c5 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -11381,14 +11381,14 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
   FormatStyle Spaces = getLLVMStyle();
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InCStyleCasts = true;
   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 = FormatStyle::SIPCS_Never;
-  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InCStyleCasts = false;
+  Spaces.SpacesInParensOptions.Other = true;
   verifyFormat("Deleted &operator=( const Deleted & ) & = default;", Spaces);
   verifyFormat("SomeType MemberFunction( const Deleted & ) & = delete;",
                Spaces);
@@ -13993,7 +13993,7 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
   FormatStyle SpaceBetweenBraces = getLLVMStyle();
   SpaceBetweenBraces.SpacesInAngles = FormatStyle::SIAS_Always;
   SpaceBetweenBraces.SpacesInParens = FormatStyle::SIPO_Custom;
-  SpaceBetweenBraces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+  SpaceBetweenBraces.SpacesInParensOptions.Other = true;
   SpaceBetweenBraces.SpacesInSquareBrackets = true;
   verifyFormat("vector< int > x{ 1, 2, 3, 4 };", SpaceBetweenBraces);
   verifyFormat("f( {}, { {}, {} }, MyMap[ { k, v } ] );", SpaceBetweenBraces);
@@ -17100,11 +17100,9 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
-  Spaces.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_Always;
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
-      FormatStyle::SIPCS_Always;
+  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);
@@ -17154,7 +17152,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InCStyleCasts = true;
   verifyFormat("Type *A = ( Type * )P;", Spaces);
   verifyFormat("Type *A = ( vector<Type *, int *> )P;", Spaces);
   verifyFormat("x = ( int32 )y;", Spaces);
@@ -17169,7 +17167,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.InEmptyParentheses = true;
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InCStyleCasts = true;
   verifyFormat("call(x, y, z);", Spaces);
   verifyFormat("call( );", Spaces);
   verifyFormat("std::function<void(int, int)> callback;", Spaces);
@@ -17250,7 +17248,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
 
   // Run subset of tests again with:
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
+  Spaces.SpacesInParensOptions.InCStyleCasts = false;
   Spaces.SpaceAfterCStyleCast = true;
   verifyFormat("while ((bool) 1)\n"
                "  continue;",
@@ -17321,44 +17319,60 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("size_t idx = (*foo)(a - 1);", Spaces);
   verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces);
 
-  // Check NonConsecutive spaces
+  // Check ExceptDoubleParentheses spaces
   Spaces.IndentWidth = 2;
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
-      FormatStyle::SIPCS_Always;
+  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);
+  verifyFormat("__attribute__( ( __aligned__(x) ) ) z;", Spaces);
+  verifyFormat("int x __attribute__( ( aligned(16) ) ) = 0;", Spaces);
+  verifyFormat("class __declspec( dllimport ) X {};", Spaces);
+  verifyFormat("class __declspec( ( dllimport ) ) X {};", Spaces);
 
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
-      FormatStyle::SIPCS_NonConsecutive;
+  Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
   verifyFormat("SomeType *__attribute__(( attr )) *a = NULL;", Spaces);
   verifyFormat("void __attribute__(( naked )) foo(int bar)", Spaces);
   verifyFormat("void f() __attribute__(( asdf ));", Spaces);
+  verifyFormat("__attribute__(( __aligned__(x) )) z;", Spaces);
+  verifyFormat("int x __attribute__(( aligned(16) )) = 0;", Spaces);
+  verifyFormat("class __declspec( dllimport ) X {};", Spaces);
+  verifyFormat("class __declspec(( dllimport )) X {};", Spaces);
+
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
+  verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
+  verifyFormat("void f() __attribute__((asdf));", Spaces);
+  verifyFormat("__attribute__((__aligned__(x))) z;", Spaces);
+  verifyFormat("int x __attribute__((aligned(16))) = 0;", Spaces);
+  verifyFormat("class __declspec(dllimport) X {};", Spaces);
+  verifyFormat("class __declspec((dllimport)) X {};", Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InCStyleCasts = true;
   verifyFormat("x = ( int32 )y;", Spaces);
   verifyFormat("y = (( int (*)(int) )foo)(x);", Spaces);
 
-  Spaces.SpacesInParensOptions.InCStyleCasts =
-      FormatStyle::SIPCS_NonConsecutive;
+  Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
   verifyFormat("x = ( int32 )y;", Spaces);
-  verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
+  verifyFormat("y = (( int (*)(int) )foo)(x);", Spaces);
 
-  Spaces.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
+  Spaces.SpacesInParensOptions.InCStyleCasts = false;
   verifyFormat("x = (int32)y;", Spaces);
   verifyFormat("y = ((int (*)(int))foo)(x);", Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InConditionalStatements = true;
   verifyFormat("while ( (bool)1 )\n"
                "  continue;",
                Spaces);
+  verifyFormat("while ( (i = j) )\n"
+               "  continue;",
+               Spaces);
   verifyFormat("for ( ;; )\n"
                "  continue;",
                Spaces);
@@ -17371,6 +17385,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                "  do_something((int)i);\n"
                "} while ( something() );",
                Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int)i);\n"
+               "} while ( (i = i + 1) );",
+               Spaces);
   verifyFormat("switch ( x ) {\n"
                "default:\n"
                "  break;\n"
@@ -17379,6 +17397,9 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ( (x - y) && (a ^ b) )\n"
                "  f();\n",
                Spaces);
+  verifyFormat("if ( (i = j) )\n"
+               "  do_something(i);",
+               Spaces);
   verifyFormat("for ( int i = 0; i < 10; i = (i + 1) )\n"
                "  foo(i);",
                Spaces);
@@ -17387,10 +17408,18 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                "  break;\n"
                "}",
                Spaces);
+  verifyFormat("if constexpr ( (a = b) )\n"
+               "  c;",
+               Spaces);
+  verifyFormat("if ( ({ a; }) )\n"
+               "  b;",
+               Spaces);
 
-  Spaces.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_NonConsecutive;
-  verifyFormat("while ((bool)1)\n"
+  Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
+  verifyFormat("while ( (bool)1 )\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("while ((i = j))\n"
                "  continue;",
                Spaces);
   verifyFormat("for ( ;; )\n"
@@ -17403,30 +17432,42 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                Spaces);
   verifyFormat("do {\n"
                "  do_something((int)i);\n"
-               "} while (something());",
+               "} while ( something() );",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int)i);\n"
+               "} while ((i = i + 1));",
                Spaces);
   verifyFormat("switch ( x ) {\n"
                "default:\n"
                "  break;\n"
                "}",
                Spaces);
-  verifyFormat("if ((x - y) && (a ^ b))\n"
+  verifyFormat("if ( (x - y) && (a ^ b) )\n"
                "  f();\n",
                Spaces);
-  verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
+  verifyFormat("if ((i = j))\n"
+               "  do_something(i);",
+               Spaces);
+  verifyFormat("for ( int i = 0; i < 10; i = (i + 1) )\n"
                "  foo(i);",
                Spaces);
-  verifyFormat("switch (x / (y + z)) {\n"
+  verifyFormat("switch ( x / (y + z) ) {\n"
                "default:\n"
                "  break;\n"
                "}",
                Spaces);
+  verifyFormat("if constexpr ((a = b))\n"
+               "  c;",
+               Spaces);
 
-  Spaces.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_Never;
+  Spaces.SpacesInParensOptions.InConditionalStatements = false;
   verifyFormat("while ((bool)1)\n"
                "  continue;",
                Spaces);
+  verifyFormat("while ((i = j))\n"
+               "  continue;",
+               Spaces);
   verifyFormat("for (;;)\n"
                "  continue;",
                Spaces);
@@ -17439,6 +17480,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                "  do_something((int)i);\n"
                "} while (something());",
                Spaces);
+  verifyFormat("do {\n"
+               "  do_something((int)i);\n"
+               "} while ((i = i + 1));",
+               Spaces);
   verifyFormat("switch (x) {\n"
                "default:\n"
                "  break;\n"
@@ -17447,6 +17492,9 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("if ((x - y) && (a ^ b))\n"
                "  f();\n",
                Spaces);
+  verifyFormat("if ((i = j))\n"
+               "  do_something(i);",
+               Spaces);
   verifyFormat("for (int i = 0; i < 10; i = (i + 1))\n"
                "  foo(i);",
                Spaces);
@@ -17455,29 +17503,83 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
                "  break;\n"
                "}",
                Spaces);
+  verifyFormat("if constexpr ((a = b))\n"
+               "  c;",
+               Spaces);
 
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.Other = true;
   verifyFormat("decltype( x ) y = 42;", Spaces);
   verifyFormat("decltype( ( x ) ) y = z;", Spaces);
   verifyFormat("decltype( ( foo() ) ) a = foo();", Spaces);
   verifyFormat("decltype( ( bar( 10 ) ) ) a = bar( 11 );", Spaces);
-  verifyFormat("x = foo( ( a * ( b - c ) ) );", Spaces);
+  verifyFormat("decltype( ( foo->bar ) ) baz;", Spaces);
+  verifyFormat("if (( i = j ))\n"
+               "  do_something( i );",
+               Spaces);
+  verifyFormat("if constexpr (( a = b ))\n"
+               "  c;",
+               Spaces);
 
-  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_NonConsecutive;
+  Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
   verifyFormat("decltype( x ) y = 42;", Spaces);
   verifyFormat("decltype(( x )) y = z;", Spaces);
-  verifyFormat("decltype((foo())) a = foo();", Spaces);
-  verifyFormat("decltype((bar( 10 ))) a = bar( 11 );", Spaces);
-  verifyFormat("x = foo((a * ( b - c )));", Spaces);
+  verifyFormat("decltype(( foo() )) a = foo();", Spaces);
+  verifyFormat("decltype(( bar( 10 ) )) a = bar( 11 );", Spaces);
+  verifyFormat("decltype(( foo->bar )) baz;", Spaces);
+  verifyFormat("if (( i = j ))\n"
+               "  do_something( i );",
+               Spaces);
+  verifyFormat("if constexpr (( a = b ))\n"
+               "  c;",
+               Spaces);
 
-  Spaces.SpacesInParensOptions.Other = FormatStyle::SIPCS_Never;
+  Spaces.SpacesInParensOptions.Other = false;
   verifyFormat("decltype(x) y = 42;", Spaces);
   verifyFormat("decltype((x)) y = z;", Spaces);
   verifyFormat("decltype((foo())) a = foo();", Spaces);
   verifyFormat("decltype((bar(10))) a = bar(11);", Spaces);
-  verifyFormat("x = foo((a * (b - c)));", Spaces);
+  verifyFormat("decltype((foo->bar)) baz;", Spaces);
+  verifyFormat("if ((i = j))\n"
+               "  do_something(i);",
+               Spaces);
+  verifyFormat("if constexpr ((a = b))\n"
+               "  c;",
+               Spaces);
+
+  Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
+  Spaces.SpacesInParensOptions = {};
+  Spaces.SpacesInParensOptions.Other = true;
+  Spaces.SpacesInParensOptions.InConditionalStatements = true;
+  verifyFormat("if ( ( i = j ) )\n"
+               "  do_something( i );",
+               Spaces);
+  verifyFormat("if constexpr ( ( a = b ) )\n"
+               "  c;",
+               Spaces);
+  verifyFormat("while ( ( i = j ) )\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something( (int)i );\n"
+               "} while ( ( i = i + 1 ) );",
+               Spaces);
+
+  Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
+  verifyFormat("if (( i = j ))\n"
+               "  do_something( i );",
+               Spaces);
+  verifyFormat("if constexpr (( a = b ))\n"
+               "  c;",
+               Spaces);
+  verifyFormat("while (( i = j ))\n"
+               "  continue;",
+               Spaces);
+  verifyFormat("do {\n"
+               "  do_something( (int)i );\n"
+               "} while (( i = i + 1 ));",
+               Spaces);
 }
 
 TEST_F(FormatTest, ConfigurableSpacesInSquareBrackets) {
@@ -24600,10 +24702,10 @@ TEST_F(FormatTest, AtomicQualifier) {
   verifyFormat("vector<_Atomic(uint64_t)* attr> x;", Style);
 
   Style.SpacesInParens = FormatStyle::SIPO_Custom;
-  Style.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Always;
+  Style.SpacesInParensOptions.InCStyleCasts = true;
   verifyFormat("x = ( _Atomic(uint64_t) )*a;", Style);
-  Style.SpacesInParensOptions.InCStyleCasts = FormatStyle::SIPCS_Never;
-  Style.SpacesInParensOptions.Other = FormatStyle::SIPCS_Always;
+  Style.SpacesInParensOptions.InCStyleCasts = false;
+  Style.SpacesInParensOptions.Other = true;
   verifyFormat("x = (_Atomic( uint64_t ))*a;", Style);
   verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);
 }
@@ -24676,8 +24778,7 @@ TEST_F(FormatTest, SpacesInConditionalStatement) {
   Spaces.IfMacros.clear();
   Spaces.IfMacros.push_back("MYIF");
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
-  Spaces.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_Always;
+  Spaces.SpacesInParensOptions.InConditionalStatements = true;
   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 5078cbe3b66d4..abebf9f7d4c78 100644
--- a/clang/unittests/Format/FormatTestVerilog.cpp
+++ b/clang/unittests/Format/FormatTestVerilog.cpp
@@ -885,8 +885,7 @@ TEST_F(FormatTestVerilog, If) {
                "    x = x;",
                Style);
   Style.SpacesInParens = FormatStyle::SIPO_Custom;
-  Style.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_Always;
+  Style.SpacesInParensOptions.InConditionalStatements = true;
   verifyFormat("if ( x )\n"
                "  x = x;\n"
                "else if ( x )\n"
@@ -983,8 +982,7 @@ TEST_F(FormatTestVerilog, Loop) {
                "end");
   auto Style = getDefaultStyle();
   Style.SpacesInParens = FormatStyle::SIPO_Custom;
-  Style.SpacesInParensOptions.InConditionalStatements =
-      FormatStyle::SIPCS_Always;
+  Style.SpacesInParensOptions.InConditionalStatements = true;
   verifyFormat("foreach ( x[x] )\n"
                "  x = x;",
                Style);

>From 9116b43d025db4effb7a64383fab53c62bacf6f5 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:25:41 -0600
Subject: [PATCH 17/31] Revert the comments of true vs false in columns

---
 clang/include/clang/Format/Format.h | 40 +++++++++--------------------
 1 file changed, 12 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 43be98e9cb1e7..d3553c0e3aa00 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4644,6 +4644,7 @@ struct FormatStyle {
   ///   # Should be declared this way:
   ///   SpacesInParens: Custom
   ///   SpacesInParensOptions:
+  ///     ExceptDoubleParentheses: false
   ///     InConditionalStatements: true
   ///     Other: true
   /// \endcode
@@ -4673,26 +4674,16 @@ struct FormatStyle {
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
-    ///    true:
-    ///    if ( ( a ) )  { ... }
-    ///    while ( i < 5 )  { ... }
-    /// \endcode
-    /// \code
-    ///   false:
-    ///   if ((a)) { ... }
-    ///   while (i < 5) { ... }
+    ///    true:                                  false:
+    ///    if ( ( a ) )  { ... }          vs.     if ((a)) { ... }
+    ///    while ( i < 5 )  { ... }               while (i < 5) { ... }
     /// \endcode
     bool InConditionalStatements;
     /// Put a space in C style casts.
     /// \code
-    ///   true:
-    ///   x = ( int32 )y
-    ///   y = (( int (*)(int) )foo)(x);
-    /// \endcode
-    /// \code
-    ///   false:
-    ///   x = (int32)y
-    ///   y = ((int (*)(int))foo)(x);
+    ///   true:                                  false:
+    ///   x = ( int32 )y                  vs.    x = (int32)y
+    ///   y = (( int (*)(int) )foo)(x);          y = ((int (*)(int))foo)(x);
     /// \endcode
     bool InCStyleCasts;
     /// Put a space in parentheses only if the parentheses are empty i.e. '()'
@@ -4708,18 +4699,11 @@ struct FormatStyle {
     bool InEmptyParentheses;
     /// Put a space in parentheses not covered by preceding options.
     /// \code
-    ///   true:
-    ///   t f( Deleted & ) & = delete;
-    ///   decltype( ( x ) )
-    ///   x = ( (int32)y )
-    ///   y = ( (int ( * )( int ))foo )( x );
-    /// \endcode
-    /// \code
-    ///   false:
-    ///   t f(Deleted &) & = delete;
-    ///   decltype((x))
-    ///   x = ((int32))y
-    ///   y = ((int (*)(int))foo)(x);
+    ///   true:                                 false:
+    ///   t f( Deleted & ) & = delete;    vs.   t f(Deleted &) & = delete;
+    ///   decltype( ( x ) )                     decltype((x))
+    ///   x = ( (int32)y )                      x = ((int32))y
+    ///   y = ( (int ( * )( int ))foo )( x );   y = ((int (*)(int))foo)(x);
     /// \endcode
     bool Other;
 

>From 8cde2ae179102a817d167d431a3d9bc923019876 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:31:35 -0600
Subject: [PATCH 18/31] Remove InAttributeSpecifiers

---
 clang/include/clang/Format/Format.h        | 22 +++++-----------------
 clang/lib/Format/Format.cpp                |  2 --
 clang/lib/Format/TokenAnnotator.cpp        |  4 ++--
 clang/unittests/Format/ConfigParseTest.cpp |  1 -
 clang/unittests/Format/FormatTest.cpp      |  5 ++---
 5 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index d3553c0e3aa00..46caf0f8c2eaf 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4661,16 +4661,6 @@ struct FormatStyle {
     ///  false:
     ///    Uses the applicable option.
     bool ExceptDoubleParentheses;
-    /// Put a space in parentheses of attribute specifiers.
-    /// \code
-    ///    true:
-    ///    __attribute__( ( noreturn ) )
-    /// \endcode
-    /// \code
-    ///    false:
-    ///    _attribute__((noreturn))
-    /// \endcode
-    bool InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
@@ -4704,27 +4694,25 @@ struct FormatStyle {
     ///   decltype( ( x ) )                     decltype((x))
     ///   x = ( (int32)y )                      x = ((int32))y
     ///   y = ( (int ( * )( int ))foo )( x );   y = ((int (*)(int))foo)(x);
+    ///    __attribute__( ( noreturn ) )        __attribute__((noreturn))
     /// \endcode
     bool Other;
 
     SpacesInParensCustom()
-        : ExceptDoubleParentheses(false), InAttributeSpecifiers(false),
-          InConditionalStatements(false), InCStyleCasts(false),
-          InEmptyParentheses(false), Other(false) {}
+        : ExceptDoubleParentheses(false),
+        InConditionalStatements(false), InCStyleCasts(false),
+        InEmptyParentheses(false), Other(false) {}
 
     SpacesInParensCustom(bool ExceptDoubleParentheses,
-                         bool InAttributeSpecifiers,
                          bool InConditionalStatements, bool InCStyleCasts,
                          bool InEmptyParentheses, bool Other)
         : ExceptDoubleParentheses(ExceptDoubleParentheses),
-          InAttributeSpecifiers(InAttributeSpecifiers),
           InConditionalStatements(InConditionalStatements),
           InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
           Other(Other) {}
 
     bool operator==(const SpacesInParensCustom &R) const {
       return ExceptDoubleParentheses == R.ExceptDoubleParentheses &&
-             InAttributeSpecifiers == R.InAttributeSpecifiers &&
              InConditionalStatements == R.InConditionalStatements &&
              InCStyleCasts == R.InCStyleCasts &&
              InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
@@ -4743,7 +4731,7 @@ struct FormatStyle {
   ///   # Example of usage:
   ///   SpacesInParens: Custom
   ///   SpacesInParensOptions:
-  ///     InAttributeSpecifiers: false
+  ///     ExceptDoubleParentheses: false
   ///     InConditionalStatements: true
   ///     InEmptyParentheses: true
   /// \endcode
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index e5b5518b19329..b7d5722127363 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -721,7 +721,6 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
 template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
   static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
     IO.mapOptional("ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);
-    IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
     IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
     IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
     IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);
@@ -1178,7 +1177,6 @@ template <> struct MappingTraits<FormatStyle> {
       if (SpacesInParentheses) {
         // for backward compatibility.
         Style.SpacesInParensOptions.ExceptDoubleParentheses = false;
-        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 fbcf2d0b3b4f7..7d2d1ef1fb147 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4416,10 +4416,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     if (RightParen && RightParen->is(TT_CastRParen))
       return AddSpace(Style.SpacesInParensOptions.InCStyleCasts);
     if (IsAttributeParen(LeftParen) || IsAttributeParen(RightParen))
-      return AddSpace(Style.SpacesInParensOptions.InAttributeSpecifiers);
+      return AddSpace(Style.SpacesInParensOptions.Other);
     if ((LeftParen && IsAttributeParen(LeftParen->Previous)) ||
         (RightParen && IsAttributeParen(RightParen->Next))) {
-      return AddSpace(Style.SpacesInParensOptions.InAttributeSpecifiers);
+      return AddSpace(Style.SpacesInParensOptions.Other);
     }
     return AddSpace(Style.SpacesInParensOptions.Other);
   }
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 00e8e196b6631..e52e1286390e3 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -236,7 +236,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, ExceptDoubleParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index e410e864835c5..0bab017896495 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17102,7 +17102,6 @@ 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);
@@ -17323,7 +17322,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.IndentWidth = 2;
   Spaces.SpacesInParens = FormatStyle::SIPO_Custom;
   Spaces.SpacesInParensOptions = {};
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  Spaces.SpacesInParensOptions.Other = true;
   verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
   verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
   verifyFormat("void f() __attribute__( ( asdf ) );", Spaces);
@@ -17341,7 +17340,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("class __declspec( dllimport ) X {};", Spaces);
   verifyFormat("class __declspec(( dllimport )) X {};", Spaces);
 
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
+  Spaces.SpacesInParensOptions.Other = false;
   verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f() __attribute__((asdf));", Spaces);

>From e718473bac38db9a8c544952d72e0a964dfd069f Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:32:00 -0600
Subject: [PATCH 19/31] Remove ReleaseNote about InAttributeSpecifiers

---
 clang/docs/ReleaseNotes.rst | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8e088b7f9cafd..0a76cacf8304b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -895,8 +895,6 @@ clang-format
 - Handles Java ``switch`` expressions.
 - Adds ``AllowShortCaseExpressionOnASingleLine`` option.
 - Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``.
-- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions``
-  to control addition of spaces after the ``__attribute__`` keyword.
 - Add ``ExceptDoubleParentheses`` sub-option for ``SpacesInParensOptions``
   to override addition of spaces between multiple, non-redundant parentheses
   similar to the rules used for ``RemoveParentheses``.

>From a423067a5b333720e15270b10352c2b0240f248b Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:32:45 -0600
Subject: [PATCH 20/31] Dump format style

---
 clang/docs/ClangFormatStyleOptions.rst | 58 +++++++-------------------
 1 file changed, 14 insertions(+), 44 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index fa6fcef83d8c2..d8ce5c5c0e4b6 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6206,7 +6206,7 @@ the configuration (without a prefix: ``Auto``).
     # Example of usage:
     SpacesInParens: Custom
     SpacesInParensOptions:
-      InAttributeSpecifiers: false
+      ExceptDoubleParentheses: false
       InConditionalStatements: true
       InEmptyParentheses: true
 
@@ -6219,6 +6219,7 @@ the configuration (without a prefix: ``Auto``).
     # Should be declared this way:
     SpacesInParens: Custom
     SpacesInParensOptions:
+      ExceptDoubleParentheses: false
       InConditionalStatements: true
       Other: true
 
@@ -6235,46 +6236,22 @@ the configuration (without a prefix: ``Auto``).
      false:
        Uses the applicable option.
 
-  * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
-
-    .. code-block:: c++
-
-       true:
-       __attribute__( ( noreturn ) )
-
-    .. code-block:: c++
-
-       false:
-       _attribute__((noreturn))
-
   * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
     (``for/if/while/switch...``).
 
     .. code-block:: c++
 
-       true:
-       if ( ( a ) )  { ... }
-       while ( i < 5 )  { ... }
-
-    .. code-block:: c++
-
-      false:
-      if ((a)) { ... }
-      while (i < 5) { ... }
+       true:                                  false:
+       if ( ( a ) )  { ... }          vs.     if ((a)) { ... }
+       while ( i < 5 )  { ... }               while (i < 5) { ... }
 
   * ``bool InCStyleCasts`` Put a space in C style casts.
 
     .. code-block:: c++
 
-      true:
-      x = ( int32 )y
-      y = (( int (*)(int) )foo)(x);
-
-    .. code-block:: c++
-
-      false:
-      x = (int32)y
-      y = ((int (*)(int))foo)(x);
+      true:                                  false:
+      x = ( int32 )y                  vs.    x = (int32)y
+      y = (( int (*)(int) )foo)(x);          y = ((int (*)(int))foo)(x);
 
   * ``bool InEmptyParentheses`` Put a space in parentheses only if the parentheses are empty i.e. '()'
 
@@ -6292,19 +6269,12 @@ the configuration (without a prefix: ``Auto``).
 
     .. code-block:: c++
 
-      true:
-      t f( Deleted & ) & = delete;
-      decltype( ( x ) )
-      x = ( (int32)y )
-      y = ( (int ( * )( int ))foo )( x );
-
-    .. code-block:: c++
-
-      false:
-      t f(Deleted &) & = delete;
-      decltype((x))
-      x = ((int32))y
-      y = ((int (*)(int))foo)(x);
+      true:                                 false:
+      t f( Deleted & ) & = delete;    vs.   t f(Deleted &) & = delete;
+      decltype( ( x ) )                     decltype((x))
+      x = ( (int32)y )                      x = ((int32))y
+      y = ( (int ( * )( int ))foo )( x );   y = ((int (*)(int))foo)(x);
+       __attribute__( ( noreturn ) )        __attribute__((noreturn))
 
 
 .. _SpacesInParentheses:

>From e7379c546971c7d6ab50ac98e92d2bbcfce3c9f0 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:39:07 -0600
Subject: [PATCH 21/31] TOkenAnnotator: rename labda per review

---
 clang/lib/Format/TokenAnnotator.cpp        | 4 ++--
 clang/unittests/Format/ConfigParseTest.cpp | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 7d2d1ef1fb147..52a9389a5077a 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4379,7 +4379,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     const auto IsAttributeParen = [](const FormatToken *Paren) {
       return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
     };
-    auto AddSpaceInDoubleParens = [&]() {
+    auto AddSpaceExceptInDoubleParens = [&]() {
       const auto *RPrev = RightParen ? RightParen->Previous : nullptr;
       const auto *LNext = LeftParen->Next;
       const auto *LPrev = LeftParen->Previous;
@@ -4404,7 +4404,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     };
     const auto AddSpace = [&](bool Option) {
       if (Style.SpacesInParensOptions.ExceptDoubleParentheses && Option)
-        return AddSpaceInDoubleParens();
+        return AddSpaceExceptInDoubleParens();
       return Option;
     };
 
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index e52e1286390e3..70967fe912438 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -640,21 +640,21 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParensOptions = {};
   CHECK_PARSE(
       "SpacesInParentheses: true", SpacesInParensOptions,
-      FormatStyle::SpacesInParensCustom(false, true, true, false, false, true));
+      FormatStyle::SpacesInParensCustom(false, true, false, false, true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, true, false,
+              FormatStyle::SpacesInParensCustom(false, true, false,
                                                 false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, false, true,
+              FormatStyle::SpacesInParensCustom(false, false, true,
                                                 false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, false, false,
+              FormatStyle::SpacesInParensCustom(false, false, false,
                                                 true, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};

>From 478d015af81746ff31c0c4a9daae8bb08d424853 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:40:03 -0600
Subject: [PATCH 22/31] remove accidentally rebased hunk

---
 clang/unittests/Format/ConfigParseTest.cpp | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 70967fe912438..d7bbae4edcdc1 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -613,24 +613,6 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               SpaceBeforeParens,
               FormatStyle::SBPO_ControlStatementsExceptControlMacros);
 
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Custom;
-  Style.SpaceBeforeParensOptions.AfterPlacementOperator =
-      FormatStyle::SpaceBeforeParensCustom::APO_Always;
-  CHECK_PARSE("SpaceBeforeParensOptions:\n"
-              "  AfterPlacementOperator: Never",
-              SpaceBeforeParensOptions.AfterPlacementOperator,
-              FormatStyle::SpaceBeforeParensCustom::APO_Never);
-
-  CHECK_PARSE("SpaceBeforeParensOptions:\n"
-              "  AfterPlacementOperator: Always",
-              SpaceBeforeParensOptions.AfterPlacementOperator,
-              FormatStyle::SpaceBeforeParensCustom::APO_Always);
-
-  CHECK_PARSE("SpaceBeforeParensOptions:\n"
-              "  AfterPlacementOperator: Leave",
-              SpaceBeforeParensOptions.AfterPlacementOperator,
-              FormatStyle::SpaceBeforeParensCustom::APO_Leave);
-
   // For backward compatibility:
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};

>From 309385ea20029cc6adc5600fed7fa49d2493ed99 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 12:57:45 -0600
Subject: [PATCH 23/31] Fix FormatTest for Other replacing InAttribute

---
 clang/unittests/Format/FormatTest.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 0bab017896495..1a2b4edb662c2 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17324,19 +17324,19 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.Other = true;
   verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
-  verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
+  verifyFormat("void __attribute__( ( naked ) ) foo( int bar )", Spaces);
   verifyFormat("void f() __attribute__( ( asdf ) );", Spaces);
-  verifyFormat("__attribute__( ( __aligned__(x) ) ) z;", Spaces);
-  verifyFormat("int x __attribute__( ( aligned(16) ) ) = 0;", Spaces);
+  verifyFormat("__attribute__( ( __aligned__( x ) ) ) z;", Spaces);
+  verifyFormat("int x __attribute__( ( aligned( 16 ) ) ) = 0;", Spaces);
   verifyFormat("class __declspec( dllimport ) X {};", Spaces);
   verifyFormat("class __declspec( ( dllimport ) ) X {};", Spaces);
 
   Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
   verifyFormat("SomeType *__attribute__(( attr )) *a = NULL;", Spaces);
-  verifyFormat("void __attribute__(( naked )) foo(int bar)", Spaces);
+  verifyFormat("void __attribute__(( naked )) foo( int bar )", Spaces);
   verifyFormat("void f() __attribute__(( asdf ));", Spaces);
-  verifyFormat("__attribute__(( __aligned__(x) )) z;", Spaces);
-  verifyFormat("int x __attribute__(( aligned(16) )) = 0;", Spaces);
+  verifyFormat("__attribute__(( __aligned__( x ) )) z;", Spaces);
+  verifyFormat("int x __attribute__(( aligned( 16 ) )) = 0;", Spaces);
   verifyFormat("class __declspec( dllimport ) X {};", Spaces);
   verifyFormat("class __declspec(( dllimport )) X {};", Spaces);
 

>From d02296bc7540e42af7a13b1c82479c1b1a58b92c Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 13:00:29 -0600
Subject: [PATCH 24/31] TokenAnnotator: refactor conditional logic a bit

---
 clang/lib/Format/TokenAnnotator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 52a9389a5077a..caa05915b409f 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4400,7 +4400,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
                      (HasEqualBeforeNextParen() &&
                       (LPrev->isOneOf(tok::kw_if, tok::kw_while) ||
                        LPrev->endsSequence(tok::kw_constexpr, tok::kw_if)))));
-      return !(DoubleParens && SuppressSpace);
+      return !DoubleParens || !SuppressSpace;
     };
     const auto AddSpace = [&](bool Option) {
       if (Style.SpacesInParensOptions.ExceptDoubleParentheses && Option)

>From 71c812e01f67bfa2d3ff7203c4c394f58a9d83cb Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 13:08:56 -0600
Subject: [PATCH 25/31] TokenAnnotator: short-circuit evaluation at
 DoubleParens

---
 clang/lib/Format/TokenAnnotator.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index caa05915b409f..06830b312f67a 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4383,8 +4383,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
       const auto *RPrev = RightParen ? RightParen->Previous : nullptr;
       const auto *LNext = LeftParen->Next;
       const auto *LPrev = LeftParen->Previous;
-      const bool DoubleParens =
-          RPrev && RPrev->is(tok::r_paren) && LNext && LNext->is(tok::l_paren);
+      if (!(RPrev && RPrev->is(tok::r_paren) && LNext &&
+            LNext->is(tok::l_paren))) {
+        return true;
+      }
       auto HasEqualBeforeNextParen = [&]() {
         auto *Tok = LNext;
         if (!Tok || !Tok->is(tok::l_paren))
@@ -4400,7 +4402,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
                      (HasEqualBeforeNextParen() &&
                       (LPrev->isOneOf(tok::kw_if, tok::kw_while) ||
                        LPrev->endsSequence(tok::kw_constexpr, tok::kw_if)))));
-      return !DoubleParens || !SuppressSpace;
+      return !SuppressSpace;
     };
     const auto AddSpace = [&](bool Option) {
       if (Style.SpacesInParensOptions.ExceptDoubleParentheses && Option)

>From 32ba58abf1718c9b93a8e8c74be3725661d7dd95 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 13:09:41 -0600
Subject: [PATCH 26/31] Format.h: fix format

---
 clang/include/clang/Format/Format.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 46caf0f8c2eaf..8390cbf7a00a5 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4699,9 +4699,8 @@ struct FormatStyle {
     bool Other;
 
     SpacesInParensCustom()
-        : ExceptDoubleParentheses(false),
-        InConditionalStatements(false), InCStyleCasts(false),
-        InEmptyParentheses(false), Other(false) {}
+        : ExceptDoubleParentheses(false), InConditionalStatements(false),
+          InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
 
     SpacesInParensCustom(bool ExceptDoubleParentheses,
                          bool InConditionalStatements, bool InCStyleCasts,

>From dc014378c033eb36c1cca439d1b0600625dbf474 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 17 May 2024 13:10:34 -0600
Subject: [PATCH 27/31] ConfigParseTest: fix format

---
 clang/unittests/Format/ConfigParseTest.cpp | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index d7bbae4edcdc1..5c0652e4ee373 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -625,19 +625,19 @@ TEST(ConfigParseTest, ParsesConfiguration) {
       FormatStyle::SpacesInParensCustom(false, true, false, false, true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
-  CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, true, false,
-                                                false, false));
+  CHECK_PARSE(
+      "SpacesInConditionalStatement: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, true, false, false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
-  CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, true,
-                                                false, false));
+  CHECK_PARSE(
+      "SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, false, true, false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
-  CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, false,
-                                                true, false));
+  CHECK_PARSE(
+      "SpaceInEmptyParentheses: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, false, false, true, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 

>From f75a81f23dbd8f2a3a182a4b5a683973f135cab1 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Wed, 22 May 2024 13:41:47 -0600
Subject: [PATCH 28/31] fix the example doc code for InConditionalStatements

---
 clang/docs/ClangFormatStyleOptions.rst | 2 +-
 clang/include/clang/Format/Format.h    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index d8ce5c5c0e4b6..3c8e679ca7cd7 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6242,7 +6242,7 @@ the configuration (without a prefix: ``Auto``).
     .. code-block:: c++
 
        true:                                  false:
-       if ( ( a ) )  { ... }          vs.     if ((a)) { ... }
+       if ( a )  { ... }              vs.     if (a) { ... }
        while ( i < 5 )  { ... }               while (i < 5) { ... }
 
   * ``bool InCStyleCasts`` Put a space in C style casts.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 8390cbf7a00a5..0d059b460a0a7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4665,7 +4665,7 @@ struct FormatStyle {
     /// (``for/if/while/switch...``).
     /// \code
     ///    true:                                  false:
-    ///    if ( ( a ) )  { ... }          vs.     if ((a)) { ... }
+    ///    if ( a )  { ... }              vs.     if (a) { ... }
     ///    while ( i < 5 )  { ... }               while (i < 5) { ... }
     /// \endcode
     bool InConditionalStatements;

>From 2f5f30590561283fe8858201fcec1c860e5dad17 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Mon, 27 May 2024 15:14:38 -0700
Subject: [PATCH 29/31] Improve the logic.

---
 clang/lib/Format/TokenAnnotator.cpp | 79 ++++++++++-------------------
 1 file changed, 26 insertions(+), 53 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 06830b312f67a..cd20fcd066d6d 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4346,6 +4346,28 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
        Right.is(tok::r_brace) && Right.isNot(BK_Block))) {
     return Style.SpacesInParensOptions.InEmptyParentheses;
   }
+  if (Style.SpacesInParens == FormatStyle::SIPO_Custom &&
+      Style.SpacesInParensOptions.ExceptDoubleParentheses &&
+      Left.is(tok::r_paren) && Right.is(tok::r_paren)) {
+    auto *InnerLParen = Left.MatchingParen;
+    if (InnerLParen && InnerLParen->Previous == Right.MatchingParen) {
+      InnerLParen->SpacesRequiredBefore = 0;
+      return false;
+    }
+  }
+  if (Style.SpacesInParensOptions.InConditionalStatements) {
+    const FormatToken *LeftParen = nullptr;
+    if (Left.is(tok::l_paren))
+      LeftParen = &Left;
+    else if (Right.is(tok::r_paren) && Right.MatchingParen)
+      LeftParen = Right.MatchingParen;
+    if (LeftParen) {
+      if (LeftParen->is(TT_ConditionLParen))
+        return true;
+      if (LeftParen->Previous && isKeywordWithCondition(*LeftParen->Previous))
+        return true;
+    }
+  }
 
   // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
   if (Left.is(tok::kw_auto) && Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
@@ -4372,60 +4394,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   }
 
   if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
-    const FormatToken *LeftParen =
-        Left.is(tok::l_paren) ? &Left : Right.MatchingParen;
-    const FormatToken *RightParen =
-        LeftParen ? LeftParen->MatchingParen : nullptr;
-    const auto IsAttributeParen = [](const FormatToken *Paren) {
-      return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
-    };
-    auto AddSpaceExceptInDoubleParens = [&]() {
-      const auto *RPrev = RightParen ? RightParen->Previous : nullptr;
-      const auto *LNext = LeftParen->Next;
-      const auto *LPrev = LeftParen->Previous;
-      if (!(RPrev && RPrev->is(tok::r_paren) && LNext &&
-            LNext->is(tok::l_paren))) {
-        return true;
-      }
-      auto HasEqualBeforeNextParen = [&]() {
-        auto *Tok = LNext;
-        if (!Tok || !Tok->is(tok::l_paren))
-          return false;
-        while ((Tok = Tok->Next) && !Tok->isOneOf(tok::l_paren, tok::r_paren))
-          if (Tok->is(tok::equal))
-            return true;
-        return false;
-      };
-      const bool SuppressSpace =
-          IsAttributeParen(LeftParen) ||
-          (LPrev && (LPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
-                     (HasEqualBeforeNextParen() &&
-                      (LPrev->isOneOf(tok::kw_if, tok::kw_while) ||
-                       LPrev->endsSequence(tok::kw_constexpr, tok::kw_if)))));
-      return !SuppressSpace;
-    };
-    const auto AddSpace = [&](bool Option) {
-      if (Style.SpacesInParensOptions.ExceptDoubleParentheses && Option)
-        return AddSpaceExceptInDoubleParens();
-      return Option;
-    };
-
-    if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||
-                      (LeftParen->Previous &&
-                       isKeywordWithCondition(*LeftParen->Previous)))) {
-      return AddSpace(Style.SpacesInParensOptions.InConditionalStatements);
-    }
-    if (RightParen && RightParen->is(TT_CastRParen))
-      return AddSpace(Style.SpacesInParensOptions.InCStyleCasts);
-    if (IsAttributeParen(LeftParen) || IsAttributeParen(RightParen))
-      return AddSpace(Style.SpacesInParensOptions.Other);
-    if ((LeftParen && IsAttributeParen(LeftParen->Previous)) ||
-        (RightParen && IsAttributeParen(RightParen->Next))) {
-      return AddSpace(Style.SpacesInParensOptions.Other);
-    }
-    return AddSpace(Style.SpacesInParensOptions.Other);
+    return (Right.is(TT_CastRParen) ||
+        (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
+               ? Style.SpacesInParensOptions.InCStyleCasts
+               : Style.SpacesInParensOptions.Other;
   }
-
   if (Right.isOneOf(tok::semi, tok::comma))
     return false;
   if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {

>From 9d1bc4716f13d060a493c71fe8f45a33f7042f5a Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 31 May 2024 12:32:43 -0600
Subject: [PATCH 30/31] FormatTest: fix and add test cases for
 ExceptDoubleParentheses

---
 clang/unittests/Format/FormatTest.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 1a2b4edb662c2..a62482e4f9392 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17330,6 +17330,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("int x __attribute__( ( aligned( 16 ) ) ) = 0;", Spaces);
   verifyFormat("class __declspec( dllimport ) X {};", Spaces);
   verifyFormat("class __declspec( ( dllimport ) ) X {};", Spaces);
+  verifyFormat("int x = ( ( a - 1 ) * 3 );", Spaces);
+  verifyFormat("int x = ( 3 * ( a - 1 ) );", Spaces);
 
   Spaces.SpacesInParensOptions.ExceptDoubleParentheses = true;
   verifyFormat("SomeType *__attribute__(( attr )) *a = NULL;", Spaces);
@@ -17339,6 +17341,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("int x __attribute__(( aligned( 16 ) )) = 0;", Spaces);
   verifyFormat("class __declspec( dllimport ) X {};", Spaces);
   verifyFormat("class __declspec(( dllimport )) X {};", Spaces);
+  verifyFormat("int x = ( ( a - 1 ) * 3 );", Spaces);
+  verifyFormat("int x = ( 3 * ( a - 1 ) );", Spaces);
 
   Spaces.SpacesInParensOptions.Other = false;
   verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces);
@@ -17514,10 +17518,10 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("decltype( ( foo() ) ) a = foo();", Spaces);
   verifyFormat("decltype( ( bar( 10 ) ) ) a = bar( 11 );", Spaces);
   verifyFormat("decltype( ( foo->bar ) ) baz;", Spaces);
-  verifyFormat("if (( i = j ))\n"
+  verifyFormat("if ( ( i = j ) )\n"
                "  do_something( i );",
                Spaces);
-  verifyFormat("if constexpr (( a = b ))\n"
+  verifyFormat("if constexpr ( ( a = b ) )\n"
                "  c;",
                Spaces);
 

>From 0c1bc5464d1d752794a43c06b2325c8a317d3850 Mon Sep 17 00:00:00 2001
From: Gedare Bloom <gedare at rtems.org>
Date: Fri, 31 May 2024 12:43:08 -0600
Subject: [PATCH 31/31] format

---
 clang/lib/Format/TokenAnnotator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index cd20fcd066d6d..a26900383b256 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4395,7 +4395,7 @@ 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)))
+            (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
                ? Style.SpacesInParensOptions.InCStyleCasts
                : Style.SpacesInParensOptions.Other;
   }



More information about the cfe-commits mailing list