Skip to content

Commit 322f1de

Browse files
committed
Replace exprs instead of regenerating everything
1 parent bcdb0fd commit 322f1de

File tree

1 file changed

+52
-51
lines changed

1 file changed

+52
-51
lines changed

clang/lib/Sema/SemaInit.cpp

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)