|
11 | 11 | #include "clang/Basic/Version.h"
|
12 | 12 | #include "clang/Driver/Driver.h"
|
13 | 13 | #include "llvm/ADT/DenseSet.h"
|
14 |
| -#include "llvm/ADT/SmallString.h" |
| 14 | +#include "llvm/ADT/SmallSet.h" |
15 | 15 | #include "llvm/ADT/StringRef.h"
|
16 | 16 | #include "llvm/Support/Compiler.h"
|
17 | 17 | #include "llvm/Support/Error.h"
|
@@ -205,13 +205,20 @@ struct MultilibGroupSerialization {
|
205 | 205 |
|
206 | 206 | struct MultilibSetSerialization {
|
207 | 207 | llvm::VersionTuple MultilibVersion;
|
208 |
| - std::vector<MultilibGroupSerialization> Groups; |
209 |
| - std::vector<MultilibSerialization> Multilibs; |
210 |
| - std::vector<MultilibSet::FlagMatcher> FlagMatchers; |
| 208 | + SmallVector<MultilibGroupSerialization> Groups; |
| 209 | + SmallVector<MultilibSerialization> Multilibs; |
| 210 | + SmallVector<MultilibSet::FlagMatcher> FlagMatchers; |
| 211 | + SmallVector<custom_flag::CustomFlagDeclarationPtr> CustomFlagDeclarations; |
211 | 212 | };
|
212 | 213 |
|
213 | 214 | } // end anonymous namespace
|
214 | 215 |
|
| 216 | +LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibSerialization) |
| 217 | +LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibGroupSerialization) |
| 218 | +LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibSet::FlagMatcher) |
| 219 | +LLVM_YAML_IS_SEQUENCE_VECTOR(custom_flag::CustomFlagValueDetail) |
| 220 | +LLVM_YAML_IS_SEQUENCE_VECTOR(custom_flag::CustomFlagDeclarationPtr) |
| 221 | + |
215 | 222 | template <> struct llvm::yaml::MappingTraits<MultilibSerialization> {
|
216 | 223 | static void mapping(llvm::yaml::IO &io, MultilibSerialization &V) {
|
217 | 224 | io.mapOptional("Dir", V.Dir);
|
@@ -259,11 +266,69 @@ template <> struct llvm::yaml::MappingTraits<MultilibSet::FlagMatcher> {
|
259 | 266 | }
|
260 | 267 | };
|
261 | 268 |
|
| 269 | +template <> |
| 270 | +struct llvm::yaml::MappingContextTraits<custom_flag::CustomFlagValueDetail, |
| 271 | + llvm::SmallSet<std::string, 32>> { |
| 272 | + static void mapping(llvm::yaml::IO &io, custom_flag::CustomFlagValueDetail &V, |
| 273 | + llvm::SmallSet<std::string, 32> &) { |
| 274 | + io.mapRequired("Name", V.Name); |
| 275 | + io.mapOptional("ExtraBuildArgs", V.ExtraBuildArgs); |
| 276 | + } |
| 277 | + static std::string validate(IO &io, custom_flag::CustomFlagValueDetail &V, |
| 278 | + llvm::SmallSet<std::string, 32> &NameSet) { |
| 279 | + if (V.Name.empty()) |
| 280 | + return "custom flag value requires a name"; |
| 281 | + if (!NameSet.insert(V.Name).second) |
| 282 | + return "duplicate custom flag value name: \"" + V.Name + "\""; |
| 283 | + return {}; |
| 284 | + } |
| 285 | +}; |
| 286 | + |
| 287 | +template <> |
| 288 | +struct llvm::yaml::MappingContextTraits<custom_flag::CustomFlagDeclarationPtr, |
| 289 | + llvm::SmallSet<std::string, 32>> { |
| 290 | + static void mapping(llvm::yaml::IO &io, |
| 291 | + custom_flag::CustomFlagDeclarationPtr &V, |
| 292 | + llvm::SmallSet<std::string, 32> &NameSet) { |
| 293 | + assert(!V); |
| 294 | + V = std::make_shared<custom_flag::CustomFlagDeclaration>(); |
| 295 | + io.mapRequired("Name", V->Name); |
| 296 | + io.mapRequired("Values", V->ValueList, NameSet); |
| 297 | + std::string DefaultValueName; |
| 298 | + io.mapRequired("Default", DefaultValueName); |
| 299 | + |
| 300 | + for (auto [Idx, Value] : llvm::enumerate(V->ValueList)) { |
| 301 | + Value.Decl = V; |
| 302 | + if (Value.Name == DefaultValueName) { |
| 303 | + assert(V->DefaultValueIdx == ~0UL); |
| 304 | + V->DefaultValueIdx = Idx; |
| 305 | + } |
| 306 | + } |
| 307 | + } |
| 308 | + static std::string validate(IO &io, custom_flag::CustomFlagDeclarationPtr &V, |
| 309 | + llvm::SmallSet<std::string, 32> &) { |
| 310 | + if (V->Name.empty()) |
| 311 | + return "custom flag requires a name"; |
| 312 | + if (V->ValueList.empty()) |
| 313 | + return "custom flag must have at least one value"; |
| 314 | + if (V->DefaultValueIdx >= V->ValueList.size()) |
| 315 | + return "custom flag must have a default value"; |
| 316 | + if (llvm::any_of(V->ValueList, [&V](const auto &Value) { |
| 317 | + return !Value.Decl || Value.Decl != V; |
| 318 | + })) |
| 319 | + return "custom flag value missing reference to its custom flag " |
| 320 | + "declaration"; |
| 321 | + return {}; |
| 322 | + } |
| 323 | +}; |
| 324 | + |
262 | 325 | template <> struct llvm::yaml::MappingTraits<MultilibSetSerialization> {
|
263 | 326 | static void mapping(llvm::yaml::IO &io, MultilibSetSerialization &M) {
|
264 | 327 | io.mapRequired("MultilibVersion", M.MultilibVersion);
|
265 | 328 | io.mapRequired("Variants", M.Multilibs);
|
266 | 329 | io.mapOptional("Groups", M.Groups);
|
| 330 | + llvm::SmallSet<std::string, 32> NameSet; |
| 331 | + io.mapOptionalWithContext("Flags", M.CustomFlagDeclarations, NameSet); |
267 | 332 | io.mapOptional("Mappings", M.FlagMatchers);
|
268 | 333 | }
|
269 | 334 | static std::string validate(IO &io, MultilibSetSerialization &M) {
|
@@ -292,10 +357,6 @@ template <> struct llvm::yaml::MappingTraits<MultilibSetSerialization> {
|
292 | 357 | }
|
293 | 358 | };
|
294 | 359 |
|
295 |
| -LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibSerialization) |
296 |
| -LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibGroupSerialization) |
297 |
| -LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibSet::FlagMatcher) |
298 |
| - |
299 | 360 | llvm::ErrorOr<MultilibSet>
|
300 | 361 | MultilibSet::parseYaml(llvm::MemoryBufferRef Input,
|
301 | 362 | llvm::SourceMgr::DiagHandlerTy DiagHandler,
|
@@ -323,7 +384,8 @@ MultilibSet::parseYaml(llvm::MemoryBufferRef Input,
|
323 | 384 | }
|
324 | 385 | }
|
325 | 386 |
|
326 |
| - return MultilibSet(std::move(Multilibs), std::move(MS.FlagMatchers)); |
| 387 | + return MultilibSet(std::move(Multilibs), std::move(MS.FlagMatchers), |
| 388 | + std::move(MS.CustomFlagDeclarations)); |
327 | 389 | }
|
328 | 390 |
|
329 | 391 | LLVM_DUMP_METHOD void MultilibSet::dump() const {
|
|
0 commit comments