llvm.org GIT mirror llvm / 80bb2d9
[TableGen] Resolve complex def names inside multiclasses We had not been trying hard enough to resolve def names inside multiclasses that had complex concatenations, etc. Now we'll try harder. Patch by Amaury Sechet! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237877 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 4 years ago
3 changed file(s) with 86 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
23212321 InstantiateMulticlassDef(MultiClass &MC,
23222322 Record *DefProto,
23232323 Init *&DefmPrefix,
2324 SMRange DefmPrefixRange) {
2324 SMRange DefmPrefixRange,
2325 const std::vector &TArgs,
2326 std::vector &TemplateVals) {
23252327 // We need to preserve DefProto so it can be reused for later
23262328 // instantiations, so create a new Record to inherit from it.
23272329
23372339 }
23382340
23392341 Init *DefName = DefProto->getNameInit();
2340
23412342 StringInit *DefNameString = dyn_cast(DefName);
23422343
23432344 if (DefNameString) {
23852386 RecordVal *DefNameRV = CurRec->getValue("NAME");
23862387 CurRec->resolveReferencesTo(DefNameRV);
23872388
2389 // Check if the name is a complex pattern.
2390 // If so, resolve it.
2391 DefName = CurRec->getNameInit();
2392 DefNameString = dyn_cast(DefName);
2393
2394 // OK the pattern is more complex than simply using NAME.
2395 // Let's use the heavy weaponery.
2396 if (!DefNameString) {
2397 ResolveMulticlassDefArgs(MC, CurRec.get(), DefmPrefixRange.Start,
2398 Lex.getLoc(), TArgs, TemplateVals,
2399 false/*Delete args*/);
2400 DefName = CurRec->getNameInit();
2401 DefNameString = dyn_cast(DefName);
2402
2403 if (!DefNameString)
2404 DefName = DefName->convertInitializerTo(StringRecTy::get());
2405
2406 // We ran out of options here...
2407 DefNameString = dyn_cast(DefName);
2408 if (!DefNameString) {
2409 PrintFatalError(CurRec->getLoc()[CurRec->getLoc().size() - 1],
2410 DefName->getAsUnquotedString() + " is not a string.");
2411 return nullptr;
2412 }
2413
2414 CurRec->setName(DefName);
2415 }
2416
23882417 // Now that NAME references are resolved and we're at the top level of
23892418 // any multiclass expansions, add the record to the RecordKeeper. If we are
23902419 // currently in a multiclass, it means this defm appears inside a
23912420 // multiclass and its name won't be fully resolvable until we see
2392 // the top-level defm. Therefore, we don't add this to the
2393 // RecordKeeper at this point. If we did we could get duplicate
2421 // the top-level defm. Therefore, we don't add this to the
2422 // RecordKeeper at this point. If we did we could get duplicate
23942423 // defs as more than one probably refers to NAME or some other
23952424 // common internal placeholder.
23962425
25222551
25232552 // Loop over all the def's in the multiclass, instantiating each one.
25242553 for (const std::unique_ptr &DefProto : MC->DefPrototypes) {
2554 // The record name construction goes as follow:
2555 // - If the def name is a string, prepend the prefix.
2556 // - If the def name is a more complex pattern, use that pattern.
2557 // As a result, the record is instanciated before resolving
2558 // arguments, as it would make its name a string.
25252559 Record *CurRec = InstantiateMulticlassDef(*MC, DefProto.get(), DefmPrefix,
25262560 SMRange(DefmLoc,
2527 DefmPrefixEndLoc));
2561 DefmPrefixEndLoc),
2562 TArgs, TemplateVals);
25282563 if (!CurRec)
25292564 return true;
25302565
2566 // Now that the record is instanciated, we can resolve arguments.
25312567 if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc,
25322568 TArgs, TemplateVals, true/*Delete args*/))
25332569 return Error(SubClassLoc, "could not instantiate def");
137137 Record *InstantiateMulticlassDef(MultiClass &MC,
138138 Record *DefProto,
139139 Init *&DefmPrefix,
140 SMRange DefmPrefixRange);
140 SMRange DefmPrefixRange,
141 const std::vector &TArgs,
142 std::vector &TemplateVals);
141143 bool ResolveMulticlassDefArgs(MultiClass &MC,
142144 Record *DefProto,
143145 SMLoc DefmPrefixLoc,
3838
3939 defm : MC2<"bar">;
4040
41 multiclass MC3 {
42 def ZFizz#s : C;
43 }
44
45 defm : MC3<"Buzz">;
46
47 // CHECK: def ZFizzBuzz
48 // CHECK: string name = "Buzz";
49 // CHECK-NOT: MC3::s
50
51 multiclass MC4 {
52 def NAME#s : C;
53 }
54
55 defm ZTagazok : MC4<"AToi">;
56
57 // CHECK: def ZTagazokAToi
58 // CHECK: string name = "AToi";
59 // CHECK-NOT: MC4::s
60
61 multiclass MC5 {
62 def NAME#c.name : C;
63 }
64
65 def CTiger : C<"Tiger">;
66 defm Zebra : MC5;
67
68 // CHECK: def ZebraTiger
69 // CHECK: string name = "Tiger";
70 // CHECK-NOT: MC5::c
71
72 multiclass MC6 {
73 def NAME#Tiger#c.name : C;
74 }
75
76 def CAligator : C<"Aligator">;
77 defm Zebra : MC6;
78
79 // CHECK: def ZebraTigerAligator
80 // CHECK: string name = "Aligator";
81 // CHECK-NOT: MC6::c
82