https://github.com/MythreyaK updated 
https://github.com/llvm/llvm-project/pull/172959

>From bcdb0fd408b055baaf1a1dc3cde1d87daf5cde44 Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Thu, 18 Dec 2025 23:21:50 -0800
Subject: [PATCH] [clang] Add FixItHint for designated init order

---
 clang/lib/Sema/SemaInit.cpp | 59 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index cc6ddf568d346..3eb648506e758 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -31,8 +31,10 @@
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaObjC.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -3092,6 +3094,60 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         PrevField = *FI;
       }
 
+      const auto GenerateDesignatedInitReorderingFixit = [&]() -> FixItHint {
+        struct ReorderInfo {
+          int Pos{};
+          const Expr *InitExpr{};
+        };
+
+        llvm::SmallDenseMap<IdentifierInfo *, int> MemberNameInx{};
+        llvm::SmallVector<ReorderInfo, 16> ReorderedInitExprs{};
+
+        const auto *CxxRecord =
+            IList->getSemanticForm()->getType()->getAsCXXRecordDecl();
+
+        for (const auto &Field : CxxRecord->fields()) {
+          MemberNameInx[Field->getIdentifier()] = Field->getFieldIndex();
+        }
+
+        for (const auto *Init : IList->inits()) {
+          if (const auto *DI = dyn_cast_if_present<DesignatedInitExpr>(Init)) {
+            // We expect only one Designator
+            if (DI->size() != 1)
+              return {};
+
+            const auto *const FieldName = DI->getDesignator(0)->getFieldName();
+            // In case we have an unknown initializer in the source, not in the
+            // record
+            if (MemberNameInx.contains(FieldName))
+              ReorderedInitExprs.emplace_back(
+                  ReorderInfo{MemberNameInx.at(FieldName), Init});
+          }
+        }
+
+        llvm::sort(ReorderedInitExprs,
+                   [](const auto &A, const auto &B) { return A.Pos < B.Pos; });
+
+        // generate replacement
+        llvm::SmallString<128> FixedInitList{};
+        SourceManager &SM = SemaRef.getSourceManager();
+        const LangOptions &LangOpts = SemaRef.getLangOpts();
+
+        FixedInitList += "{";
+        for (const auto &Item : ReorderedInitExprs) {
+          CharSourceRange CharRange =
+              CharSourceRange::getTokenRange(Item.InitExpr->getSourceRange());
+          const auto InitText =
+              Lexer::getSourceText(CharRange, SM, LangOpts) + ", ";
+          FixedInitList += InitText.str();
+        }
+        FixedInitList.pop_back_n(2); // remove trailing comma
+        FixedInitList += "}";
+
+        return FixItHint::CreateReplacement(IList->getSourceRange(),
+                                            FixedInitList);
+      };
+
       if (PrevField &&
           PrevField->getFieldIndex() > KnownField->getFieldIndex()) {
         SemaRef.Diag(DIE->getInit()->getBeginLoc(),
@@ -3101,9 +3157,10 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         unsigned OldIndex = StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
+            auto ReorderFixit = GenerateDesignatedInitReorderingFixit();
             SemaRef.Diag(PrevInit->getBeginLoc(),
                          diag::note_previous_field_init)
-                << PrevField << PrevInit->getSourceRange();
+                << PrevField << PrevInit->getSourceRange() << ReorderFixit;
           }
         }
       }

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

Reply via email to