aboutsummaryrefslogtreecommitdiffstats
path: root/lib/TableGen
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-08-02 18:46:42 +0000
committerJim Grosbach <grosbach@apple.com>2012-08-02 18:46:42 +0000
commitcfbda4a04dacaf976505c54a5308f6954b3b9a58 (patch)
treedafefb43d1afbe12801b6814320d75192560117c /lib/TableGen
parent79a20ce6f0d6c1041a5031aca41b50a1e58b1d4b (diff)
downloadexternal_llvm-cfbda4a04dacaf976505c54a5308f6954b3b9a58.zip
external_llvm-cfbda4a04dacaf976505c54a5308f6954b3b9a58.tar.gz
external_llvm-cfbda4a04dacaf976505c54a5308f6954b3b9a58.tar.bz2
TableGen: Allow use of #NAME# outside of 'def' names.
Previously, def NAME values were only populated, and references to NAME resolved, when NAME was referenced in the 'def' entry of the multiclass sub-entry. e.g., multiclass foo<...> { def prefix_#NAME : ... } It's useful, however, to be able to reference NAME even when the default def name is used. For example, when a multiclass has 'def : Pat<...>' or 'def : InstAlias<...>' entries which refer to earlier instruction definitions in the same multiclass. e.g., multiclass myMulti<RegisterClass rc> { def _r : myI<(outs rc:$d), (ins rc:$r), "r $d, $r", []>; def : InstAlias<\"wilma $r\", (!cast<Instruction>(NAME#\"_r\") rc:$r, rc:$r)>; } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161198 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/TableGen')
-rw-r--r--lib/TableGen/TGParser.cpp32
1 files changed, 21 insertions, 11 deletions
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index 9424677..b9c7ff6 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -2284,23 +2284,33 @@ InstantiateMulticlassDef(MultiClass &MC,
Ref.Rec = DefProto;
AddSubClass(CurRec, Ref);
- if (DefNameString == 0) {
- // We must resolve references to NAME.
- if (SetValue(CurRec, Ref.RefLoc, "NAME", std::vector<unsigned>(),
- DefmPrefix)) {
- Error(DefmPrefixLoc, "Could not resolve "
- + CurRec->getNameInitAsString() + ":NAME to '"
- + DefmPrefix->getAsUnquotedString() + "'");
- return 0;
- }
+ // Set the value for NAME. We don't resolve references to it 'til later,
+ // though, so that uses in nested multiclass names don't get
+ // confused.
+ if (SetValue(CurRec, Ref.RefLoc, "NAME", std::vector<unsigned>(),
+ DefmPrefix)) {
+ Error(DefmPrefixLoc, "Could not resolve "
+ + CurRec->getNameInitAsString() + ":NAME to '"
+ + DefmPrefix->getAsUnquotedString() + "'");
+ return 0;
+ }
+ // If the DefNameString didn't resolve, we probably have a reference to
+ // NAME and need to replace it. We need to do at least this much greedily,
+ // otherwise nested multiclasses will end up with incorrect NAME expansions.
+ if (DefNameString == 0) {
RecordVal *DefNameRV = CurRec->getValue("NAME");
CurRec->resolveReferencesTo(DefNameRV);
}
if (!CurMultiClass) {
- // We do this after resolving NAME because before resolution, many
- // multiclass defs will have the same name expression. If we are
+ // Now that we're at the top level, resolve all NAME references
+ // in the resultant defs that weren't in the def names themselves.
+ RecordVal *DefNameRV = CurRec->getValue("NAME");
+ CurRec->resolveReferencesTo(DefNameRV);
+
+ // Now that NAME references are resolved and we're at the top level of
+ // any multiclass expansions, add the record to the RecordKeeper. If we are
// currently in a multiclass, it means this defm appears inside a
// multiclass and its name won't be fully resolvable until we see
// the top-level defm. Therefore, we don't add this to the