https://github.com/aaronsms updated 
https://github.com/llvm/llvm-project/pull/194154

>From 6d55f8117324298b3fcb50881ce4fe045471f95b Mon Sep 17 00:00:00 2001
From: Aaron Saw Min Sern <[email protected]>
Date: Sat, 9 May 2026 16:38:28 +0800
Subject: [PATCH 1/3] add option to only align enum assignments for
 AlignConsecutiveAssignments

---
 clang/docs/ClangFormatStyleOptions.rst     | 77 ++++++++++++++++++++++
 clang/docs/ReleaseNotes.rst                |  2 +
 clang/include/clang/Format/Format.h        | 11 ++++
 clang/lib/Format/Format.cpp                | 16 +++--
 clang/lib/Format/FormatToken.h             |  1 +
 clang/lib/Format/TokenAnnotator.cpp        | 17 ++++-
 clang/lib/Format/TokenAnnotator.h          |  2 +
 clang/lib/Format/WhitespaceManager.cpp     | 13 +++-
 clang/unittests/Format/AlignmentTest.cpp   | 23 ++++++-
 clang/unittests/Format/ConfigParseTest.cpp | 72 ++++++++++----------
 10 files changed, 189 insertions(+), 45 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index fe8dfa406bc32..55f5fbf8560f3 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -402,6 +402,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
@@ -560,6 +571,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
@@ -718,6 +740,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
@@ -877,6 +910,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
@@ -1155,6 +1199,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
@@ -1311,6 +1366,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
@@ -1467,6 +1533,17 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
+    aligned.
+
+    .. code-block:: c++
+
+      enum ValueKind {
+        VK_Argument   = 1,
+        VK_BasicBlock = 2,
+        VK_Segment    = 8,
+      };
+
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
     put all assignment operators to the right of the left hand side.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c5c8c1fa12e7a..7f36408d1a55f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -697,6 +697,8 @@ clang-format
 - Extend ``BreakBinaryOperations`` to accept a structured configuration with
   per-operator break rules and minimum chain length gating via ``PerOperator``.
 - Add ``AllowShortRecordOnASingleLine`` option and set it to 
``EmptyAndAttached`` for LLVM style.
+- Add ``EnumAssignments`` option to ``AlignConsecutiveAssignments`` for 
aligning
+  enum assignments without affecting other assignments.
 
 libclang
 --------
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index f89323c71713b..80589e8bbfa5e 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -236,6 +236,16 @@ struct FormatStyle {
     ///   int (*f)();
     /// \endcode
     bool AlignFunctionPointers;
+    /// Only for ``AlignConsecutiveAssignments``. Whether enum assignments are
+    /// aligned.
+    /// \code
+    ///   enum ValueKind {
+    ///     VK_Argument   = 1,
+    ///     VK_BasicBlock = 2,
+    ///     VK_Segment    = 8,
+    ///   };
+    /// \endcode
+    bool EnumAssignments;
     /// Only for ``AlignConsecutiveAssignments``.  Whether short assignment
     /// operators are left-padded to the same length as long ones in order to
     /// put all assignment operators to the right of the left hand side.
@@ -259,6 +269,7 @@ struct FormatStyle {
       return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
              AcrossComments == R.AcrossComments &&
              AlignCompound == R.AlignCompound &&
+             EnumAssignments == R.EnumAssignments &&
              AlignFunctionDeclarations == R.AlignFunctionDeclarations &&
              AlignFunctionPointers == R.AlignFunctionPointers &&
              PadOperators == R.PadOperators;
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 8d447177a18a7..249fa1f950f9a 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -62,25 +62,29 @@ template <> struct 
MappingTraits<FormatStyle::AlignConsecutiveStyle> {
                     {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
                      /*AcrossComments=*/false, /*AlignCompound=*/false,
                      /*AlignFunctionDeclarations=*/true,
-                     /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
+                     /*AlignFunctionPointers=*/false,
+                     /*EnumAssignments=*/true, /*PadOperators=*/true}));
     IO.enumCase(Value, "AcrossEmptyLines",
                 FormatStyle::AlignConsecutiveStyle(
                     {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
                      /*AcrossComments=*/false, /*AlignCompound=*/false,
                      /*AlignFunctionDeclarations=*/true,
-                     /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
+                     /*AlignFunctionPointers=*/false,
+                     /*EnumAssignments=*/true, /*PadOperators=*/true}));
     IO.enumCase(Value, "AcrossComments",
                 FormatStyle::AlignConsecutiveStyle(
                     {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
                      /*AcrossComments=*/true, /*AlignCompound=*/false,
                      /*AlignFunctionDeclarations=*/true,
-                     /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
+                     /*AlignFunctionPointers=*/false,
+                     /*EnumAssignments=*/true, /*PadOperators=*/true}));
     IO.enumCase(Value, "AcrossEmptyLinesAndComments",
                 FormatStyle::AlignConsecutiveStyle(
                     {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
                      /*AcrossComments=*/true, /*AlignCompound=*/false,
                      /*AlignFunctionDeclarations=*/true,
-                     /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
+                     /*AlignFunctionPointers=*/false,
+                     /*EnumAssignments=*/true, /*PadOperators=*/true}));
 
     // For backward compatibility.
     IO.enumCase(Value, "true",
@@ -88,7 +92,8 @@ template <> struct 
MappingTraits<FormatStyle::AlignConsecutiveStyle> {
                     {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
                      /*AcrossComments=*/false, /*AlignCompound=*/false,
                      /*AlignFunctionDeclarations=*/true,
-                     /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
+                     /*AlignFunctionPointers=*/false,
+                     /*EnumAssignments=*/true, /*PadOperators=*/true}));
     IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle{});
   }
 
