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

Gedare Bloom via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 11 16:58:31 PST 2024


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

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

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

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

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index ac9a0b70ed5daa..5dc7ad5298f83b 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``).
       InConditionalStatements: true
       Other: true
 
+  * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
+
+    .. code-block:: c++
+
+       true:                                  false:
+       __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+
   * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
     (``for/if/while/switch...``).
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 59732962caac65..f4e29df336b3a6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1102,6 +1102,8 @@ clang-format
   attributes (like ``nonatomic, strong, nullable``).
 - Add ``.clang-format-ignore`` files.
 - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``.
+- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions``
+  to control addition of spaces after the ``__attribute__`` keyword.
 
 libclang
 --------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 5ffd63ee73fc36..95f15a3098044c 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4534,6 +4534,12 @@ struct FormatStyle {
   ///     Other: true
   /// \endcode
   struct SpacesInParensCustom {
+    /// Put a space in parentheses of attribute specifiers.
+    /// \code
+    ///    true:                                  false:
+    ///    __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+    /// \endcode
+    bool InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
@@ -4567,17 +4573,20 @@ struct FormatStyle {
     bool Other;
 
     SpacesInParensCustom()
-        : InConditionalStatements(false), InCStyleCasts(false),
-          InEmptyParentheses(false), Other(false) {}
+        : InAttributeSpecifiers(false), InConditionalStatements(false),
+          InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
 
-    SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts,
+    SpacesInParensCustom(bool InAttributeSpecifiers,
+                         bool InConditionalStatements, bool InCStyleCasts,
                          bool InEmptyParentheses, bool Other)
-        : InConditionalStatements(InConditionalStatements),
+        : InAttributeSpecifiers(InAttributeSpecifiers),
+          InConditionalStatements(InConditionalStatements),
           InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
           Other(Other) {}
 
     bool operator==(const SpacesInParensCustom &R) const {
-      return InConditionalStatements == R.InConditionalStatements &&
+      return InAttributeSpecifiers == R.InAttributeSpecifiers &&
+             InConditionalStatements == R.InConditionalStatements &&
              InCStyleCasts == R.InCStyleCasts &&
              InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
     }
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index ff5ed6c306f383..af4db7161be20b 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -752,6 +752,7 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
 
 template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
   static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
+    IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
     IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
     IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
     IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);
@@ -1190,6 +1191,7 @@ template <> struct MappingTraits<FormatStyle> {
       if (SpacesInParentheses) {
         // set all options except InCStyleCasts and InEmptyParentheses
         // to true for backward compatibility.
+        Style.SpacesInParensOptions.InAttributeSpecifiers = true;
         Style.SpacesInParensOptions.InConditionalStatements = true;
         Style.SpacesInParensOptions.InCStyleCasts =
             SpacesInCStyleCastParentheses;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index b31ecc840626f9..7f48042d064de4 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4005,10 +4005,18 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   }
 
   if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
-    return (Right.is(TT_CastRParen) ||
-            (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
-               ? Style.SpacesInParensOptions.InCStyleCasts
-               : Style.SpacesInParensOptions.Other;
+    if (Right.is(TT_CastRParen) ||
+        (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) {
+      return Style.SpacesInParensOptions.InCStyleCasts;
+    }
+    const auto isAttributeParen = [](const FormatToken *Paren) {
+      return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
+    };
+    if (isAttributeParen(&Left) || isAttributeParen(&Right) ||
+        isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
+      return Style.SpacesInParensOptions.InAttributeSpecifiers;
+    }
+    return Style.SpacesInParensOptions.Other;
   }
   if (Right.isOneOf(tok::semi, tok::comma))
     return false;
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 18ecba270e3455..eed1a882badc2d 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -231,6 +231,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
@@ -632,19 +633,23 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(true, false, false, true));
+              FormatStyle::SpacesInParensCustom(true, true, false, false,
+                  true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(true, false, false, false));
+              FormatStyle::SpacesInParensCustom(false, true, false, false,
+                  false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, true, false, false));
+              FormatStyle::SpacesInParensCustom(false, false, true, false,
+                  false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, true, false));
+              FormatStyle::SpacesInParensCustom(false, false, false, true,
+                  false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 8f115fb8cbf0fb..58a36c7ba2fc26 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16821,6 +16821,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.Other = true;
   Spaces.SpacesInParensOptions.InConditionalStatements = true;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
   verifyFormat("do_something( ::globalVar );", Spaces);
   verifyFormat("call( x, y, z );", Spaces);
   verifyFormat("call();", Spaces);
@@ -16895,6 +16896,12 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
 
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
+  verifyFormat("void f( ) __attribute__( ( asdf ) );", Spaces);
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
+
   // Run the first set of tests again with:
   Spaces.SpaceAfterCStyleCast = true;
   verifyFormat("call(x, y, z);", Spaces);

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

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

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 95f15a3098044c..ebc16c6f8d1292 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4525,6 +4525,16 @@ struct FormatStyle {
   /// \version 17
   SpacesInParensStyle SpacesInParens;
 
+  /// Selective control over spaces in parens.
+  enum SpacesInParensCustomStyle : int8_t {
+    /// Never put spaces in parens.
+    SIPCS_Never,
+    /// Only put spaces in parens not followed by the same consecutive parens.
+    SIPCS_NonConsecutive,
+    /// Always put spaces in parens.
+    SIPCS_Always
+  };
+
   /// Precise control over the spacing in parentheses.
   /// \code
   ///   # Should be declared this way:
@@ -4536,10 +4546,18 @@ struct FormatStyle {
   struct SpacesInParensCustom {
     /// Put a space in parentheses of attribute specifiers.
     /// \code
-    ///    true:                                  false:
-    ///    __attribute__( ( noreturn ) )    vs.     __attribute__((noreturn))
+    ///    Always:
+    ///    __attribute__( ( noreturn ) )
+    /// \endcode
+    /// \code
+    ///   NonConsecutive:
+    ///   _attribute__(( noreturn ))
+    /// \endcode
+    /// \code
+    ///   Never:
+    ///   _attribute__((noreturn))
     /// \endcode
-    bool InAttributeSpecifiers;
+    SpacesInParensCustomStyle InAttributeSpecifiers;
     /// Put a space in parentheses only inside conditional statements
     /// (``for/if/while/switch...``).
     /// \code
@@ -4573,10 +4591,10 @@ struct FormatStyle {
     bool Other;
 
     SpacesInParensCustom()
-        : InAttributeSpecifiers(false), InConditionalStatements(false),
+        : InAttributeSpecifiers(SIPCS_Never), InConditionalStatements(false),
           InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
 
-    SpacesInParensCustom(bool InAttributeSpecifiers,
+    SpacesInParensCustom(SpacesInParensCustomStyle InAttributeSpecifiers,
                          bool InConditionalStatements, bool InCStyleCasts,
                          bool InEmptyParentheses, bool Other)
         : InAttributeSpecifiers(InAttributeSpecifiers),
@@ -4604,6 +4622,7 @@ struct FormatStyle {
   ///   # Example of usage:
   ///   SpacesInParens: Custom
   ///   SpacesInParensOptions:
+  ///     InAttributeSpecifiers: NonConsecutive
   ///     InConditionalStatements: true
   ///     InEmptyParentheses: true
   /// \endcode
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index af4db7161be20b..9bcca72c1e2847 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -750,6 +750,14 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
   }
 };
 
+template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInParensCustomStyle> {
+  static void enumeration(IO &IO, FormatStyle::SpacesInParensCustomStyle &Value) {
+    IO.enumCase(Value, "Never", FormatStyle::SIPCS_Never);
+    IO.enumCase(Value, "NonConsecutive", FormatStyle::SIPCS_NonConsecutive);
+    IO.enumCase(Value, "Always", FormatStyle::SIPCS_Always);
+  }
+};
+
 template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
   static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
     IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
@@ -1191,7 +1199,7 @@ template <> struct MappingTraits<FormatStyle> {
       if (SpacesInParentheses) {
         // set all options except InCStyleCasts and InEmptyParentheses
         // to true for backward compatibility.
-        Style.SpacesInParensOptions.InAttributeSpecifiers = true;
+        Style.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Always;
         Style.SpacesInParensOptions.InConditionalStatements = true;
         Style.SpacesInParensOptions.InCStyleCasts =
             SpacesInCStyleCastParentheses;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 7f48042d064de4..2e27eb7dfa9a4f 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4012,10 +4012,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     const auto isAttributeParen = [](const FormatToken *Paren) {
       return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
     };
-    if (isAttributeParen(&Left) || isAttributeParen(&Right) ||
-        isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
-      return Style.SpacesInParensOptions.InAttributeSpecifiers;
-    }
+    if (isAttributeParen(&Left) || isAttributeParen(&Right))
+      return Style.SpacesInParensOptions.InAttributeSpecifiers == FormatStyle::SIPCS_Always;
+    if (isAttributeParen(Left.Previous) || isAttributeParen(Right.Next))
+      return Style.SpacesInParensOptions.InAttributeSpecifiers != FormatStyle::SIPCS_Never;
     return Style.SpacesInParensOptions.Other;
   }
   if (Right.isOneOf(tok::semi, tok::comma))
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index eed1a882badc2d..7fa1fb943b8595 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -231,7 +231,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
   CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
@@ -625,6 +624,20 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               SpaceBeforeParensOptions.AfterPlacementOperator,
               FormatStyle::SpaceBeforeParensCustom::APO_Leave);
 
+  Style.SpacesInParens = FormatStyle::SIPO_Custom;
+  Style.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
+  CHECK_PARSE("SpacesInParensOptions:\n"
+              "  InAttributeSpecifiers: Always",
+              SpacesInParensOptions.InAttributeSpecifiers,
+              FormatStyle::SIPCS_Always);
+  CHECK_PARSE("SpacesInParensOptions:\n"
+              "  InAttributeSpecifiers: Never",
+              SpacesInParensOptions.InAttributeSpecifiers,
+              FormatStyle::SIPCS_Never);
+  CHECK_PARSE("SpacesInParensOptions:\n"
+              "  InAttributeSpecifiers: NonConsecutive",
+              SpacesInParensOptions.InAttributeSpecifiers,
+              FormatStyle::SIPCS_NonConsecutive);
   // For backward compatibility:
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
@@ -633,23 +646,23 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(true, true, false, false,
-                  true));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Always, true,
+                  false, false, true));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, true, false, false,
-                  false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, true,
+                  false, false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, true, false,
-                  false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, false,
+                  true, false, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
   CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
-              FormatStyle::SpacesInParensCustom(false, false, false, true,
-                  false));
+              FormatStyle::SpacesInParensCustom(FormatStyle::SIPCS_Never, false,
+                  false, true, false));
   Style.SpacesInParens = FormatStyle::SIPO_Never;
   Style.SpacesInParensOptions = {};
 
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 58a36c7ba2fc26..7c613b615e6dc0 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16821,7 +16821,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   Spaces.SpacesInParensOptions = {};
   Spaces.SpacesInParensOptions.Other = true;
   Spaces.SpacesInParensOptions.InConditionalStatements = true;
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
+      FormatStyle::SIPCS_Always;
   verifyFormat("do_something( ::globalVar );", Spaces);
   verifyFormat("call( x, y, z );", Spaces);
   verifyFormat("call();", Spaces);
@@ -16896,11 +16897,17 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
   verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__((asdf));", Spaces);
 
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
+      FormatStyle::SIPCS_Always;
   verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
   verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
   verifyFormat("void f( ) __attribute__( ( asdf ) );", Spaces);
-  Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers =
+      FormatStyle::SIPCS_NonConsecutive;
+  verifyFormat("SomeType *__attribute__(( attr )) *a = NULL;", Spaces);
+  verifyFormat("void __attribute__(( naked )) foo(int bar)", Spaces);
+  verifyFormat("void f( ) __attribute__(( asdf ));", Spaces); 
+  Spaces.SpacesInParensOptions.InAttributeSpecifiers = FormatStyle::SIPCS_Never;
 
   // Run the first set of tests again with:
   Spaces.SpaceAfterCStyleCast = true;

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

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

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

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

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

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

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

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

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

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

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

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

>From 2247d1c208be924124142521247c913827271b5c 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/12] 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 208be4746c0080..8060b7335285a8 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16816,6 +16816,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 = {};
@@ -16853,6 +16870,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 = {};
@@ -16865,6 +16899,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;
@@ -16897,7 +16932,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);
@@ -16910,6 +16965,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 b1e7d62eed2f19b73f6b715155f1a112635bc848 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/12] 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 fc924912ec1fbb..a468fec2020c81 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3978,10 +3978,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 8060b7335285a8..c2676b4a8b2a17 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16828,7 +16828,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"
                "}",
