diff options
author | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-03-09 12:24:06 +0000 |
---|---|---|
committer | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-03-09 12:24:06 +0000 |
commit | b537605956400d62729cebc9d5d053c45aa5f4c5 (patch) | |
tree | 309691df62219727c021261ba83e0dd95a1082f3 /llvm/lib/TableGen/Record.cpp | |
parent | 47c3472c412b79ccd9df9b1461910127df0d1d97 (diff) | |
download | bcm5719-llvm-b537605956400d62729cebc9d5d053c45aa5f4c5.tar.gz bcm5719-llvm-b537605956400d62729cebc9d5d053c45aa5f4c5.zip |
TableGen: add !isa operation
Change-Id: Iddb724c3ae706d82933a2d82c91d07e0e36b30e3
Differential revision: https://reviews.llvm.org/D44105
llvm-svn: 327117
Diffstat (limited to 'llvm/lib/TableGen/Record.cpp')
-rw-r--r-- | llvm/lib/TableGen/Record.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index c1344aea4eb..76bbe7a0e5d 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -1231,6 +1231,68 @@ std::string FoldOpInit::getAsString() const { .str(); } +static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType, + Init *Expr) { + ID.AddPointer(CheckType); + ID.AddPointer(Expr); +} + +IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) { + static FoldingSet<IsAOpInit> ThePool; + + FoldingSetNodeID ID; + ProfileIsAOpInit(ID, CheckType, Expr); + + void *IP = nullptr; + if (IsAOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) + return I; + + IsAOpInit *I = new (Allocator) IsAOpInit(CheckType, Expr); + ThePool.InsertNode(I, IP); + return I; +} + +void IsAOpInit::Profile(FoldingSetNodeID &ID) const { + ProfileIsAOpInit(ID, CheckType, Expr); +} + +Init *IsAOpInit::Fold() const { + if (TypedInit *TI = dyn_cast<TypedInit>(Expr)) { + // Is the expression type known to be (a subclass of) the desired type? + if (TI->getType()->typeIsConvertibleTo(CheckType)) + return IntInit::get(1); + + if (isa<RecordRecTy>(CheckType)) { + // If the target type is not a subclass of the expression type, or if + // the expression has fully resolved to a record, we know that it can't + // be of the required type. + if (!CheckType->typeIsConvertibleTo(TI->getType()) || isa<DefInit>(Expr)) + return IntInit::get(0); + } else { + // We treat non-record types as not castable. + return IntInit::get(0); + } + } + return const_cast<IsAOpInit *>(this); +} + +Init *IsAOpInit::resolveReferences(Resolver &R) const { + Init *NewExpr = Expr->resolveReferences(R); + if (Expr != NewExpr) + return get(CheckType, NewExpr)->Fold(); + return const_cast<IsAOpInit *>(this); +} + +Init *IsAOpInit::getBit(unsigned Bit) const { + return VarBitInit::get(const_cast<IsAOpInit *>(this), Bit); +} + +std::string IsAOpInit::getAsString() const { + return (Twine("!isa<") + CheckType->getAsString() + ">(" + + Expr->getAsString() + ")") + .str(); +} + RecTy *TypedInit::getFieldType(StringInit *FieldName) const { if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) { for (Record *Rec : RecordType->getClasses()) { |