@@ -100,6 +105,7 @@ template <> struct 
MappingTraits<FormatStyle::AlignConsecutiveStyle> {
     IO.mapOptional("AlignFunctionDeclarations",
                    Value.AlignFunctionDeclarations);
     IO.mapOptional("AlignFunctionPointers", Value.AlignFunctionPointers);
+    IO.mapOptional("EnumAssignments", Value.EnumAssignments);
     IO.mapOptional("PadOperators", Value.PadOperators);
   }
 };
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 68d94b087136d..1d8f0f1cfe412 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -76,6 +76,7 @@ namespace format {
   TYPE(DoWhile)                                                                
\
   TYPE(ElseLBrace)                                                             
\
   TYPE(ElseRBrace)                                                             
\
+  TYPE(EnumEqual)                                                              
\
   TYPE(EnumLBrace)                                                             
\
   TYPE(EnumRBrace)                                                             
\
   TYPE(EnumUnderlyingTypeColon)                                                
\
diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 898759cb8ea1b..7a555e05ec08b 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -139,6 +139,8 @@ class AnnotatingParser {
     case TT_StructLBrace:
     case TT_UnionLBrace:
       return ST_Class;
+    case TT_EnumLBrace:
+      return ST_Enum;
     case TT_CompoundRequirementLBrace:
       return ST_CompoundRequirement;
     default:
@@ -1232,6 +1234,7 @@ class AnnotatingParser {
         return false;
       updateParameterCount(&OpeningBrace, CurrentToken);
       if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
+        assert(!Scopes.empty());
         FormatToken *Previous = CurrentToken->getPreviousNonComment();
         if (Previous->is(TT_JsTypeOptionalQuestion))
           Previous = Previous->getPreviousNonComment();
@@ -1239,6 +1242,7 @@ class AnnotatingParser {
              (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||
             Style.isProto()) {
           OpeningBrace.setType(TT_DictLiteral);
+          Scopes.back() = getScopeType(OpeningBrace);
           if (Previous->Tok.getIdentifierInfo() ||
               Previous->is(tok::string_literal)) {
             Previous->setType(TT_SelectorName);
@@ -1247,16 +1251,21 @@ class AnnotatingParser {
         if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown) &&
             !Style.isTableGen()) {
           OpeningBrace.setType(TT_DictLiteral);
+          Scopes.back() = getScopeType(OpeningBrace);
         } else if (Style.isJavaScript()) {
           OpeningBrace.overwriteFixedType(TT_DictLiteral);
+          Scopes.back() = getScopeType(OpeningBrace);
         }
       }
       bool IsBracedListComma = false;
       if (CurrentToken->is(tok::comma)) {
-        if (Style.isJavaScript())
+        assert(!Scopes.empty());
+        if (Style.isJavaScript()) {
           OpeningBrace.overwriteFixedType(TT_DictLiteral);
-        else
+          Scopes.back() = getScopeType(OpeningBrace);
+        } else {
           IsBracedListComma = OpeningBrace.is(BK_BracedInit);
+        }
         ++CommaCount;
       }
       if (!consumeToken())
@@ -1835,6 +1844,10 @@ class AnnotatingParser {
       // In TableGen, there must be a value after "=";
       if (Style.isTableGen() && !parseTableGenValue())
         return false;
+      if ((CurrentToken && CurrentToken->is(tok::numeric_constant)) &&
+          (!Scopes.empty() && Scopes.back() == ST_Enum)) {
+        Tok->setFinalizedType(TT_EnumEqual);
+      }
       break;
     default:
       break;
diff --git a/clang/lib/Format/TokenAnnotator.h 
b/clang/lib/Format/TokenAnnotator.h
index 597dd890ee990..33c7df9d0f949 100644
--- a/clang/lib/Format/TokenAnnotator.h
+++ b/clang/lib/Format/TokenAnnotator.h
@@ -40,6 +40,8 @@ enum LineType {
 enum ScopeType {
   // Contained in class declaration/definition.
   ST_Class,
+  // Contained in enum declaration/definition.
+  ST_Enum,
   // Contained in compound requirement.
   ST_CompoundRequirement,
   // Contained in other blocks (function, lambda, loop, if/else, child, etc).
diff --git a/clang/lib/Format/WhitespaceManager.cpp 
b/clang/lib/Format/WhitespaceManager.cpp
index 74aa8a2795150..4a72abbfa9ec3 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -813,8 +813,10 @@ void WhitespaceManager::alignConsecutiveMacros() {
 }
 
 void WhitespaceManager::alignConsecutiveAssignments() {
-  if (!Style.AlignConsecutiveAssignments.Enabled)
+  if (!Style.AlignConsecutiveAssignments.Enabled &&
+      !Style.AlignConsecutiveAssignments.EnumAssignments) {
     return;
+  }
 
   AlignTokens(
       Style,
@@ -827,6 +829,15 @@ void WhitespaceManager::alignConsecutiveAssignments() {
         if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
           return false;
 
+        // Align enum '=' when EnumAssignments is enabled.
+        if (Style.AlignConsecutiveAssignments.EnumAssignments &&
+            C.Tok->is(TT_EnumEqual)) {
+          return true;
+        }
+
+        if (!Style.AlignConsecutiveAssignments.Enabled)
+          return false;
+
         // Do not align operator= overloads.
         FormatToken *Previous = C.Tok->getPreviousNonComment();
         if (Previous && Previous->is(tok::kw_operator))
diff --git a/clang/unittests/Format/AlignmentTest.cpp 
b/clang/unittests/Format/AlignmentTest.cpp
index 2f49c5c7875a4..6109fc276319c 100644
--- a/clang/unittests/Format/AlignmentTest.cpp
+++ b/clang/unittests/Format/AlignmentTest.cpp
@@ -1135,6 +1135,25 @@ TEST_F(AlignmentTest, 
ConsecutiveAssignmentsAcrossEmptyLinesAndComments) {
                Alignment);
 }
 
+TEST_F(AlignmentTest, ConsecutiveEnumAssignments) {
+  FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveAssignments.EnumAssignments = true;
+  verifyFormat("enum ValueKind {\n"
+               "  VK_Argument   = 1,\n"
+               "  VK_BasicBlock = 2,\n"
+               "  VK_Segment    = 8,\n"
+               "};",
+               Alignment);
+  Alignment.AlignConsecutiveAssignments.Enabled = true;
+  Alignment.AlignConsecutiveAssignments.EnumAssignments = false;
+  verifyFormat("enum ValueKind {\n"
+               "  VK_Argument   = 1,\n"
+               "  VK_BasicBlock = 2,\n"
+               "  VK_Segment    = 8,\n"
+               "};",
+               Alignment);
+}
+
 TEST_F(AlignmentTest, ConsecutiveCompoundAssignments) {
   FormatStyle Alignment = getLLVMStyle();
   Alignment.AlignConsecutiveAssignments.Enabled = true;
@@ -2363,14 +2382,14 @@ TEST_F(AlignmentTest, AlignWithLineBreaks) {
                  /*AcrossComments=*/false, /*AlignCompound=*/false,
                  /*AlignFunctionDeclarations=*/false,
                  /*AlignFunctionPointers=*/false,
-                 /*PadOperators=*/true}));
+                 /*EnumAssignments=*/false, /*PadOperators=*/true}));
   EXPECT_EQ(Style.AlignConsecutiveDeclarations,
             FormatStyle::AlignConsecutiveStyle(
                 {/*Enabled=*/false, /*AcrossEmptyLines=*/false,
                  /*AcrossComments=*/false, /*AlignCompound=*/false,
                  /*AlignFunctionDeclarations=*/true,
                  /*AlignFunctionPointers=*/false,
-                 /*PadOperators=*/false}));
+                 /*EnumAssignments=*/false, /*PadOperators=*/false}));
   verifyFormat("void foo() {\n"
                "  int myVar = 5;\n"
                "  double x = 3.14;\n"
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index 498e44b190ef2..9c1b870796454 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -338,44 +338,44 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   do {                                                                         
\
     Style.FIELD.Enabled = true;                                                
\
     CHECK_PARSE(#FIELD ": None", FIELD, FormatStyle::AlignConsecutiveStyle{}); 
\
-    CHECK_PARSE(                                                               
\
-        #FIELD ": Consecutive", FIELD,                                         
\
-        FormatStyle::AlignConsecutiveStyle(                                    
\
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     
\
-             /*AcrossComments=*/false, /*AlignCompound=*/false,                
\
-             /*AlignFunctionDeclarations=*/true,                               
\
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        
\
-    CHECK_PARSE(                                                               
\
-        #FIELD ": AcrossEmptyLines", FIELD,                                    
\
-        FormatStyle::AlignConsecutiveStyle(                                    
\
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/true,                      
\
-             /*AcrossComments=*/false, /*AlignCompound=*/false,                
\
-             /*AlignFunctionDeclarations=*/true,                               
\
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        
\
-    CHECK_PARSE(                                                               
\
-        #FIELD ": AcrossComments", FIELD,                                      
\
-        FormatStyle::AlignConsecutiveStyle(                                    
\
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     
\
-             /*AcrossComments=*/true, /*AlignCompound=*/false,                 
\
-             /*AlignFunctionDeclarations=*/true,                               
\
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        
\
-    CHECK_PARSE(                                                               
\
-        #FIELD ": AcrossEmptyLinesAndComments", FIELD,                         
\
-        FormatStyle::AlignConsecutiveStyle(                                    
\
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/true,                      
\
-             /*AcrossComments=*/true, /*AlignCompound=*/false,                 
\
-             /*AlignFunctionDeclarations=*/true,                               
\
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        
\
+    CHECK_PARSE(#FIELD ": Consecutive", FIELD,                                 
\
+                FormatStyle::AlignConsecutiveStyle(                            
\
+                    {/*Enabled=*/true, /*AcrossEmptyLines=*/false,             
\
+                     /*AcrossComments=*/false, /*AlignCompound=*/false,        
\
+                     /*AlignFunctionDeclarations=*/true,                       
\
+                     /*AlignFunctionPointers=*/false,                          
\
+                     /*EnumAssignments =*/true, /*PadOperators=*/true}));      
\
+    CHECK_PARSE(#FIELD ": AcrossEmptyLines", FIELD,                            
\
+                FormatStyle::AlignConsecutiveStyle(                            
\
+                    {/*Enabled=*/true, /*AcrossEmptyLines=*/true,              
\
+                     /*AcrossComments=*/false, /*AlignCompound=*/false,        
\
+                     /*AlignFunctionDeclarations=*/true,                       
\
+                     /*AlignFunctionPointers=*/false,                          
\
+                     /*EnumAssignments =*/true, /*PadOperators=*/true}));      
\
+    CHECK_PARSE(#FIELD ": AcrossComments", FIELD,                              
\
+                FormatStyle::AlignConsecutiveStyle(                            
\
+                    {/*Enabled=*/true, /*AcrossEmptyLines=*/false,             
\
+                     /*AcrossComments=*/true, /*AlignCompound=*/false,         
\
+                     /*AlignFunctionDeclarations=*/true,                       
\
+                     /*AlignFunctionPointers=*/false,                          
\
+                     /*EnumAssignments =*/true, /*PadOperators=*/true}));      
\
+    CHECK_PARSE(#FIELD ": AcrossEmptyLinesAndComments", FIELD,                 
\
+                FormatStyle::AlignConsecutiveStyle(                            
\
+                    {/*Enabled=*/true, /*AcrossEmptyLines=*/true,              
\
+                     /*AcrossComments=*/true, /*AlignCompound=*/false,         
\
+                     /*AlignFunctionDeclarations=*/true,                       
\
+                     /*AlignFunctionPointers=*/false,                          
\
+                     /*EnumAssignments =*/true, /*PadOperators=*/true}));      
\
     /* For backwards compability, false / true should still parse */           
\
     CHECK_PARSE(#FIELD ": false", FIELD,                                       
\
                 FormatStyle::AlignConsecutiveStyle{});                         
\
-    CHECK_PARSE(                                                               
\
-        #FIELD ": true", FIELD,                                                
\
-        FormatStyle::AlignConsecutiveStyle(                                    
\
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     
\
-             /*AcrossComments=*/false, /*AlignCompound=*/false,                
\
-             /*AlignFunctionDeclarations=*/true,                               
\
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        
\
+    CHECK_PARSE(#FIELD ": true", FIELD,                                        
\
+                FormatStyle::AlignConsecutiveStyle(                            
\
+                    {/*Enabled=*/true, /*AcrossEmptyLines=*/false,             
\
+                     /*AcrossComments=*/false, /*AlignCompound=*/false,        
\
+                     /*AlignFunctionDeclarations=*/true,                       
\
+                     /*AlignFunctionPointers=*/false,                          
\
+                     /*EnumAssignments =*/true, /*PadOperators=*/true}));      
\
                                                                                
\
     CHECK_PARSE_NESTED_BOOL(FIELD, Enabled);                                   
\
     CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines);                          
\
@@ -383,8 +383,10 @@ TEST(ConfigParseTest, ParsesConfiguration) {
     CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound);                             
\
     CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations);                 
\
     CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers);                     
\
+    CHECK_PARSE_NESTED_BOOL(FIELD, EnumAssignments);                           
\
     CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators);                              
\
   } while (false)
+  // @todo
 
   CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
   CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);

>From 90ef0107640261bf2bf1a5350b5a4b1e0e675474 Mon Sep 17 00:00:00 2001
From: Aaron Saw Min Sern <[email protected]>
Date: Sun, 10 May 2026 16:37:41 +0800
Subject: [PATCH 2/3] annotate enum assignments with RHS besides numeric
 constant

---
 clang/docs/ClangFormatStyleOptions.rst     | 98 +++++++---------------
 clang/include/clang/Format/Format.h        | 15 ++--
 clang/lib/Format/TokenAnnotator.cpp        | 20 ++---
 clang/unittests/Format/ConfigParseTest.cpp |  1 -
 4 files changed, 39 insertions(+), 95 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 55f5fbf8560f3..6c237f0065f18 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -402,16 +402,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
@@ -571,16 +565,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
@@ -740,16 +728,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
@@ -910,16 +892,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
@@ -1199,16 +1175,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
@@ -1366,16 +1336,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
@@ -1533,16 +1497,10 @@ the configuration (without a prefix: ``Auto``).
       int     *p;
       int (*f)();
 
-  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``. Whether 
enum assignments are
-    aligned.
-
-    .. code-block:: c++
-
-      enum ValueKind {
-        VK_Argument   = 1,
-        VK_BasicBlock = 2,
-        VK_Segment    = 8,
-      };
+  * ``bool EnumAssignments`` Only for ``AlignConsecutiveAssignments``.
+    Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    setting this to ``true`` forces alignment for enum assignments only.
+    If ``Enabled`` is ``true``, enum assignments are always aligned.
 
   * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
     operators are left-padded to the same length as long ones in order to
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 80589e8bbfa5e..605a33e4fb406 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -236,15 +236,10 @@ struct FormatStyle {
     ///   int (*f)();
     /// \endcode
     bool AlignFunctionPointers;
-    /// Only for ``AlignConsecutiveAssignments``. Whether enum assignments are
-    /// aligned.
-    /// \code
-    ///   enum ValueKind {
-    ///     VK_Argument   = 1,
-    ///     VK_BasicBlock = 2,
-    ///     VK_Segment    = 8,
-    ///   };
-    /// \endcode
+    /// Only for ``AlignConsecutiveAssignments``.
+    /// Whether enum assignments are aligned. If ``Enabled`` is ``false``,
+    /// setting this to ``true`` forces alignment for enum assignments only.
+    /// If ``Enabled`` is ``true``, enum assignments are always aligned.
     bool EnumAssignments;
     /// Only for ``AlignConsecutiveAssignments``.  Whether short assignment
     /// operators are left-padded to the same length as long ones in order to
@@ -269,9 +264,9 @@ struct FormatStyle {
       return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
              AcrossComments == R.AcrossComments &&
              AlignCompound == R.AlignCompound &&
-             EnumAssignments == R.EnumAssignments &&
              AlignFunctionDeclarations == R.AlignFunctionDeclarations &&
              AlignFunctionPointers == R.AlignFunctionPointers &&
+             EnumAssignments == R.EnumAssignments &&
              PadOperators == R.PadOperators;
     }
     bool operator!=(const AlignConsecutiveStyle &R) const {
diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 7a555e05ec08b..61f0d800180b0 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -1214,8 +1214,9 @@ class AnnotatingParser {
 
     unsigned CommaCount = 0;
     while (CurrentToken) {
+      assert(!Scopes.empty());
+      Scopes.back() = getScopeType(OpeningBrace);
       if (CurrentToken->is(tok::r_brace)) {
-        assert(!Scopes.empty());
         assert(Scopes.back() == getScopeType(OpeningBrace));
         Scopes.pop_back();
         assert(OpeningBrace.Optional == CurrentToken->Optional);
@@ -1234,7 +1235,6 @@ class AnnotatingParser {
         return false;
       updateParameterCount(&OpeningBrace, CurrentToken);
       if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
-        assert(!Scopes.empty());
         FormatToken *Previous = CurrentToken->getPreviousNonComment();
         if (Previous->is(TT_JsTypeOptionalQuestion))
           Previous = Previous->getPreviousNonComment();
@@ -1242,7 +1242,6 @@ class AnnotatingParser {
              (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||
             Style.isProto()) {
           OpeningBrace.setType(TT_DictLiteral);
-          Scopes.back() = getScopeType(OpeningBrace);
           if (Previous->Tok.getIdentifierInfo() ||
               Previous->is(tok::string_literal)) {
             Previous->setType(TT_SelectorName);
@@ -1251,21 +1250,16 @@ class AnnotatingParser {
         if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown) &&
             !Style.isTableGen()) {
           OpeningBrace.setType(TT_DictLiteral);
-          Scopes.back() = getScopeType(OpeningBrace);
         } else if (Style.isJavaScript()) {
           OpeningBrace.overwriteFixedType(TT_DictLiteral);
-          Scopes.back() = getScopeType(OpeningBrace);
         }
       }
       bool IsBracedListComma = false;
       if (CurrentToken->is(tok::comma)) {
-        assert(!Scopes.empty());
-        if (Style.isJavaScript()) {
+        if (Style.isJavaScript())
           OpeningBrace.overwriteFixedType(TT_DictLiteral);
-          Scopes.back() = getScopeType(OpeningBrace);
-        } else {
+        else
           IsBracedListComma = OpeningBrace.is(BK_BracedInit);
-        }
         ++CommaCount;
       }
       if (!consumeToken())
@@ -1844,10 +1838,8 @@ class AnnotatingParser {
       // In TableGen, there must be a value after "=";
       if (Style.isTableGen() && !parseTableGenValue())
         return false;
-      if ((CurrentToken && CurrentToken->is(tok::numeric_constant)) &&
-          (!Scopes.empty() && Scopes.back() == ST_Enum)) {
+      if (!Scopes.empty() && Scopes.back() == ST_Enum)
         Tok->setFinalizedType(TT_EnumEqual);
-      }
       break;
     default:
       break;
@@ -5718,7 +5710,7 @@ bool TokenAnnotator::spaceRequiredBefore(const 
AnnotatedLine &Line,
     return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
   }
   if ((Right.is(TT_BinaryOperator) && Left.isNot(tok::l_paren)) ||
-      (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
+      (Left.isOneOf(TT_BinaryOperator, TT_EnumEqual, TT_ConditionalExpr) &&
        Right.isNot(tok::r_paren))) {
     return true;
   }
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index 9c1b870796454..53994741a48f6 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -386,7 +386,6 @@ TEST(ConfigParseTest, ParsesConfiguration) {
     CHECK_PARSE_NESTED_BOOL(FIELD, EnumAssignments);                           
\
     CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators);                              
\
   } while (false)
-  // @todo
 
   CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
   CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);

>From 5dd22530fb6b1e74a597209c9f1d400263d74976 Mon Sep 17 00:00:00 2001
From: Aaron Saw Min Sern <[email protected]>
Date: Sun, 10 May 2026 16:40:07 +0800
Subject: [PATCH 3/3] remove redundant assertion when parsing brace

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

diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 61f0d800180b0..b9d2f4bcc56ea 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -1217,7 +1217,6 @@ class AnnotatingParser {
       assert(!Scopes.empty());
       Scopes.back() = getScopeType(OpeningBrace);
       if (CurrentToken->is(tok::r_brace)) {
-        assert(Scopes.back() == getScopeType(OpeningBrace));
         Scopes.pop_back();
         assert(OpeningBrace.Optional == CurrentToken->Optional);
         OpeningBrace.MatchingParen = CurrentToken;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to