@@ -16871,7 +16871,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);
@@ -16879,10 +16879,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"
                "}",
@@ -16941,28 +16941,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;
@@ -17005,10 +17113,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"
                "}",
@@ -17038,10 +17146,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"
                "}",
@@ -17071,10 +17179,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"
                "}",
@@ -17098,115 +17206,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 dad60f20f5a6bfeb0945fff174c5622da956cef8 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/12] 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 a468fec2020c81..f9c8f6378f5222 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3971,7 +3971,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;
@@ -3984,10 +3983,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 5c8d6ce7405c0b8c49080048244b97709d1c7966 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/12] 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 f9c8f6378f5222..f96a77fb93bf78 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3969,30 +3969,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,
@@ -4016,26 +3992,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 8e36969528706d7c4998edafd9d895359e45ced2 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/12] 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 9470ec31068096..bcdd67796cedb3 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -5763,8 +5763,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 2a6ec4a2e0a772..5c50de8488b04f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4578,8 +4578,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 67ddd037024b7617fe16e5ebc8a85ca0408dcc96 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/12] 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 c2676b4a8b2a17..d2e9813a0d49d6 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -17070,7 +17070,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;
@@ -17087,7 +17087,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"
@@ -17189,7 +17189,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);



More information about the cfe-commits mailing list