@@ -96,9 +96,9 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) {
9696
9797void MultilibSet::push_back (const Multilib &M) { Multilibs.push_back (M); }
9898
99- static void WarnUnclaimedMultilibCustomFlags (
99+ static void DiagnoseUnclaimedMultilibCustomFlags (
100100 const Driver &D, const SmallVector<StringRef> &UnclaimedCustomFlagValues,
101- const SmallVector<custom_flag::CustomFlagDeclarationPtr > &CustomFlagDecls) {
101+ const SmallVector<custom_flag::DeclarationPtr > &CustomFlagDecls) {
102102 struct EditDistanceInfo {
103103 StringRef FlagValue;
104104 unsigned EditDistance;
@@ -120,30 +120,32 @@ static void WarnUnclaimedMultilibCustomFlags(
120120 }
121121 }
122122 if (!BestCandidate)
123- D.Diag (clang::diag::warn_drv_unsupported_opt )
123+ D.Diag (clang::diag::err_drv_unsupported_opt )
124124 << (custom_flag::Prefix + Unclaimed).str ();
125125 else
126- D.Diag (clang::diag::warn_drv_unsupported_opt_with_suggestion )
126+ D.Diag (clang::diag::err_drv_unsupported_opt_with_suggestion )
127127 << (custom_flag::Prefix + Unclaimed).str ()
128128 << (custom_flag::Prefix + BestCandidate->FlagValue ).str ();
129129 }
130130}
131131
132132namespace 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.
133135class ValueNameToDetailMap {
134- SmallVector<std::pair<StringRef, const CustomFlagValueDetail *>> Mapping;
136+ SmallVector<std::pair<StringRef, const ValueDetail *>> Mapping;
135137
136138public:
137139 template <typename It>
138140 ValueNameToDetailMap (It FlagDeclsBegin, It FlagDeclsEnd) {
139141 for (auto DeclIt = FlagDeclsBegin; DeclIt != FlagDeclsEnd; ++DeclIt) {
140- const CustomFlagDeclarationPtr &Decl = *DeclIt;
142+ const DeclarationPtr &Decl = *DeclIt;
141143 for (const auto &Value : Decl->ValueList )
142144 Mapping.emplace_back (Value.Name , &Value);
143145 }
144146 }
145147
146- const CustomFlagValueDetail *get (StringRef Key) const {
148+ const ValueDetail *get (StringRef Key) const {
147149 auto Iter = llvm::find_if (
148150 Mapping, [&](const auto &Pair) { return Pair.first == Key; });
149151 return Iter != Mapping.end () ? Iter->second : nullptr ;
@@ -155,8 +157,12 @@ Multilib::flags_list
155157MultilibSet::processCustomFlags (const Driver &D,
156158 const Multilib::flags_list &Flags) const {
157159 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.
160166 SmallVector<StringRef> UnclaimedCustomFlagValueStrs;
161167
162168 const auto ValueNameToValueDetail = custom_flag::ValueNameToDetailMap (
@@ -169,32 +175,38 @@ MultilibSet::processCustomFlags(const Driver &D,
169175 }
170176
171177 StringRef CustomFlagValueStr = Flag.substr (custom_flag::Prefix.size ());
172- const custom_flag::CustomFlagValueDetail *Detail =
178+ const custom_flag::ValueDetail *Detail =
173179 ValueNameToValueDetail.get (CustomFlagValueStr);
174180 if (Detail)
175181 ClaimedCustomFlagValues.push_back (Detail);
176182 else
177183 UnclaimedCustomFlagValueStrs.push_back (CustomFlagValueStr);
178184 }
179185
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;
182192
193+ // Detect multiple values for the same flag declaration. Last one wins.
183194 for (auto *CustomFlagValue : llvm::reverse (ClaimedCustomFlagValues)) {
184195 if (!TriggeredCustomFlagDecls.insert (CustomFlagValue->Decl ).second )
185196 continue ;
186197 Result.push_back (std::string (custom_flag::Prefix) + CustomFlagValue->Name );
187198 }
188199
200+ // Detect flag declarations with no value passed in. Select default value.
189201 for (const auto &Decl : CustomFlagDecls) {
190202 if (TriggeredCustomFlagDecls.contains (Decl))
191203 continue ;
192204 Result.push_back (std::string (custom_flag::Prefix) +
193- Decl->ValueList [Decl->DefaultValueIdx ].Name );
205+ Decl->ValueList [* Decl->DefaultValueIdx ].Name );
194206 }
195207
196- WarnUnclaimedMultilibCustomFlags (D, UnclaimedCustomFlagValueStrs,
197- CustomFlagDecls);
208+ DiagnoseUnclaimedMultilibCustomFlags (D, UnclaimedCustomFlagValueStrs,
209+ CustomFlagDecls);
198210
199211 return Result;
200212}
@@ -508,7 +520,7 @@ void MultilibSet::print(raw_ostream &OS) const {
508520 continue ;
509521
510522 StringRef CustomFlagValueStr = Flag.substr (custom_flag::Prefix.size ());
511- const custom_flag::CustomFlagValueDetail *Detail =
523+ const custom_flag::ValueDetail *Detail =
512524 ValueNameToValueDetail.get (CustomFlagValueStr);
513525
514526 if (!Detail || !Detail->ExtraBuildArgs )
0 commit comments