3131#include " clang/Sema/SemaHLSL.h"
3232#include " clang/Sema/SemaObjC.h"
3333#include " llvm/ADT/APInt.h"
34+ #include " llvm/ADT/DenseMap.h"
3435#include " llvm/ADT/FoldingSet.h"
3536#include " llvm/ADT/PointerIntPair.h"
37+ #include " llvm/ADT/SmallString.h"
3638#include " llvm/ADT/SmallVector.h"
3739#include " llvm/ADT/StringExtras.h"
3840#include " llvm/Support/ErrorHandling.h"
3941#include " llvm/Support/raw_ostream.h"
4042
43+ #include < iostream>
44+ #define DUMP_ARG1 (X ) \
45+ { \
46+ if (X) { \
47+ fprintf (stderr, " ----- %s ----- (%s:%d)\n " , #X, __FILE__, __LINE__); \
48+ (X)->dumpColor (); \
49+ fprintf (stderr, " --------------------------------\n\n " ); \
50+ fflush (stdout); \
51+ std::flush (std::cout); \
52+ } else \
53+ fprintf (stderr, " Arg '" #X " ' was empty\n " ); \
54+ } \
55+ do { \
56+ } while (0 )
57+
58+ #define DUMP_ARG2 (PREFIX, X ) \
59+ { \
60+ if (X) { \
61+ fprintf (stderr, " %s: %s ----- (%s:%d)\n " , PREFIX, #X, __FILE__, \
62+ __LINE__); \
63+ (X)->dumpColor (); \
64+ fprintf (stderr, " --------------------------------\n\n " ); \
65+ fflush (stdout); \
66+ std::flush (std::cout); \
67+ } else \
68+ fprintf (stderr, " Arg '" #X " ' was empty\n " ); \
69+ } \
70+ do { \
71+ } while (0 )
72+
4173using namespace clang ;
4274
4375// ===----------------------------------------------------------------------===//
@@ -3092,6 +3124,60 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
30923124 PrevField = *FI;
30933125 }
30943126
3127+ const auto GenerateDesignatedInitReorderingFixit = [&]() -> FixItHint {
3128+ struct ReorderInfo {
3129+ int Pos{};
3130+ const Expr *InitExpr{};
3131+ };
3132+
3133+ llvm::SmallDenseMap<IdentifierInfo *, int > MemberNameInx{};
3134+ llvm::SmallVector<ReorderInfo, 16 > ReorderedInitExprs{};
3135+
3136+ const auto *CxxRecord =
3137+ IList->getSemanticForm ()->getType ()->getAsCXXRecordDecl ();
3138+
3139+ for (const auto &Field : CxxRecord->fields ()) {
3140+ MemberNameInx[Field->getIdentifier ()] = Field->getFieldIndex ();
3141+ }
3142+
3143+ for (const auto *Init : IList->inits ()) {
3144+ if (const auto *DI = dyn_cast_if_present<DesignatedInitExpr>(Init)) {
3145+ // We expect only one Designator
3146+ if (DI->size () != 1 )
3147+ return {};
3148+
3149+ const auto *const FieldName = DI->getDesignator (0 )->getFieldName ();
3150+ // In case we have an unknown initializer in the source, not in the
3151+ // record
3152+ if (MemberNameInx.contains (FieldName))
3153+ ReorderedInitExprs.emplace_back (
3154+ ReorderInfo{MemberNameInx.at (FieldName), Init});
3155+ }
3156+ }
3157+
3158+ llvm::sort (ReorderedInitExprs,
3159+ [](const auto &A, const auto &B) { return A.Pos < B.Pos ; });
3160+
3161+ // generate replacement
3162+ llvm::SmallString<128 > FixedInitList{};
3163+ SourceManager &SM = SemaRef.getSourceManager ();
3164+ const LangOptions &LangOpts = SemaRef.getLangOpts ();
3165+
3166+ FixedInitList += " {" ;
3167+ for (const auto &Item : ReorderedInitExprs) {
3168+ CharSourceRange CharRange =
3169+ CharSourceRange::getTokenRange (Item.InitExpr ->getSourceRange ());
3170+ const auto InitText =
3171+ Lexer::getSourceText (CharRange, SM, LangOpts) + " , " ;
3172+ FixedInitList += InitText.str ();
3173+ }
3174+ FixedInitList.pop_back_n (2 ); // remove trailing comma
3175+ FixedInitList += " }" ;
3176+
3177+ return FixItHint::CreateReplacement (IList->getSourceRange (),
3178+ FixedInitList);
3179+ };
3180+
30953181 if (PrevField &&
30963182 PrevField->getFieldIndex () > KnownField->getFieldIndex ()) {
30973183 SemaRef.Diag (DIE->getInit ()->getBeginLoc (),
@@ -3101,9 +3187,10 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
31013187 unsigned OldIndex = StructuredIndex - 1 ;
31023188 if (StructuredList && OldIndex <= StructuredList->getNumInits ()) {
31033189 if (Expr *PrevInit = StructuredList->getInit (OldIndex)) {
3190+ auto ReorderFixit = GenerateDesignatedInitReorderingFixit ();
31043191 SemaRef.Diag (PrevInit->getBeginLoc (),
31053192 diag::note_previous_field_init)
3106- << PrevField << PrevInit->getSourceRange ();
3193+ << PrevField << PrevInit->getSourceRange () << ReorderFixit ;
31073194 }
31083195 }
31093196 }
0 commit comments