summaryrefslogtreecommitdiffstats
path: root/llvm/lib/TableGen/TGParser.cpp
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2018-03-06 13:48:47 +0000
committerNicolai Haehnle <nhaehnle@gmail.com>2018-03-06 13:48:47 +0000
commit0f529885fad55a42a81625cb8894e7646bc2761f (patch)
treee58cf00087981ccec537b7d28304f1cee4a79bc1 /llvm/lib/TableGen/TGParser.cpp
parentdfda9dcc1dfc4c50b7b3f538b9a629163dc44ee7 (diff)
downloadbcm5719-llvm-0f529885fad55a42a81625cb8894e7646bc2761f.tar.gz
bcm5719-llvm-0f529885fad55a42a81625cb8894e7646bc2761f.zip
TableGen: Explicitly check whether a record has been resolved
Summary: There are various places where resolving and constant folds can get stuck, especially around casts. We don't always signal an error for those, because in many cases they can legitimately occur without being an error in the "untaken branch" of an !if. Change-Id: I3befc0e4234c8e6cc61190504702918c9f29ce5c Reviewers: arsenm, craig.topper, tra, MartinO Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D43754 llvm-svn: 326786
Diffstat (limited to 'llvm/lib/TableGen/TGParser.cpp')
-rw-r--r--llvm/lib/TableGen/TGParser.cpp54
1 files changed, 51 insertions, 3 deletions
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 79f0799197b..efd993d8b2b 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -68,6 +68,47 @@ LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
} // end namespace llvm
+static bool checkBitsConcrete(Record &R, const RecordVal &RV) {
+ BitsInit *BV = cast<BitsInit>(RV.getValue());
+ for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
+ Init *Bit = BV->getBit(i);
+ bool IsReference = false;
+ if (auto VBI = dyn_cast<VarBitInit>(Bit)) {
+ if (auto VI = dyn_cast<VarInit>(VBI->getBitVar())) {
+ if (R.getValue(VI->getName()))
+ IsReference = true;
+ }
+ } else if (isa<VarInit>(Bit)) {
+ IsReference = true;
+ }
+ if (!(IsReference || Bit->isConcrete()))
+ return false;
+ }
+ return true;
+}
+
+static void checkConcrete(Record &R) {
+ for (const RecordVal &RV : R.getValues()) {
+ // HACK: Disable this check for variables declared with 'field'. This is
+ // done merely because existing targets have legitimate cases of
+ // non-concrete variables in helper defs. Ideally, we'd introduce a
+ // 'maybe' or 'optional' modifier instead of this.
+ if (RV.getPrefix())
+ continue;
+
+ if (Init *V = RV.getValue()) {
+ bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete();
+ if (!Ok) {
+ PrintError(R.getLoc(),
+ Twine("Initializer of '") + RV.getNameInitAsString() +
+ "' in '" + R.getNameInitAsString() +
+ "' could not be fully resolved: " +
+ RV.getValue()->getAsString());
+ }
+ }
+ }
+}
+
bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
if (!CurRec)
CurRec = &CurMultiClass->Rec;
@@ -371,6 +412,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
Record *IterRecSave = IterRec.get(); // Keep a copy before release.
Records.addDef(std::move(IterRec));
IterRecSave->resolveReferences();
+ checkConcrete(*IterRecSave);
return false;
}
@@ -2150,11 +2192,14 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
return true;
}
- if (!CurMultiClass) // Def's in multiclasses aren't really defs.
+ if (!CurMultiClass) { // Def's in multiclasses aren't really defs.
// See Record::setName(). This resolve step will see any new name
// for the def that might have been created when resolving
// inheritance, values and arguments above.
CurRec->resolveReferences();
+ if (Loops.empty())
+ checkConcrete(*CurRec);
+ }
// If ObjectBody has template arguments, it's an error.
assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
@@ -2747,12 +2792,15 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
}
}
- if (!CurMultiClass)
- for (Record *CurRec : NewRecDefs)
+ if (!CurMultiClass) {
+ for (Record *CurRec : NewRecDefs) {
// See Record::setName(). This resolve step will see any new
// name for the def that might have been created when resolving
// inheritance, values and arguments above.
CurRec->resolveReferences();
+ checkConcrete(*CurRec);
+ }
+ }
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' at end of defm");
OpenPOWER on IntegriCloud