@@ -34,6 +34,34 @@ static constexpr bool IgnoreMacrosDefault = true;
34
34
35
35
namespace {
36
36
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
+
37
65
unsigned getNumberOfDesignated (const InitListExpr *SyntacticInitList) {
38
66
return llvm::count_if (*SyntacticInitList, [](auto *InitExpr) {
39
67
return isa<DesignatedInitExpr>(InitExpr);
@@ -90,16 +118,10 @@ void UseDesignatedInitializersCheck::check(
90
118
const auto *SyntacticInitList = InitList->getSyntacticForm ();
91
119
if (!SyntacticInitList)
92
120
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};
100
122
const unsigned NumberOfDesignated = getNumberOfDesignated (SyntacticInitList);
101
123
if (SyntacticInitList->getNumInits () - NumberOfDesignated >
102
- LazyDesignators () .size ())
124
+ Designators .size ())
103
125
return ;
104
126
if (0 == NumberOfDesignated) {
105
127
if (IgnoreMacros && InitList->getBeginLoc ().isMacroID ())
@@ -111,11 +133,9 @@ void UseDesignatedInitializersCheck::check(
111
133
Diag << Type;
112
134
Diag << InitList->getSourceRange ();
113
135
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 ()])
117
137
Diag << FixItHint::CreateInsertion (InitExpr->getBeginLoc (),
118
- Designator + " =" );
138
+ (* Designator + " =" ). str () );
119
139
}
120
140
}
121
141
diag (Type->getBeginLoc (), " aggregate type is defined here" ,
@@ -127,16 +147,15 @@ void UseDesignatedInitializersCheck::check(
127
147
continue ;
128
148
if (IgnoreMacros && InitExpr->getBeginLoc ().isMacroID ())
129
149
continue ;
130
- const std::string &Designator =
131
- LazyDesignators ().at (InitExpr->getBeginLoc ());
132
150
DiagnosticBuilder Diag =
133
151
diag (InitExpr->getBeginLoc (),
134
152
" use designated init expression to initialize field '%0'" );
135
153
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
138
157
Diag << FixItHint::CreateInsertion (InitExpr->getBeginLoc (),
139
- Designator + " =" );
158
+ (* Designator + " =" ). str () );
140
159
}
141
160
}
142
161
}
0 commit comments