/// We could pack these a bit tighter by not having the IK_FirstXXXInit
/// and IK_LastXXXInit be their own values, but that would degrade
/// readability for really no benefit.
- enum InitKind {
+ enum InitKind : uint8_t {
IK_BitInit,
IK_FirstTypedInit,
IK_BitsInit,
private:
const InitKind Kind;
+protected:
+ uint8_t Opc; // Used by UnOpInit, BinOpInit, and TernOpInit
+private:
Init(const Init &) = delete;
Init &operator=(const Init &) = delete;
virtual void anchor();
InitKind getKind() const { return Kind; }
protected:
- explicit Init(InitKind K) : Kind(K) {}
+ explicit Init(InitKind K, uint8_t Opc = 0) : Kind(K), Opc(Opc) {}
public:
virtual ~Init() {}
TypedInit &operator=(const TypedInit &Other) = delete;
protected:
- explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {}
- ~TypedInit() {
+ explicit TypedInit(InitKind K, RecTy *T, uint8_t Opc = 0)
+ : Init(K, Opc), Ty(T) {}
+ ~TypedInit() override {
// If this is a DefInit we need to delete the RecordRecTy.
if (getKind() == IK_DefInit)
delete Ty;
class StringInit : public TypedInit {
std::string Value;
- explicit StringInit(const std::string &V)
+ explicit StringInit(StringRef V)
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
StringInit(const StringInit &Other) = delete;
OpInit &operator=(OpInit &Other) = delete;
protected:
- explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {}
+ explicit OpInit(InitKind K, RecTy *Type, uint8_t Opc)
+ : TypedInit(K, Type, Opc) {}
public:
static bool classof(const Init *I) {
///
class UnOpInit : public OpInit {
public:
- enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
+ enum UnaryOp : uint8_t { CAST, HEAD, TAIL, EMPTY };
private:
- UnaryOp Opc;
Init *LHS;
UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
- : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {}
+ : OpInit(IK_UnOpInit, Type, opc), LHS(lhs) {}
UnOpInit(const UnOpInit &Other) = delete;
UnOpInit &operator=(const UnOpInit &Other) = delete;
return getOperand();
}
- UnaryOp getOpcode() const { return Opc; }
+ UnaryOp getOpcode() const { return (UnaryOp)Opc; }
Init *getOperand() const { return LHS; }
// Fold - If possible, fold this to a simpler init. Return this if not
///
class BinOpInit : public OpInit {
public:
- enum BinaryOp { ADD, AND, SHL, SRA, SRL, LISTCONCAT, STRCONCAT, CONCAT, EQ };
+ enum BinaryOp : uint8_t { ADD, AND, SHL, SRA, SRL, LISTCONCAT,
+ STRCONCAT, CONCAT, EQ };
private:
- BinaryOp Opc;
Init *LHS, *RHS;
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
- OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {}
+ OpInit(IK_BinOpInit, Type, opc), LHS(lhs), RHS(rhs) {}
BinOpInit(const BinOpInit &Other) = delete;
BinOpInit &operator=(const BinOpInit &Other) = delete;
}
}
- BinaryOp getOpcode() const { return Opc; }
+ BinaryOp getOpcode() const { return (BinaryOp)Opc; }
Init *getLHS() const { return LHS; }
Init *getRHS() const { return RHS; }
///
class TernOpInit : public OpInit {
public:
- enum TernaryOp { SUBST, FOREACH, IF };
+ enum TernaryOp : uint8_t { SUBST, FOREACH, IF };
private:
- TernaryOp Opc;
Init *LHS, *MHS, *RHS;
TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
RecTy *Type) :
- OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
+ OpInit(IK_TernOpInit, Type, opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
TernOpInit(const TernOpInit &Other) = delete;
TernOpInit &operator=(const TernOpInit &Other) = delete;
}
}
- TernaryOp getOpcode() const { return Opc; }
+ TernaryOp getOpcode() const { return (TernaryOp)Opc; }
Init *getLHS() const { return LHS; }
Init *getMHS() const { return MHS; }
Init *getRHS() const { return RHS; }
class VarInit : public TypedInit {
Init *VarName;
- explicit VarInit(const std::string &VN, RecTy *T)
- : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {}
explicit VarInit(Init *VN, RecTy *T)
: TypedInit(IK_VarInit, T), VarName(VN) {}
// Tracks Record instances. Not owned by Record.
RecordKeeper &TrackedRecords;
- DefInit *TheInit;
+ std::unique_ptr<DefInit> TheInit;
bool IsAnonymous;
// Class-instance values can be used by other defs. For example, Struct<i>
explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
bool Anonymous = false) :
ID(LastID++), Name(N), Locs(locs.begin(), locs.end()),
- TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous),
- ResolveFirst(false) {
+ TrackedRecords(records), IsAnonymous(Anonymous), ResolveFirst(false) {
init();
}
explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
// When copy-constructing a Record, we must still guarantee a globally unique
- // ID number. All other fields can be copied normally.
+ // ID number. Don't copy TheInit either since it's owned by the original
+ // record. All other fields can be copied normally.
Record(const Record &O) :
ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
Values(O.Values), SuperClasses(O.SuperClasses),
SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords),
- TheInit(O.TheInit), IsAnonymous(O.IsAnonymous),
+ IsAnonymous(O.IsAnonymous),
ResolveFirst(O.ResolveFirst) { }
static unsigned getNewUID() { return LastID++; }
/// get the corresponding DefInit.
DefInit *getDefInit();
- const std::vector<Init *> &getTemplateArgs() const {
+ ArrayRef<Init *> getTemplateArgs() const {
return TemplateArgs;
}
- const std::vector<RecordVal> &getValues() const { return Values; }
- const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
+ ArrayRef<RecordVal> getValues() const { return Values; }
+ ArrayRef<Record *> getSuperClasses() const { return SuperClasses; }
ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
bool isTemplateArg(Init *Name) const {
Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
const std::string &Name, const std::string &Scoper);
-} // End llvm namespace
+} // end llvm namespace
-#endif
+#endif // LLVM_TABLEGEN_RECORD_H