Skip to content

Commit 14c991c

Browse files
committed
Extract to class to handle missing elements gracefully
1 parent cfe41c5 commit 14c991c

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,34 @@ static constexpr bool IgnoreMacrosDefault = true;
3434

3535
namespace {
3636

37+
struct Designators {
38+
39+
Designators(const InitListExpr *InitList) : InitList(InitList) {
40+
assert(InitList->isSyntacticForm());
41+
};
42+
43+
unsigned size() { return get().size(); }
44+
45+
std::optional<llvm::StringRef> operator[](const SourceLocation &Location) {
46+
const auto Result = get().find(Location);
47+
if (Result == get().end())
48+
return {};
49+
return Result->getSecond();
50+
}
51+
52+
private:
53+
using LocationToNameMap = llvm::DenseMap<clang::SourceLocation, std::string>;
54+
55+
std::optional<LocationToNameMap> CachedDesignators;
56+
const InitListExpr *InitList;
57+
58+
LocationToNameMap &get() {
59+
return CachedDesignators ? *CachedDesignators
60+
: CachedDesignators.emplace(
61+
utils::getUnwrittenDesignators(InitList));
62+
}
63+
};
64+
3765
unsigned getNumberOfDesignated(const InitListExpr *SyntacticInitList) {
3866
return llvm::count_if(*SyntacticInitList, [](auto *InitExpr) {
3967
return isa<DesignatedInitExpr>(InitExpr);
@@ -90,16 +118,10 @@ void UseDesignatedInitializersCheck::check(
90118
const auto *SyntacticInitList = InitList->getSyntacticForm();
91119
if (!SyntacticInitList)
92120
return;
93-
std::optional<llvm::DenseMap<clang::SourceLocation, std::string>>
94-
Designators{};
95-
const auto LazyDesignators = [SyntacticInitList, &Designators]() -> auto & {
96-
return Designators ? *Designators
97-
: Designators.emplace(
98-
utils::getUnwrittenDesignators(SyntacticInitList));
99-
};
121+
Designators Designators{SyntacticInitList};
100122
const unsigned NumberOfDesignated = getNumberOfDesignated(SyntacticInitList);
101123
if (SyntacticInitList->getNumInits() - NumberOfDesignated >
102-
LazyDesignators().size())
124+
Designators.size())
103125
return;
104126
if (0 == NumberOfDesignated) {
105127
if (IgnoreMacros && InitList->getBeginLoc().isMacroID())
@@ -111,11 +133,9 @@ void UseDesignatedInitializersCheck::check(
111133
Diag << Type;
112134
Diag << InitList->getSourceRange();
113135
for (const Stmt *InitExpr : *SyntacticInitList) {
114-
const std::string &Designator =
115-
LazyDesignators().at(InitExpr->getBeginLoc());
116-
if (!Designator.empty())
136+
if (const auto Designator = Designators[InitExpr->getBeginLoc()])
117137
Diag << FixItHint::CreateInsertion(InitExpr->getBeginLoc(),
118-
Designator + "=");
138+
(*Designator + "=").str());
119139
}
120140
}
121141
diag(Type->getBeginLoc(), "aggregate type is defined here",
@@ -127,16 +147,15 @@ void UseDesignatedInitializersCheck::check(
127147
continue;
128148
if (IgnoreMacros && InitExpr->getBeginLoc().isMacroID())
129149
continue;
130-
const std::string &Designator =
131-
LazyDesignators().at(InitExpr->getBeginLoc());
132150
DiagnosticBuilder Diag =
133151
diag(InitExpr->getBeginLoc(),
134152
"use designated init expression to initialize field '%0'");
135153
Diag << InitExpr->getSourceRange();
136-
if (!Designator.empty() && Designator.front() == '.') {
137-
Diag << StringRef(Designator).substr(1); // Strip leading dot
154+
const auto Designator = Designators[InitExpr->getBeginLoc()];
155+
if (Designator && Designator->front() == '.') {
156+
Diag << Designator->substr(1); // Strip leading dot
138157
Diag << FixItHint::CreateInsertion(InitExpr->getBeginLoc(),
139-
Designator + "=");
158+
(*Designator + "=").str());
140159
}
141160
}
142161
}

0 commit comments

Comments
 (0)