diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
tree | 4def12e759965de927d963ac65840d663ef9d1ea /include/llvm/TableGen | |
parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) |
Vendor import of llvm release_39 branch r276489:vendor/llvm/llvm-release_39-r276489
Diffstat (limited to 'include/llvm/TableGen')
-rw-r--r-- | include/llvm/TableGen/Record.h | 319 | ||||
-rw-r--r-- | include/llvm/TableGen/SearchableTable.td | 41 | ||||
-rw-r--r-- | include/llvm/TableGen/StringToOffsetTable.h | 20 |
3 files changed, 260 insertions, 120 deletions
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 4c1ef4013dda..393cafa7924a 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -22,6 +22,7 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SMLoc.h" +#include "llvm/Support/TrailingObjects.h" #include "llvm/Support/raw_ostream.h" #include <map> @@ -43,6 +44,7 @@ public: enum RecTyKind { BitRecTyKind, BitsRecTyKind, + CodeRecTyKind, IntRecTyKind, StringRecTyKind, ListRecTyKind, @@ -64,11 +66,11 @@ public: void print(raw_ostream &OS) const { OS << getAsString(); } void dump() const; - /// typeIsConvertibleTo - Return true if all values of 'this' type can be - /// converted to the specified type. + /// Return true if all values of 'this' type can be converted to the specified + /// type. virtual bool typeIsConvertibleTo(const RecTy *RHS) const; - /// getListTy - Returns the type representing list<this>. + /// Returns the type representing list<this>. ListRecTy *getListTy(); }; @@ -77,7 +79,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { return OS; } -/// BitRecTy - 'bit' - Represent a single bit +/// 'bit' - Represent a single bit /// class BitRecTy : public RecTy { static BitRecTy Shared; @@ -95,7 +97,7 @@ public: bool typeIsConvertibleTo(const RecTy *RHS) const override; }; -/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits +/// 'bits<n>' - Represent a fixed number of bits /// class BitsRecTy : public RecTy { unsigned Size; @@ -115,7 +117,23 @@ public: bool typeIsConvertibleTo(const RecTy *RHS) const override; }; -/// IntRecTy - 'int' - Represent an integer value of no particular size +/// 'code' - Represent a code fragment +/// +class CodeRecTy : public RecTy { + static CodeRecTy Shared; + CodeRecTy() : RecTy(CodeRecTyKind) {} + +public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == CodeRecTyKind; + } + + static CodeRecTy *get() { return &Shared; } + + std::string getAsString() const override { return "code"; } +}; + +/// 'int' - Represent an integer value of no particular size /// class IntRecTy : public RecTy { static IntRecTy Shared; @@ -133,7 +151,7 @@ public: bool typeIsConvertibleTo(const RecTy *RHS) const override; }; -/// StringRecTy - 'string' - Represent an string value +/// 'string' - Represent an string value /// class StringRecTy : public RecTy { static StringRecTy Shared; @@ -141,7 +159,8 @@ class StringRecTy : public RecTy { public: static bool classof(const RecTy *RT) { - return RT->getRecTyKind() == StringRecTyKind; + return RT->getRecTyKind() == StringRecTyKind || + RT->getRecTyKind() == CodeRecTyKind; } static StringRecTy *get() { return &Shared; } @@ -149,7 +168,7 @@ public: std::string getAsString() const override; }; -/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of +/// 'list<Ty>' - Represent a list of values, all of which must be of /// the specified type. /// class ListRecTy : public RecTy { @@ -170,7 +189,7 @@ public: bool typeIsConvertibleTo(const RecTy *RHS) const override; }; -/// DagRecTy - 'dag' - Represent a dag fragment +/// 'dag' - Represent a dag fragment /// class DagRecTy : public RecTy { static DagRecTy Shared; @@ -186,7 +205,7 @@ public: std::string getAsString() const override; }; -/// RecordRecTy - '[classname]' - Represent an instance of a class, such as: +/// '[classname]' - Represent an instance of a class, such as: /// (R32 X = EAX). /// class RecordRecTy : public RecTy { @@ -208,7 +227,7 @@ public: bool typeIsConvertibleTo(const RecTy *RHS) const override; }; -/// resolveTypes - Find a common type that T1 and T2 convert to. +/// Find a common type that T1 and T2 convert to. /// Return 0 if no such type exists. /// RecTy *resolveTypes(RecTy *T1, RecTy *T2); @@ -236,6 +255,7 @@ protected: IK_BitInit, IK_FirstTypedInit, IK_BitsInit, + IK_CodeInit, IK_DagInit, IK_DefInit, IK_FieldInit, @@ -272,30 +292,30 @@ protected: public: virtual ~Init() {} - /// isComplete - This virtual method should be overridden by values that may + /// This virtual method should be overridden by values that may /// not be completely specified yet. virtual bool isComplete() const { return true; } - /// print - Print out this value. + /// Print out this value. void print(raw_ostream &OS) const { OS << getAsString(); } - /// getAsString - Convert this value to a string form. + /// Convert this value to a string form. virtual std::string getAsString() const = 0; - /// getAsUnquotedString - Convert this value to a string form, + /// Convert this value to a string form, /// without adding quote markers. This primaruly affects /// StringInits where we will not surround the string value with /// quotes. virtual std::string getAsUnquotedString() const { return getAsString(); } - /// dump - Debugging method that may be called through a debugger, just + /// Debugging method that may be called through a debugger, just /// invokes print on stderr. void dump() const; - /// convertInitializerTo - This virtual function converts to the appropriate + /// This virtual function converts to the appropriate /// Init based on the passed in type. virtual Init *convertInitializerTo(RecTy *Ty) const = 0; - /// convertInitializerBitRange - This method is used to implement the bitrange + /// This method is used to implement the bitrange /// selection operator. Given an initializer, it selects the specified bits /// out, returning them as a new init of bits type. If it is not legal to use /// the bit subscript operator on this initializer, return null. @@ -305,7 +325,7 @@ public: return nullptr; } - /// convertInitListSlice - This method is used to implement the list slice + /// This method is used to implement the list slice /// selection operator. Given an initializer, it selects the specified list /// elements, returning them as a new init of list type. If it is not legal /// to take a slice of this, return null. @@ -315,7 +335,7 @@ public: return nullptr; } - /// getFieldType - This method is used to implement the FieldInit class. + /// This method is used to implement the FieldInit class. /// Implementors of this method should return the type of the named field if /// they are of record type. /// @@ -323,7 +343,7 @@ public: return nullptr; } - /// getFieldInit - This method complements getFieldType to return the + /// This method complements getFieldType to return the /// initializer for the specified field. If getFieldType returns non-null /// this method should return non-null, otherwise it returns null. /// @@ -332,7 +352,7 @@ public: return nullptr; } - /// resolveReferences - This method is used by classes that refer to other + /// This method is used by classes that refer to other /// variables which may not be defined at the time the expression is formed. /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. @@ -341,15 +361,15 @@ public: return const_cast<Init *>(this); } - /// getBit - This method is used to return the initializer for the specified + /// This method is used to return the initializer for the specified /// bit. virtual Init *getBit(unsigned Bit) const = 0; - /// getBitVar - This method is used to retrieve the initializer for bit + /// This method is used to retrieve the initializer for bit /// reference. For non-VarBitInit, it simply returns itself. virtual Init *getBitVar() const { return const_cast<Init*>(this); } - /// getBitNum - This method is used to retrieve the bit number of a bit + /// This method is used to retrieve the bit number of a bit /// reference. For non-VarBitInit, it simply returns 0. virtual unsigned getBitNum() const { return 0; } }; @@ -358,7 +378,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { I.print(OS); return OS; } -/// TypedInit - This is the common super-class of types that have a specific, +/// This is the common super-class of types that have a specific, /// explicit, type. /// class TypedInit : public Init { @@ -390,20 +410,20 @@ public: Init * convertInitListSlice(const std::vector<unsigned> &Elements) const override; - /// getFieldType - This method is used to implement the FieldInit class. + /// This method is used to implement the FieldInit class. /// Implementors of this method should return the type of the named field if /// they are of record type. /// RecTy *getFieldType(const std::string &FieldName) const override; - /// resolveListElementReference - This method is used to implement + /// This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const = 0; }; -/// UnsetInit - ? - Represents an uninitialized value +/// '?' - Represents an uninitialized value /// class UnsetInit : public Init { UnsetInit() : Init(IK_UnsetInit) {} @@ -426,7 +446,7 @@ public: std::string getAsString() const override { return "?"; } }; -/// BitInit - true/false - Represent a concrete initializer for a bit. +/// 'true'/'false' - Represent a concrete initializer for a bit. /// class BitInit : public Init { bool Value; @@ -453,20 +473,23 @@ public: std::string getAsString() const override { return Value ? "1" : "0"; } }; -/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. +/// '{ 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 TypedInit, public FoldingSetNode { - std::vector<Init*> Bits; +class BitsInit final : public TypedInit, public FoldingSetNode, + public TrailingObjects<BitsInit, Init *> { + unsigned NumBits; - BitsInit(ArrayRef<Init *> Range) - : TypedInit(IK_BitsInit, BitsRecTy::get(Range.size())), - Bits(Range.begin(), Range.end()) {} + BitsInit(unsigned N) + : TypedInit(IK_BitsInit, BitsRecTy::get(N)), NumBits(N) {} BitsInit(const BitsInit &Other) = delete; BitsInit &operator=(const BitsInit &Other) = delete; public: + // Do not use sized deallocation due to trailing objects. + void operator delete(void *p) { ::operator delete(p); } + static bool classof(const Init *I) { return I->getKind() == IK_BitsInit; } @@ -474,7 +497,7 @@ public: void Profile(FoldingSetNodeID &ID) const; - unsigned getNumBits() const { return Bits.size(); } + unsigned getNumBits() const { return NumBits; } Init *convertInitializerTo(RecTy *Ty) const override; Init * @@ -492,7 +515,7 @@ public: } std::string getAsString() const override; - /// resolveListElementReference - This method is used to implement + /// 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, @@ -503,12 +526,12 @@ public: Init *resolveReferences(Record &R, const RecordVal *RV) const override; Init *getBit(unsigned Bit) const override { - assert(Bit < Bits.size() && "Bit index out of range!"); - return Bits[Bit]; + assert(Bit < NumBits && "Bit index out of range!"); + return getTrailingObjects<Init *>()[Bit]; } }; -/// IntInit - 7 - Represent an initialization by a literal integer value. +/// '7' - Represent an initialization by a literal integer value. /// class IntInit : public TypedInit { int64_t Value; @@ -533,7 +556,7 @@ public: std::string getAsString() const override; - /// resolveListElementReference - This method is used to implement + /// 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, @@ -546,13 +569,13 @@ public: } }; -/// StringInit - "foo" - Represent an initialization by a string value. +/// "foo" - Represent an initialization by a string value. /// class StringInit : public TypedInit { std::string Value; explicit StringInit(StringRef V) - : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {} + : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {} StringInit(const StringInit &Other) = delete; StringInit &operator=(const StringInit &Other) = delete; @@ -568,6 +591,7 @@ public: Init *convertInitializerTo(RecTy *Ty) const override; std::string getAsString() const override { return "\"" + Value + "\""; } + std::string getAsUnquotedString() const override { return Value; } /// resolveListElementReference - This method is used to implement @@ -583,23 +607,65 @@ public: } }; -/// ListInit - [AL, AH, CL] - Represent a list of defs +class CodeInit : public TypedInit { + std::string Value; + + explicit CodeInit(StringRef V) + : TypedInit(IK_CodeInit, static_cast<RecTy *>(CodeRecTy::get())), + Value(V) {} + + CodeInit(const StringInit &Other) = delete; + CodeInit &operator=(const StringInit &Other) = delete; + +public: + static bool classof(const Init *I) { + return I->getKind() == IK_CodeInit; + } + static CodeInit *get(StringRef); + + const std::string &getValue() const { return Value; } + + Init *convertInitializerTo(RecTy *Ty) const override; + + std::string getAsString() const override { + return "[{" + Value + "}]"; + } + + std::string getAsUnquotedString() const override { return Value; } + + /// 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 string"); + } + + Init *getBit(unsigned Bit) const override { + llvm_unreachable("Illegal bit reference off string"); + } +}; + +/// [AL, AH, CL] - Represent a list of defs /// -class ListInit : public TypedInit, public FoldingSetNode { - std::vector<Init*> Values; +class ListInit final : public TypedInit, public FoldingSetNode, + public TrailingObjects<BitsInit, Init *> { + unsigned NumValues; public: - typedef std::vector<Init*>::const_iterator const_iterator; + typedef Init *const *const_iterator; private: - explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy) - : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), - Values(Range.begin(), Range.end()) {} + explicit ListInit(unsigned N, RecTy *EltTy) + : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {} ListInit(const ListInit &Other) = delete; ListInit &operator=(const ListInit &Other) = delete; public: + // Do not use sized deallocation due to trailing objects. + void operator delete(void *p) { ::operator delete(p); } + static bool classof(const Init *I) { return I->getKind() == IK_ListInit; } @@ -608,8 +674,8 @@ public: void Profile(FoldingSetNodeID &ID) const; Init *getElement(unsigned i) const { - assert(i < Values.size() && "List element index out of range!"); - return Values[i]; + assert(i < NumValues && "List element index out of range!"); + return getTrailingObjects<Init *>()[i]; } Record *getElementAsRecord(unsigned i) const; @@ -619,7 +685,7 @@ public: Init *convertInitializerTo(RecTy *Ty) const override; - /// resolveReferences - This method is used by classes that refer to other + /// This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. @@ -628,15 +694,17 @@ public: std::string getAsString() const override; - ArrayRef<Init*> getValues() const { return Values; } + ArrayRef<Init*> getValues() const { + return makeArrayRef(getTrailingObjects<Init *>(), NumValues); + } - const_iterator begin() const { return Values.begin(); } - const_iterator end () const { return Values.end(); } + const_iterator begin() const { return getTrailingObjects<Init *>(); } + const_iterator end () const { return begin() + NumValues; } - size_t size () const { return Values.size(); } - bool empty() const { return Values.empty(); } + size_t size () const { return NumValues; } + bool empty() const { return NumValues == 0; } - /// resolveListElementReference - This method is used to implement + /// 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, @@ -647,7 +715,7 @@ public: } }; -/// OpInit - Base class for operators +/// Base class for operators /// class OpInit : public TypedInit { OpInit(const OpInit &Other) = delete; @@ -678,9 +746,9 @@ public: Init *getBit(unsigned Bit) const override; }; -/// UnOpInit - !op (X) - Transform an init. +/// !op (X) - Transform an init. /// -class UnOpInit : public OpInit { +class UnOpInit : public OpInit, public FoldingSetNode { public: enum UnaryOp : uint8_t { CAST, HEAD, TAIL, EMPTY }; @@ -699,6 +767,8 @@ public: } static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); + void Profile(FoldingSetNodeID &ID) const; + // Clone - Clone this operator, replacing arguments with the new list OpInit *clone(std::vector<Init *> &Operands) const override { assert(Operands.size() == 1 && @@ -724,9 +794,9 @@ public: std::string getAsString() const override; }; -/// BinOpInit - !op (X, Y) - Combine two inits. +/// !op (X, Y) - Combine two inits. /// -class BinOpInit : public OpInit { +class BinOpInit : public OpInit, public FoldingSetNode { public: enum BinaryOp : uint8_t { ADD, AND, SHL, SRA, SRL, LISTCONCAT, STRCONCAT, CONCAT, EQ }; @@ -747,6 +817,8 @@ public: static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type); + void Profile(FoldingSetNodeID &ID) const; + // Clone - Clone this operator, replacing arguments with the new list OpInit *clone(std::vector<Init *> &Operands) const override { assert(Operands.size() == 2 && @@ -776,9 +848,9 @@ public: std::string getAsString() const override; }; -/// TernOpInit - !op (X, Y, Z) - Combine two inits. +/// !op (X, Y, Z) - Combine two inits. /// -class TernOpInit : public OpInit { +class TernOpInit : public OpInit, public FoldingSetNode { public: enum TernaryOp : uint8_t { SUBST, FOREACH, IF }; @@ -800,6 +872,8 @@ public: Init *mhs, Init *rhs, RecTy *Type); + void Profile(FoldingSetNodeID &ID) const; + // Clone - Clone this operator, replacing arguments with the new list OpInit *clone(std::vector<Init *> &Operands) const override { assert(Operands.size() == 3 && @@ -834,7 +908,7 @@ public: std::string getAsString() const override; }; -/// VarInit - 'Opcode' - Represent a reference to an entire variable object. +/// 'Opcode' - Represent a reference to an entire variable object. /// class VarInit : public TypedInit { Init *VarName; @@ -865,7 +939,7 @@ public: Init *getFieldInit(Record &R, const RecordVal *RV, const std::string &FieldName) const override; - /// resolveReferences - This method is used by classes that refer to other + /// This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. @@ -877,7 +951,7 @@ public: std::string getAsString() const override { return getName(); } }; -/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field. +/// Opcode{0} - Represent access to one bit of a variable or field. /// class VarBitInit : public Init { TypedInit *TI; @@ -914,7 +988,7 @@ public: } }; -/// VarListElementInit - List[4] - Represent access to one element of a var or +/// List[4] - Represent access to one element of a var or /// field. class VarListElementInit : public TypedInit { TypedInit *TI; @@ -940,7 +1014,7 @@ public: TypedInit *getVariable() const { return TI; } unsigned getElementNum() const { return Element; } - /// resolveListElementReference - This method is used to implement + /// 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, @@ -952,7 +1026,7 @@ public: Init *getBit(unsigned Bit) const override; }; -/// DefInit - AL - Represent a reference to a 'def' in the description +/// AL - Represent a reference to a 'def' in the description /// class DefInit : public TypedInit { Record *Def; @@ -985,7 +1059,7 @@ public: llvm_unreachable("Illegal bit reference off def"); } - /// resolveListElementReference - This method is used to implement + /// 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, @@ -994,7 +1068,7 @@ public: } }; -/// FieldInit - X.Y - Represent a reference to a subfield of a variable +/// X.Y - Represent a reference to a subfield of a variable /// class FieldInit : public TypedInit { Init *Rec; // Record we are referring to @@ -1026,7 +1100,7 @@ public: } }; -/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required +/// (v a, b) - Represent a DAG tree value. DAG inits are required /// to have at least one value then a (possibly empty) list of arguments. Each /// argument can have a name associated with it. /// @@ -1148,21 +1222,22 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) { class Record { static unsigned LastID; - // Unique record ID. - unsigned ID; Init *Name; // Location where record was instantiated, followed by the location of // multiclass prototypes used. SmallVector<SMLoc, 4> Locs; - std::vector<Init *> TemplateArgs; - std::vector<RecordVal> Values; - std::vector<Record *> SuperClasses; - std::vector<SMRange> SuperClassRanges; + SmallVector<Init *, 0> TemplateArgs; + SmallVector<RecordVal, 0> Values; + SmallVector<std::pair<Record *, SMRange>, 0> SuperClasses; // Tracks Record instances. Not owned by Record. RecordKeeper &TrackedRecords; std::unique_ptr<DefInit> TheInit; + + // Unique record ID. + unsigned ID; + bool IsAnonymous; // Class-instance values can be used by other defs. For example, Struct<i> @@ -1184,8 +1259,8 @@ public: // Constructs a record. explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, bool Anonymous = false) : - ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), - TrackedRecords(records), IsAnonymous(Anonymous), ResolveFirst(false) { + Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records), + ID(LastID++), IsAnonymous(Anonymous), ResolveFirst(false) { init(); } explicit Record(const std::string &N, ArrayRef<SMLoc> locs, @@ -1197,11 +1272,10 @@ public: // 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), + Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), Values(O.Values), SuperClasses(O.SuperClasses), - SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords), - IsAnonymous(O.IsAnonymous), - ResolveFirst(O.ResolveFirst) { } + TrackedRecords(O.TrackedRecords), ID(LastID++), + IsAnonymous(O.IsAnonymous), ResolveFirst(O.ResolveFirst) { } static unsigned getNewUID() { return LastID++; } @@ -1227,8 +1301,9 @@ public: return TemplateArgs; } ArrayRef<RecordVal> getValues() const { return Values; } - ArrayRef<Record *> getSuperClasses() const { return SuperClasses; } - ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; } + ArrayRef<std::pair<Record *, SMRange>> getSuperClasses() const { + return SuperClasses; + } bool isTemplateArg(Init *Name) const { for (Init *TA : TemplateArgs) @@ -1290,31 +1365,35 @@ public: } bool isSubClassOf(const Record *R) const { - for (const Record *SC : SuperClasses) - if (SC == R) + for (const auto &SCPair : SuperClasses) + if (SCPair.first == R) return true; return false; } bool isSubClassOf(StringRef Name) const { - for (const Record *SC : SuperClasses) - if (SC->getNameInitAsString() == Name) + for (const auto &SCPair : SuperClasses) { + if (const auto *SI = dyn_cast<StringInit>(SCPair.first->getNameInit())) { + if (SI->getValue() == Name) + return true; + } else if (SCPair.first->getNameInitAsString() == Name) { return true; + } + } return false; } void addSuperClass(Record *R, SMRange Range) { assert(!isSubClassOf(R) && "Already subclassing record!"); - SuperClasses.push_back(R); - SuperClassRanges.push_back(Range); + SuperClasses.push_back(std::make_pair(R, Range)); } - /// resolveReferences - If there are any field references that refer to fields + /// If there are any field references that refer to fields /// that have been filled in, we can propagate the values now. /// void resolveReferences() { resolveReferencesTo(nullptr); } - /// resolveReferencesTo - If anything in this record refers to RV, replace the + /// If anything in this record refers to RV, replace the /// reference to RV with the RHS of RV. If RV is null, we resolve all /// possible references. void resolveReferencesTo(const RecordVal *RV); @@ -1341,7 +1420,7 @@ public: // High-level methods useful to tablegen back-ends // - /// getValueInit - Return the initializer for a value with the specified name, + /// Return the initializer for a value with the specified name, /// or throw an exception if the field does not exist. /// Init *getValueInit(StringRef FieldName) const; @@ -1351,67 +1430,67 @@ public: return isa<UnsetInit>(getValueInit(FieldName)); } - /// getValueAsString - This method looks up the specified field and returns + /// This method looks up the specified field and returns /// its value as a string, throwing an exception if the field does not exist /// or if the value is not a string. /// std::string getValueAsString(StringRef FieldName) const; - /// getValueAsBitsInit - This method looks up the specified field and returns + /// This method looks up the specified field and returns /// its value as a BitsInit, throwing an exception if the field does not exist /// or if the value is not the right type. /// BitsInit *getValueAsBitsInit(StringRef FieldName) const; - /// getValueAsListInit - This method looks up the specified field and returns + /// This method looks up the specified field and returns /// its value as a ListInit, throwing an exception if the field does not exist /// or if the value is not the right type. /// ListInit *getValueAsListInit(StringRef FieldName) const; - /// getValueAsListOfDefs - This method looks up the specified field and + /// This method looks up the specified field and /// returns its value as a vector of records, throwing an exception if the /// field does not exist or if the value is not the right type. /// std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const; - /// getValueAsListOfInts - This method looks up the specified field and + /// This method looks up the specified field and /// returns its value as a vector of integers, throwing an exception if the /// field does not exist or if the value is not the right type. /// std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const; - /// getValueAsListOfStrings - This method looks up the specified field and + /// This method looks up the specified field and /// returns its value as a vector of strings, throwing an exception if the /// field does not exist or if the value is not the right type. /// std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const; - /// getValueAsDef - This method looks up the specified field and returns its + /// This method looks up the specified field and returns its /// value as a Record, throwing an exception if the field does not exist or if /// the value is not the right type. /// Record *getValueAsDef(StringRef FieldName) const; - /// getValueAsBit - This method looks up the specified field and returns its + /// This method looks up the specified field and returns its /// value as a bit, throwing an exception if the field does not exist or if /// the value is not the right type. /// bool getValueAsBit(StringRef FieldName) const; - /// getValueAsBitOrUnset - This method looks up the specified field and + /// This method looks up the specified field and /// returns its value as a bit. If the field is unset, sets Unset to true and /// returns false. /// bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const; - /// getValueAsInt - This method looks up the specified field and returns its + /// This method looks up the specified field and returns its /// value as an int64_t, throwing an exception if the field does not exist or /// if the value is not the right type. /// int64_t getValueAsInt(StringRef FieldName) const; - /// getValueAsDag - This method looks up the specified field and returns its + /// This method looks up the specified field and returns its /// value as an Dag, throwing an exception if the field does not exist or if /// the value is not the right type. /// @@ -1463,16 +1542,16 @@ public: //===--------------------------------------------------------------------===// // High-level helper methods, useful for tablegen backends... - /// getAllDerivedDefinitions - This method returns all concrete definitions - /// that derive from the specified class name. If a class with the specified - /// name does not exist, an exception is thrown. - std::vector<Record*> + /// This method returns all concrete definitions + /// that derive from the specified class name. A class with the specified + /// name must exist. + std::vector<Record *> getAllDerivedDefinitions(const std::string &ClassName) const; void dump() const; }; -/// LessRecord - Sorting predicate to sort record pointers by name. +/// Sorting predicate to sort record pointers by name. /// struct LessRecord { bool operator()(const Record *Rec1, const Record *Rec2) const { @@ -1480,7 +1559,7 @@ struct LessRecord { } }; -/// LessRecordByID - Sorting predicate to sort record pointers by their +/// Sorting predicate to sort record pointers by their /// unique ID. If you just need a deterministic order, use this, since it /// just compares two `unsigned`; the other sorting predicates require /// string manipulation. @@ -1490,7 +1569,7 @@ struct LessRecordByID { } }; -/// LessRecordFieldName - Sorting predicate to sort record pointers by their +/// Sorting predicate to sort record pointers by their /// name field. /// struct LessRecordFieldName { @@ -1580,12 +1659,12 @@ struct LessRecordRegister { raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK); -/// QualifyName - Return an Init with a qualifier prefix referring +/// Return an Init with a qualifier prefix referring /// to CurRec's name. Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, Init *Name, const std::string &Scoper); -/// QualifyName - Return an Init with a qualifier prefix referring +/// Return an Init with a qualifier prefix referring /// to CurRec's name. Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, const std::string &Name, const std::string &Scoper); diff --git a/include/llvm/TableGen/SearchableTable.td b/include/llvm/TableGen/SearchableTable.td new file mode 100644 index 000000000000..12aaf6000c31 --- /dev/null +++ b/include/llvm/TableGen/SearchableTable.td @@ -0,0 +1,41 @@ +//===- SearchableTable.td ----------------------------------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the key top-level classes needed to produce a reasonably +// generic table that can be binary-searched via int and string entries. +// +// Each table must instantiate "Mappingkind", listing the fields that should be +// included and fields that shoould be searchable. Only two kinds of fields are +// searchable at the moment: "strings" (which are compared case-insensitively), +// and "bits". +// +// For each "MappingKind" the generated header will create GET_MAPPINGKIND_DECL +// and GET_MAPPINGKIND_IMPL guards. +// +// Inside the DECL guard will be a set of function declarations: +// "lookup{InstanceClass}By{SearchableField}", returning "const {InstanceClass} +// *" and accepting either a StringRef or a uintN_t. Additionally, if +// EnumNameField is still defined, there will be an "enum {InstanceClass}Values" +// allowing C++ code to reference either the primary data table's entries (if +// EnumValueField is not defined) or some other field (e.g. encoding) if it is. +// +// Inside the IMPL guard will be a primary data table "{InstanceClass}sList" and +// as many searchable indexes as requested +// ("{InstanceClass}sBy{SearchableField}"). Additionally implementations of the +// lookup function will be provided. +// +// See AArch64SystemOperands.td and its generated header for example uses. +// +//===----------------------------------------------------------------------===// + +class SearchableTable { + list<string> SearchableFields; + string EnumNameField = "Name"; + string EnumValueField; +} diff --git a/include/llvm/TableGen/StringToOffsetTable.h b/include/llvm/TableGen/StringToOffsetTable.h index e3277036dc76..e5b61ed1195e 100644 --- a/include/llvm/TableGen/StringToOffsetTable.h +++ b/include/llvm/TableGen/StringToOffsetTable.h @@ -76,6 +76,26 @@ public: } O << "\""; } + + /// Emit the string using character literals. MSVC has a limitation that + /// string literals cannot be longer than 64K. + void EmitCharArray(raw_ostream &O) { + assert(AggregateString.find(')') == std::string::npos && + "can't emit raw string with closing parens"); + int Count = 0; + O << ' '; + for (char C : AggregateString) { + O << " \'"; + O.write_escaped(StringRef(&C, 1)); + O << "\',"; + Count++; + if (Count > 14) { + O << "\n "; + Count = 0; + } + } + O << '\n'; + } }; } // end namespace llvm |