@@ -3094,59 +3094,60 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
30943094 PrevField = *FI;
30953095 }
30963096
3097- const auto GenerateDesignatedInitReorderingFixit = [&]() -> FixItHint {
3098- struct ReorderInfo {
3099- int Pos{};
3100- const Expr *InitExpr{};
3101- };
3097+ const auto GenerateDesignatedInitReorderingFixit =
3098+ [&](SemaBase::SemaDiagnosticBuilder &Diags) {
3099+ struct ReorderInfo {
3100+ int Pos{};
3101+ const Expr *InitExpr{};
3102+ };
31023103
3103- llvm::SmallDenseMap<IdentifierInfo *, int > MemberNameInx{};
3104- llvm::SmallVector<ReorderInfo, 16 > ReorderedInitExprs{};
3104+ llvm::SmallDenseMap<IdentifierInfo *, int > MemberNameInx{};
3105+ llvm::SmallVector<ReorderInfo, 16 > ReorderedInitExprs{};
31053106
3106- const auto *CxxRecord =
3107- IList->getSemanticForm ()->getType ()->getAsCXXRecordDecl ();
3107+ const auto *CxxRecord =
3108+ IList->getSemanticForm ()->getType ()->getAsCXXRecordDecl ();
31083109
3109- for (const auto &Field : CxxRecord->fields ()) {
3110- MemberNameInx[Field->getIdentifier ()] = Field->getFieldIndex ();
3111- }
3110+ for (const auto &Field : CxxRecord->fields ()) {
3111+ MemberNameInx[Field->getIdentifier ()] = Field->getFieldIndex ();
3112+ }
31123113
3113- for (const auto *Init : IList->inits ()) {
3114- if (const auto *DI = dyn_cast_if_present<DesignatedInitExpr>(Init)) {
3115- // We expect only one Designator
3116- if (DI->size () != 1 )
3117- return {};
3118-
3119- const auto *const FieldName = DI->getDesignator (0 )->getFieldName ();
3120- // In case we have an unknown initializer in the source, not in the
3121- // record
3122- if (MemberNameInx.contains (FieldName))
3123- ReorderedInitExprs.emplace_back (
3124- ReorderInfo{MemberNameInx.at (FieldName), Init});
3125- }
3126- }
3114+ for (const auto *Init : IList->inits ()) {
3115+ if (const auto *DI =
3116+ dyn_cast_if_present<DesignatedInitExpr>(Init)) {
3117+ // We expect only one Designator
3118+ if (DI->size () != 1 )
3119+ return ;
3120+
3121+ const auto *const FieldName =
3122+ DI->getDesignator (0 )->getFieldName ();
3123+ // In case we have an unknown initializer in the source, not in
3124+ // the record
3125+ if (MemberNameInx.contains (FieldName))
3126+ ReorderedInitExprs.emplace_back (
3127+ ReorderInfo{MemberNameInx.at (FieldName), Init});
3128+ }
3129+ }
31273130
3128- llvm::sort (ReorderedInitExprs,
3129- [](const auto &A, const auto &B) { return A.Pos < B.Pos ; });
3130-
3131- // generate replacement
3132- llvm::SmallString<128 > FixedInitList{};
3133- SourceManager &SM = SemaRef.getSourceManager ();
3134- const LangOptions &LangOpts = SemaRef.getLangOpts ();
3135-
3136- FixedInitList += " {" ;
3137- for (const auto &Item : ReorderedInitExprs) {
3138- CharSourceRange CharRange =
3139- CharSourceRange::getTokenRange (Item.InitExpr ->getSourceRange ());
3140- const auto InitText =
3141- Lexer::getSourceText (CharRange, SM, LangOpts) + " , " ;
3142- FixedInitList += InitText.str ();
3143- }
3144- FixedInitList.pop_back_n (2 ); // remove trailing comma
3145- FixedInitList += " }" ;
3131+ llvm::sort (ReorderedInitExprs, [](const auto &A, const auto &B) {
3132+ return A.Pos < B.Pos ;
3133+ });
3134+
3135+ llvm::SmallString<128 > FixedInitList{};
3136+ SourceManager &SM = SemaRef.getSourceManager ();
3137+ const LangOptions &LangOpts = SemaRef.getLangOpts ();
31463138
3147- return FixItHint::CreateReplacement (IList->getSourceRange (),
3148- FixedInitList);
3149- };
3139+ // loop over each existing expression and apply replacement
3140+ for (const auto &[OrigExpr, Repl] :
3141+ llvm::zip (IList->inits (), ReorderedInitExprs)) {
3142+ CharSourceRange CharRange = CharSourceRange::getTokenRange (
3143+ Repl.InitExpr ->getSourceRange ());
3144+ const auto InitText =
3145+ Lexer::getSourceText (CharRange, SM, LangOpts);
3146+
3147+ Diags << FixItHint::CreateReplacement (OrigExpr->getSourceRange (),
3148+ InitText.str ());
3149+ }
3150+ };
31503151
31513152 if (PrevField &&
31523153 PrevField->getFieldIndex () > KnownField->getFieldIndex ()) {
@@ -3157,10 +3158,10 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
31573158 unsigned OldIndex = StructuredIndex - 1 ;
31583159 if (StructuredList && OldIndex <= StructuredList->getNumInits ()) {
31593160 if (Expr *PrevInit = StructuredList->getInit (OldIndex)) {
3160- auto ReorderFixit = GenerateDesignatedInitReorderingFixit ();
3161- SemaRef. Diag (PrevInit-> getBeginLoc (),
3162- diag::note_previous_field_init)
3163- << PrevField << PrevInit-> getSourceRange () << ReorderFixit ;
3161+ auto Diags = SemaRef. Diag (PrevInit-> getBeginLoc (),
3162+ diag::note_previous_field_init)
3163+ << PrevField << PrevInit-> getSourceRange ();
3164+ GenerateDesignatedInitReorderingFixit (Diags) ;
31643165 }
31653166 }
31663167 }
0 commit comments