|
7 | 7 | #include <llvm/Support/MemoryBuffer.h> |
8 | 8 |
|
9 | 9 | #include <algorithm> |
| 10 | +#include <format> |
10 | 11 | #include <string> |
11 | 12 | #include <vector> |
12 | 13 |
|
@@ -303,6 +304,26 @@ void ExprRule::dump() const { |
303 | 304 | } |
304 | 305 | } |
305 | 306 |
|
| 307 | +void ExprRule::validate(const std::string &name) const { |
| 308 | + if (src.empty()) { |
| 309 | + llvm::errs() << name << '\n'; |
| 310 | + dump(); |
| 311 | + assert(0 && "Expr rule loaded from IR but has no src"); |
| 312 | + } |
| 313 | + |
| 314 | + // Check that both source and target use the same generics. |
| 315 | + for (unsigned i = 0; i < generics.size(); ++i) { |
| 316 | + auto placeholder = std::format("T{}", i + 1); |
| 317 | + if (src.find(placeholder) == std::string::npos) { |
| 318 | + llvm::errs() << name << '\n'; |
| 319 | + dump(); |
| 320 | + llvm::errs() << "generic " << placeholder |
| 321 | + << " declared but missing from src: " << src << '\n'; |
| 322 | + assert(0 && "Expr rule declares a generic absent from its src"); |
| 323 | + } |
| 324 | + } |
| 325 | +} |
| 326 | + |
306 | 327 | void GenericFragment::dump() const { log() << " generic: " << n << '\n'; } |
307 | 328 |
|
308 | 329 | void TypeInfo::dump() const { |
@@ -339,11 +360,7 @@ std::pair<ExprRules, TypeRules> Load(const std::filesystem::path &path, |
339 | 360 | LoadIrSrc(exprs, types, dir / "ir_src.json"); |
340 | 361 |
|
341 | 362 | for (auto &[name, rule] : exprs) { |
342 | | - if (rule.src.empty()) { |
343 | | - llvm::errs() << name << '\n'; |
344 | | - rule.dump(); |
345 | | - assert(0 && "Expr rule loaded from IR but has no src"); |
346 | | - } |
| 363 | + rule.validate(name); |
347 | 364 | } |
348 | 365 | for (auto &[name, rule] : types) { |
349 | 366 | if (rule.src.empty()) { |
|
0 commit comments