@@ -96,9 +96,9 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) {
96
96
97
97
void MultilibSet::push_back (const Multilib &M) { Multilibs.push_back (M); }
98
98
99
- static void WarnUnclaimedMultilibCustomFlags (
99
+ static void DiagnoseUnclaimedMultilibCustomFlags (
100
100
const Driver &D, const SmallVector<StringRef> &UnclaimedCustomFlagValues,
101
- const SmallVector<custom_flag::CustomFlagDeclarationPtr > &CustomFlagDecls) {
101
+ const SmallVector<custom_flag::DeclarationPtr > &CustomFlagDecls) {
102
102
struct EditDistanceInfo {
103
103
StringRef FlagValue;
104
104
unsigned EditDistance;
@@ -120,30 +120,32 @@ static void WarnUnclaimedMultilibCustomFlags(
120
120
}
121
121
}
122
122
if (!BestCandidate)
123
- D.Diag (clang::diag::warn_drv_unsupported_opt )
123
+ D.Diag (clang::diag::err_drv_unsupported_opt )
124
124
<< (custom_flag::Prefix + Unclaimed).str ();
125
125
else
126
- D.Diag (clang::diag::warn_drv_unsupported_opt_with_suggestion )
126
+ D.Diag (clang::diag::err_drv_unsupported_opt_with_suggestion )
127
127
<< (custom_flag::Prefix + Unclaimed).str ()
128
128
<< (custom_flag::Prefix + BestCandidate->FlagValue ).str ();
129
129
}
130
130
}
131
131
132
132
namespace clang ::driver::custom_flag {
133
+ // Map implemented using linear searches as the expected size is too small for
134
+ // the overhead of a search tree or a hash table.
133
135
class ValueNameToDetailMap {
134
- SmallVector<std::pair<StringRef, const CustomFlagValueDetail *>> Mapping;
136
+ SmallVector<std::pair<StringRef, const ValueDetail *>> Mapping;
135
137
136
138
public:
137
139
template <typename It>
138
140
ValueNameToDetailMap (It FlagDeclsBegin, It FlagDeclsEnd) {
139
141
for (auto DeclIt = FlagDeclsBegin; DeclIt != FlagDeclsEnd; ++DeclIt) {
140
- const CustomFlagDeclarationPtr &Decl = *DeclIt;
142
+ const DeclarationPtr &Decl = *DeclIt;
141
143
for (const auto &Value : Decl->ValueList )
142
144
Mapping.emplace_back (Value.Name , &Value);
143
145
}
144
146
}
145
147
146
- const CustomFlagValueDetail *get (StringRef Key) const {
148
+ const ValueDetail *get (StringRef Key) const {
147
149
auto Iter = llvm::find_if (
148
150
Mapping, [&](const auto &Pair) { return Pair.first == Key; });
149
151
return Iter != Mapping.end () ? Iter->second : nullptr ;
@@ -155,8 +157,12 @@ Multilib::flags_list
155
157
MultilibSet::processCustomFlags (const Driver &D,
156
158
const Multilib::flags_list &Flags) const {
157
159
Multilib::flags_list Result;
158
- SmallVector<const custom_flag::CustomFlagValueDetail *>
159
- ClaimedCustomFlagValues;
160
+
161
+ // Custom flag values detected in the flags list
162
+ SmallVector<const custom_flag::ValueDetail *> ClaimedCustomFlagValues;
163
+
164
+ // Arguments to -fmultilib-flag=<arg> that don't correspond to any valid
165
+ // custom flag value. An error will be printed out for each of these.
160
166
SmallVector<StringRef> UnclaimedCustomFlagValueStrs;
161
167
162
168
const auto ValueNameToValueDetail = custom_flag::ValueNameToDetailMap (
@@ -169,32 +175,38 @@ MultilibSet::processCustomFlags(const Driver &D,
169
175
}
170
176
171
177
StringRef CustomFlagValueStr = Flag.substr (custom_flag::Prefix.size ());
172
- const custom_flag::CustomFlagValueDetail *Detail =
178
+ const custom_flag::ValueDetail *Detail =
173
179
ValueNameToValueDetail.get (CustomFlagValueStr);
174
180
if (Detail)
175
181
ClaimedCustomFlagValues.push_back (Detail);
176
182
else
177
183
UnclaimedCustomFlagValueStrs.push_back (CustomFlagValueStr);
178
184
}
179
185
180
- llvm::SmallSet<custom_flag::CustomFlagDeclarationPtr, 32 >
181
- TriggeredCustomFlagDecls;
186
+ // Set of custom flag declarations for which a value was passed in the flags
187
+ // list. This is used to, firstly, detect multiple values for the same flag
188
+ // declaration (in this case, the last one wins), and secondly, to detect
189
+ // which declarations had no value passed in (in this case, the default value
190
+ // is selected).
191
+ llvm::SmallSet<custom_flag::DeclarationPtr, 32 > TriggeredCustomFlagDecls;
182
192
193
+ // Detect multiple values for the same flag declaration. Last one wins.
183
194
for (auto *CustomFlagValue : llvm::reverse (ClaimedCustomFlagValues)) {
184
195
if (!TriggeredCustomFlagDecls.insert (CustomFlagValue->Decl ).second )
185
196
continue ;
186
197
Result.push_back (std::string (custom_flag::Prefix) + CustomFlagValue->Name );
187
198
}
188
199
200
+ // Detect flag declarations with no value passed in. Select default value.
189
201
for (const auto &Decl : CustomFlagDecls) {
190
202
if (TriggeredCustomFlagDecls.contains (Decl))
191
203
continue ;
192
204
Result.push_back (std::string (custom_flag::Prefix) +
193
- Decl->ValueList [Decl->DefaultValueIdx ].Name );
205
+ Decl->ValueList [* Decl->DefaultValueIdx ].Name );
194
206
}
195
207
196
- WarnUnclaimedMultilibCustomFlags (D, UnclaimedCustomFlagValueStrs,
197
- CustomFlagDecls);
208
+ DiagnoseUnclaimedMultilibCustomFlags (D, UnclaimedCustomFlagValueStrs,
209
+ CustomFlagDecls);
198
210
199
211
return Result;
200
212
}
@@ -508,7 +520,7 @@ void MultilibSet::print(raw_ostream &OS) const {
508
520
continue ;
509
521
510
522
StringRef CustomFlagValueStr = Flag.substr (custom_flag::Prefix.size ());
511
- const custom_flag::CustomFlagValueDetail *Detail =
523
+ const custom_flag::ValueDetail *Detail =
512
524
ValueNameToValueDetail.get (CustomFlagValueStr);
513
525
514
526
if (!Detail || !Detail->ExtraBuildArgs )
0 commit comments