diff options
Diffstat (limited to 'include/llvm/TableGen/Record.h')
-rw-r--r-- | include/llvm/TableGen/Record.h | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 36464d7..8c5452e 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -432,8 +432,8 @@ protected: /// readability for really no benefit. enum InitKind { IK_BitInit, - IK_BitsInit, IK_FirstTypedInit, + IK_BitsInit, IK_DagInit, IK_DefInit, IK_FieldInit, @@ -651,11 +651,12 @@ public: /// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. /// It contains a vector of bits, whose size is determined by the type. /// -class BitsInit : public Init, public FoldingSetNode { +class BitsInit : public TypedInit, public FoldingSetNode { std::vector<Init*> Bits; BitsInit(ArrayRef<Init *> Range) - : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {} + : TypedInit(IK_BitsInit, BitsRecTy::get(Range.size())), + Bits(Range.begin(), Range.end()) {} BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION; BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION; @@ -688,6 +689,14 @@ public: } std::string getAsString() const override; + /// resolveListElementReference - This method is used to implement + /// VarListElementInit::resolveReferences. If the list element is resolvable + /// now, we return the resolved value, otherwise we return null. + Init *resolveListElementReference(Record &R, const RecordVal *RV, + unsigned Elt) const override { + llvm_unreachable("Illegal element reference off bits<n>"); + } + Init *resolveReferences(Record &R, const RecordVal *RV) const override; Init *getBit(unsigned Bit) const override { @@ -928,7 +937,7 @@ public: /// class BinOpInit : public OpInit { public: - enum BinaryOp { ADD, SHL, SRA, SRL, LISTCONCAT, STRCONCAT, CONCAT, EQ }; + enum BinaryOp { ADD, AND, SHL, SRA, SRL, LISTCONCAT, STRCONCAT, CONCAT, EQ }; private: BinaryOp Opc; @@ -1392,6 +1401,18 @@ class Record { DefInit *TheInit; bool IsAnonymous; + // Class-instance values can be used by other defs. For example, Struct<i> + // is used here as a template argument to another class: + // + // multiclass MultiClass<int i> { + // def Def : Class<Struct<i>>; + // + // These need to get fully resolved before instantiating any other + // definitions that usie them (e.g. Def). However, inside a multiclass they + // can't be immediately resolved so we mark them ResolveFirst to fully + // resolve them later as soon as the multiclass is instantiated. + bool ResolveFirst; + void init(); void checkName(); @@ -1400,13 +1421,15 @@ public: explicit Record(const std::string &N, ArrayRef<SMLoc> locs, RecordKeeper &records, bool Anonymous = false) : ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), - TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous) { + TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous), + ResolveFirst(false) { init(); } 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) { + TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous), + ResolveFirst(false) { init(); } @@ -1416,7 +1439,8 @@ public: 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) { } + TheInit(O.TheInit), IsAnonymous(O.IsAnonymous), + ResolveFirst(O.ResolveFirst) { } ~Record() {} @@ -1544,6 +1568,14 @@ public: return IsAnonymous; } + bool isResolveFirst() const { + return ResolveFirst; + } + + void setResolveFirst(bool b) { + ResolveFirst = b; + } + void dump() const; //===--------------------------------------------------------------------===// @@ -1641,53 +1673,36 @@ struct MultiClass { }; class RecordKeeper { - std::map<std::string, Record*> Classes, Defs; + typedef std::map<std::string, std::unique_ptr<Record>> RecordMap; + RecordMap Classes, Defs; public: - ~RecordKeeper() { - for (std::map<std::string, Record*>::iterator I = Classes.begin(), - E = Classes.end(); I != E; ++I) - delete I->second; - for (std::map<std::string, Record*>::iterator I = Defs.begin(), - E = Defs.end(); I != E; ++I) - delete I->second; - } - - const std::map<std::string, Record*> &getClasses() const { return Classes; } - const std::map<std::string, Record*> &getDefs() const { return Defs; } + const RecordMap &getClasses() const { return Classes; } + const RecordMap &getDefs() const { return Defs; } Record *getClass(const std::string &Name) const { - std::map<std::string, Record*>::const_iterator I = Classes.find(Name); - return I == Classes.end() ? nullptr : I->second; + auto I = Classes.find(Name); + return I == Classes.end() ? nullptr : I->second.get(); } Record *getDef(const std::string &Name) const { - std::map<std::string, Record*>::const_iterator I = Defs.find(Name); - return I == Defs.end() ? nullptr : I->second; + auto I = Defs.find(Name); + return I == Defs.end() ? nullptr : I->second.get(); } - void addClass(Record *R) { - bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second; + void addClass(Record *_R) { + std::unique_ptr<Record> R(_R); + bool Ins = Classes.insert(std::make_pair(R->getName(), + std::move(R))).second; (void)Ins; assert(Ins && "Class already exists"); } - void addDef(Record *R) { - bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second; + void addDef(Record *_R) { + std::unique_ptr<Record> R(_R); + bool Ins = Defs.insert(std::make_pair(R->getName(), + std::move(R))).second; (void)Ins; assert(Ins && "Record already exists"); } - /// removeClass - Remove, but do not delete, the specified record. - /// - void removeClass(const std::string &Name) { - assert(Classes.count(Name) && "Class does not exist!"); - Classes.erase(Name); - } - /// removeDef - Remove, but do not delete, the specified record. - /// - void removeDef(const std::string &Name) { - assert(Defs.count(Name) && "Def does not exist!"); - Defs.erase(Name); - } - //===--------------------------------------------------------------------===// // High-level helper methods, useful for tablegen backends... |