X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FRecord.h;h=87a49ee2f8448c2fc89481cb3fd4460acf5d53ca;hb=20072af3b0b22d90afbce769409f4ed822520366;hp=1729b02866853f94af4ec5aa6c01fed84ff957a5;hpb=c7d58024f8bed33e0b3e795e51a62ec30248aff3;p=oota-llvm.git diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index 1729b028668..87a49ee2f84 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -1,5 +1,12 @@ //===- Record.h - Classes to represent Table Records ------------*- C++ -*-===// // +// 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 main TableGen data structures, including the TableGen // types, values, and high-level data structures. // @@ -8,13 +15,27 @@ #ifndef RECORD_H #define RECORD_H +#include "llvm/Support/DataTypes.h" #include #include #include -#include +#include #include -class Init; +namespace llvm { + +// RecTy subclasses. +class BitRecTy; +class BitsRecTy; +class IntRecTy; +class StringRecTy; +class ListRecTy; +class CodeRecTy; +class DagRecTy; +class RecordRecTy; + +// Init subclasses. +struct Init; class UnsetInit; class BitInit; class BitsInit; @@ -22,12 +43,18 @@ class IntInit; class StringInit; class CodeInit; class ListInit; +class BinOpInit; class DefInit; +class DagInit; class TypedInit; class VarInit; class FieldInit; class VarBitInit; +class VarListElementInit; + +// Other classes. class Record; +class RecordVal; //===----------------------------------------------------------------------===// // Type Classes @@ -36,15 +63,26 @@ class Record; struct RecTy { virtual ~RecTy() {} + virtual std::string getAsString() const = 0; + void print(std::ostream &OS) const { OS << getAsString(); } + void dump() const; + + /// typeIsConvertibleTo - Return true if all values of 'this' type can be + /// converted to the specified type. + virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; + +public: // These methods should only be called from subclasses of Init virtual Init *convertValue( UnsetInit *UI) { return 0; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } virtual Init *convertValue( IntInit *II) { return 0; } virtual Init *convertValue(StringInit *SI) { return 0; } virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } virtual Init *convertValue( CodeInit *CI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } virtual Init *convertValue( TypedInit *TI) { return 0; } virtual Init *convertValue( VarInit *VI) { return convertValue((TypedInit*)VI); @@ -53,8 +91,17 @@ struct RecTy { return convertValue((TypedInit*)FI); } - virtual void print(std::ostream &OS) const = 0; - void dump() const; +public: // These methods should only be called by subclasses of RecTy. + // baseClassOf - These virtual methods should be overloaded to return true iff + // all values of type 'RHS' can be converted to the 'this' type. + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) { @@ -65,101 +112,308 @@ inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) { /// BitRecTy - 'bit' - Represent a single bit /// -struct BitRecTy : public RecTy { - Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - Init *convertValue(BitInit *BI) { return (Init*)BI; } - Init *convertValue(BitsInit *BI); - Init *convertValue(IntInit *II); - Init *convertValue(TypedInit *VI); - Init *convertValue(VarBitInit *VB) { return (Init*)VB; } - - void print(std::ostream &OS) const { OS << "bit"; } +class BitRecTy : public RecTy { +public: + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI) { return (Init*)BI; } + virtual Init *convertValue( BitsInit *BI); + virtual Init *convertValue( IntInit *II); + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const { return "bit"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } + virtual bool baseClassOf(const BitsRecTy *RHS) const; + virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } + }; -/// BitsRecTy - 'bits' - Represent a fixed number of bits +// BitsRecTy - 'bits' - Represent a fixed number of bits +/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits /// class BitsRecTy : public RecTy { unsigned Size; public: - BitsRecTy(unsigned Sz) : Size(Sz) {} + explicit BitsRecTy(unsigned Sz) : Size(Sz) {} unsigned getNumBits() const { return Size; } - Init *convertValue(UnsetInit *UI); - Init *convertValue(BitInit *UI); - Init *convertValue(BitsInit *BI); - Init *convertValue(IntInit *II); - Init *convertValue(TypedInit *VI); + virtual Init *convertValue( UnsetInit *UI); + virtual Init *convertValue( BitInit *UI); + virtual Init *convertValue( BitsInit *BI); + virtual Init *convertValue( IntInit *II); + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const; + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { + return RHS->Size == Size; + } + virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } - void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; } }; /// IntRecTy - 'int' - Represent an integer value of no particular size /// -struct IntRecTy : public RecTy { - Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - Init *convertValue(IntInit *II) { return (Init*)II; } - Init *convertValue(BitsInit *BI); - Init *convertValue(TypedInit *TI); +class IntRecTy : public RecTy { +public: + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI); + virtual Init *convertValue( BitsInit *BI); + virtual Init *convertValue( IntInit *II) { return (Init*)II; } + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const { return "int"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } - void print(std::ostream &OS) const { OS << "int"; } }; /// StringRecTy - 'string' - Represent an string value /// -struct StringRecTy : public RecTy { - Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - Init *convertValue(StringInit *SI) { return (Init*)SI; } - Init *convertValue(TypedInit *TI); - void print(std::ostream &OS) const { OS << "string"; } +class StringRecTy : public RecTy { +public: + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI) { return 0; } + virtual Init *convertValue( BitsInit *BI) { return 0; } + virtual Init *convertValue( IntInit *II) { return 0; } + virtual Init *convertValue(StringInit *SI) { return (Init*)SI; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( BinOpInit *BO); + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const { return "string"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return true; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; -/// ListRecTy - 'list' - Represent a list defs, all of which must be -/// derived from the specified class. +// ListRecTy - 'list' - Represent a list of values, all of which must be of +// the specified type. +/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must +/// be of the specified type. /// class ListRecTy : public RecTy { - Record *Class; + RecTy *Ty; public: - ListRecTy(Record *C) : Class(C) {} + explicit ListRecTy(RecTy *T) : Ty(T) {} - /// getElementClass - Return the class that the list contains. - /// - Record *getElementClass() const { return Class; } + RecTy *getElementType() const { return Ty; } - Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - Init *convertValue(ListInit *LI); - Init *convertValue(TypedInit *TI); - - void print(std::ostream &OS) const; + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI) { return 0; } + virtual Init *convertValue( BitsInit *BI) { return 0; } + virtual Init *convertValue( IntInit *II) { return 0; } + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI); + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const; + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { + return RHS->getElementType()->typeIsConvertibleTo(Ty); + } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; /// CodeRecTy - 'code' - Represent an code fragment, function or method. /// -struct CodeRecTy : public RecTy { - Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - Init *convertValue( CodeInit *CI) { return (Init*)CI; } +class CodeRecTy : public RecTy { +public: + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI) { return 0; } + virtual Init *convertValue( BitsInit *BI) { return 0; } + virtual Init *convertValue( IntInit *II) { return 0; } + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( CodeInit *CI) { return (Init*)CI; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const { return "code"; } - void print(std::ostream &OS) const { OS << "code"; } + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; +/// DagRecTy - 'dag' - Represent a dag fragment +/// +class DagRecTy : public RecTy { +public: + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI) { return 0; } + virtual Init *convertValue( BitsInit *BI) { return 0; } + virtual Init *convertValue( IntInit *II) { return 0; } + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( BinOpInit *BO); + virtual Init *convertValue( DagInit *CI) { return (Init*)CI; } + virtual Init *convertValue( TypedInit *TI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const { return "dag"; } -/// RecordRecTy - '' - Represent an instance of a class, such as: + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return true; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } +}; + + +/// RecordRecTy - '[classname]' - Represent an instance of a class, such as: /// (R32 X = EAX). /// class RecordRecTy : public RecTy { Record *Rec; public: - RecordRecTy(Record *R) : Rec(R) {} + explicit RecordRecTy(Record *R) : Rec(R) {} Record *getRecord() const { return Rec; } - Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - Init *convertValue( DefInit *DI); - Init *convertValue(TypedInit *VI); + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } + virtual Init *convertValue( BitInit *BI) { return 0; } + virtual Init *convertValue( BitsInit *BI) { return 0; } + virtual Init *convertValue( IntInit *II) { return 0; } + virtual Init *convertValue(StringInit *SI) { return 0; } + virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( CodeInit *CI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } + virtual Init *convertValue( DefInit *DI); + virtual Init *convertValue( DagInit *DI) { return 0; } + virtual Init *convertValue( TypedInit *VI); + virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} + virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} + + std::string getAsString() const; - void print(std::ostream &OS) const; + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const; }; @@ -176,7 +430,10 @@ struct Init { virtual bool isComplete() const { return true; } /// print - Print out this value. - virtual void print(std::ostream &OS) const = 0; + void print(std::ostream &OS) const { OS << getAsString(); } + + /// getAsString - Convert this value to a string form. + virtual std::string getAsString() const = 0; /// dump - Debugging method that may be called through a debugger, just /// invokes print on cerr. @@ -197,6 +454,15 @@ struct Init { return 0; } + /// convertInitListSlice - 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. + /// + virtual Init *convertInitListSlice(const std::vector &Elements) { + return 0; + } + /// getFieldType - 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. @@ -216,7 +482,9 @@ struct Init { /// 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. /// - virtual Init *resolveReferences(Record &R) { return this; } + virtual Init *resolveReferences(Record &R, const RecordVal *RV) { + return this; + } }; inline std::ostream &operator<<(std::ostream &OS, const Init &I) { @@ -226,13 +494,14 @@ inline std::ostream &operator<<(std::ostream &OS, const Init &I) { /// UnsetInit - ? - Represents an uninitialized value /// -struct UnsetInit : public Init { +class UnsetInit : public Init { +public: virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } virtual bool isComplete() const { return false; } - virtual void print(std::ostream &OS) const { OS << "?"; } + virtual std::string getAsString() const { return "?"; } }; @@ -241,7 +510,7 @@ struct UnsetInit : public Init { class BitInit : public Init { bool Value; public: - BitInit(bool V) : Value(V) {} + explicit BitInit(bool V) : Value(V) {} bool getValue() const { return Value; } @@ -249,7 +518,7 @@ public: return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); } + virtual std::string getAsString() const { return Value ? "1" : "0"; } }; /// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. @@ -258,7 +527,7 @@ public: class BitsInit : public Init { std::vector Bits; public: - BitsInit(unsigned Size) : Bits(Size) {} + explicit BitsInit(unsigned Size) : Bits(Size) {} unsigned getNumBits() const { return Bits.size(); } @@ -282,9 +551,9 @@ public: if (!getBit(i)->isComplete()) return false; return true; } - virtual void print(std::ostream &OS) const; + virtual std::string getAsString() const; - virtual Init *resolveReferences(Record &R); + virtual Init *resolveReferences(Record &R, const RecordVal *RV); // printXX - Print this bitstream with the specified format, returning true if // it is not possible. @@ -297,18 +566,18 @@ public: /// IntInit - 7 - Represent an initalization by a literal integer value. /// class IntInit : public Init { - int Value; + int64_t Value; public: - IntInit(int V) : Value(V) {} + explicit IntInit(int64_t V) : Value(V) {} - int getValue() const { return Value; } + int64_t getValue() const { return Value; } virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } virtual Init *convertInitializerBitRange(const std::vector &Bits); - virtual void print(std::ostream &OS) const { OS << Value; } + virtual std::string getAsString() const; }; @@ -317,7 +586,7 @@ public: class StringInit : public Init { std::string Value; public: - StringInit(const std::string &V) : Value(V) {} + explicit StringInit(const std::string &V) : Value(V) {} const std::string &getValue() const { return Value; } @@ -325,7 +594,7 @@ public: return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; } + virtual std::string getAsString() const { return "\"" + Value + "\""; } }; /// CodeInit - "[{...}]" - Represent a code fragment. @@ -333,7 +602,7 @@ public: class CodeInit : public Init { std::string Value; public: - CodeInit(const std::string &V) : Value(V) {} + explicit CodeInit(const std::string &V) : Value(V) {} const std::string getValue() const { return Value; } @@ -341,47 +610,109 @@ public: return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const { OS << "[{" << Value << "}]"; } + virtual std::string getAsString() const { return "[{" + Value + "}]"; } }; /// ListInit - [AL, AH, CL] - Represent a list of defs /// class ListInit : public Init { - std::vector Records; + std::vector Values; public: - ListInit(std::vector &Rs) { - Records.swap(Rs); + explicit ListInit(std::vector &Vs) { + Values.swap(Vs); } - unsigned getSize() const { return Records.size(); } - Record *getElement(unsigned i) const { - assert(i < Records.size() && "List element index out of range!"); - return Records[i]; + unsigned getSize() const { return Values.size(); } + Init *getElement(unsigned i) const { + assert(i < Values.size() && "List element index out of range!"); + return Values[i]; } + Record *getElementAsRecord(unsigned i) const; + + Init *convertInitListSlice(const std::vector &Elements); + virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const; + /// resolveReferences - 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. + /// + virtual Init *resolveReferences(Record &R, const RecordVal *RV); + + virtual std::string getAsString() const; + + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + + inline iterator begin() { return Values.begin(); } + inline const_iterator begin() const { return Values.begin(); } + inline iterator end () { return Values.end(); } + inline const_iterator end () const { return Values.end(); } + + inline size_t size () const { return Values.size(); } + inline bool empty() const { return Values.empty(); } }; +/// BinOpInit - !op (X, Y) - Combine two inits. +/// +class BinOpInit : public Init { +public: + enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT }; +private: + BinaryOp Opc; + Init *LHS, *RHS; +public: + BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) { + } + + BinaryOp getOpcode() const { return Opc; } + Init *getLHS() const { return LHS; } + Init *getRHS() const { return RHS; } + + // Fold - If possible, fold this to a simpler init. Return this if not + // possible to fold. + Init *Fold(); + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual Init *resolveReferences(Record &R, const RecordVal *RV); + + virtual std::string getAsString() const; +}; + + /// TypedInit - This is the common super-class of types that have a specific, /// explicit, type. /// class TypedInit : public Init { RecTy *Ty; -public: - TypedInit(RecTy *T) : Ty(T) {} +public: + explicit TypedInit(RecTy *T) : Ty(T) {} RecTy *getType() const { return Ty; } + virtual Init *convertInitializerBitRange(const std::vector &Bits); + virtual Init *convertInitListSlice(const std::vector &Elements); + /// resolveBitReference - This method is used to implement /// VarBitInit::resolveReferences. If the bit is able to be resolved, we - /// simply return the resolved value, otherwise we return this. + /// simply return the resolved value, otherwise we return null. /// - virtual Init *resolveBitReference(Record &R, unsigned Bit) = 0; + virtual Init *resolveBitReference(Record &R, const RecordVal *RV, + unsigned Bit) = 0; + + /// 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. + virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, + unsigned Elt) = 0; }; /// VarInit - 'Opcode' - Represent a reference to an entire variable object. @@ -389,17 +720,19 @@ public: class VarInit : public TypedInit { std::string VarName; public: - VarInit(const std::string &VN, RecTy *T) : TypedInit(T), VarName(VN) {} - + explicit VarInit(const std::string &VN, RecTy *T) + : TypedInit(T), VarName(VN) {} + virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } const std::string &getName() const { return VarName; } - virtual Init *convertInitializerBitRange(const std::vector &Bits); - - virtual Init *resolveBitReference(Record &R, unsigned Bit); + virtual Init *resolveBitReference(Record &R, const RecordVal *RV, + unsigned Bit); + virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, + unsigned Elt); virtual RecTy *getFieldType(const std::string &FieldName) const; virtual Init *getFieldInit(Record &R, const std::string &FieldName) const; @@ -409,9 +742,9 @@ public: /// 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. /// - virtual Init *resolveReferences(Record &R); - - virtual void print(std::ostream &OS) const { OS << VarName; } + virtual Init *resolveReferences(Record &R, const RecordVal *RV); + + virtual std::string getAsString() const { return VarName; } }; @@ -433,21 +766,51 @@ public: TypedInit *getVariable() const { return TI; } unsigned getBitNum() const { return Bit; } - - virtual void print(std::ostream &OS) const { - TI->print(OS); OS << "{" << Bit << "}"; - } - virtual Init *resolveReferences(Record &R); + + virtual std::string getAsString() const; + virtual Init *resolveReferences(Record &R, const RecordVal *RV); }; +/// VarListElementInit - List[4] - Represent access to one element of a var or +/// field. +class VarListElementInit : public TypedInit { + TypedInit *TI; + unsigned Element; +public: + VarListElementInit(TypedInit *T, unsigned E) + : TypedInit(dynamic_cast(T->getType())->getElementType()), + TI(T), Element(E) { + assert(T->getType() && dynamic_cast(T->getType()) && + "Illegal VarBitInit expression!"); + } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + TypedInit *getVariable() const { return TI; } + unsigned getElementNum() const { return Element; } + + virtual Init *resolveBitReference(Record &R, const RecordVal *RV, + unsigned Bit); + + /// 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. + virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, + unsigned Elt); + + virtual std::string getAsString() const; + virtual Init *resolveReferences(Record &R, const RecordVal *RV); +}; /// DefInit - AL - Represent a reference to a 'def' in the description /// class DefInit : public Init { Record *Def; public: - DefInit(Record *D) : Def(D) {} - + explicit DefInit(Record *D) : Def(D) {} + virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } @@ -458,8 +821,8 @@ public: virtual RecTy *getFieldType(const std::string &FieldName) const; virtual Init *getFieldInit(Record &R, const std::string &FieldName) const; - - virtual void print(std::ostream &OS) const; + + virtual std::string getAsString() const; }; @@ -478,17 +841,88 @@ public: return Ty->convertValue(this); } - virtual Init *convertInitializerBitRange(const std::vector &Bits); - - virtual Init *resolveBitReference(Record &R, unsigned Bit); + virtual Init *resolveBitReference(Record &R, const RecordVal *RV, + unsigned Bit); + virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, + unsigned Elt); - virtual Init *resolveReferences(Record &R); + virtual Init *resolveReferences(Record &R, const RecordVal *RV); - virtual void print(std::ostream &OS) const { - Rec->print(OS); OS << "." << FieldName; + virtual std::string getAsString() const { + return Rec->getAsString() + "." + FieldName; } }; +/// DagInit - (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. +/// +class DagInit : public Init { + Init *Val; + std::vector Args; + std::vector ArgNames; +public: + DagInit(Init *V, const std::vector > &args) + : Val(V) { + Args.reserve(args.size()); + ArgNames.reserve(args.size()); + for (unsigned i = 0, e = args.size(); i != e; ++i) { + Args.push_back(args[i].first); + ArgNames.push_back(args[i].second); + } + } + DagInit(Init *V, const std::vector &args, + const std::vector &argNames) + : Val(V), Args(args), ArgNames(argNames) { + } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + Init *getOperator() const { return Val; } + + unsigned getNumArgs() const { return Args.size(); } + Init *getArg(unsigned Num) const { + assert(Num < Args.size() && "Arg number out of range!"); + return Args[Num]; + } + const std::string &getArgName(unsigned Num) const { + assert(Num < ArgNames.size() && "Arg number out of range!"); + return ArgNames[Num]; + } + + void setArg(unsigned Num, Init *I) { + assert(Num < Args.size() && "Arg number out of range!"); + Args[Num] = I; + } + + virtual Init *resolveReferences(Record &R, const RecordVal *RV); + + virtual std::string getAsString() const; + + typedef std::vector::iterator arg_iterator; + typedef std::vector::const_iterator const_arg_iterator; + typedef std::vector::iterator name_iterator; + typedef std::vector::const_iterator const_name_iterator; + + inline arg_iterator arg_begin() { return Args.begin(); } + inline const_arg_iterator arg_begin() const { return Args.begin(); } + inline arg_iterator arg_end () { return Args.end(); } + inline const_arg_iterator arg_end () const { return Args.end(); } + + inline size_t arg_size () const { return Args.size(); } + inline bool arg_empty() const { return Args.empty(); } + + inline name_iterator name_begin() { return ArgNames.begin(); } + inline const_name_iterator name_begin() const { return ArgNames.begin(); } + inline name_iterator name_end () { return ArgNames.end(); } + inline const_name_iterator name_end () const { return ArgNames.end(); } + + inline size_t name_size () const { return ArgNames.size(); } + inline bool name_empty() const { return ArgNames.empty(); } + +}; //===----------------------------------------------------------------------===// // High-Level Classes @@ -526,17 +960,18 @@ inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) { return OS; } -struct Record { - const std::string Name; +class Record { + std::string Name; std::vector TemplateArgs; std::vector Values; std::vector SuperClasses; public: - Record(const std::string &N) : Name(N) {} + explicit Record(const std::string &N) : Name(N) {} ~Record() {} const std::string &getName() const { return Name; } + void setName(const std::string &Name); // Also updates RecordKeeper. const std::vector &getTemplateArgs() const { return TemplateArgs; } @@ -583,7 +1018,14 @@ public: bool isSubClassOf(Record *R) const { for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) if (SuperClasses[i] == R) - return true; + return true; + return false; + } + + bool isSubClassOf(const std::string &Name) const { + for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) + if (SuperClasses[i]->getName() == Name) + return true; return false; } @@ -592,10 +1034,15 @@ public: SuperClasses.push_back(R); } - // resolveReferences - If there are any field references that refer to fields - // that have been filled in, we can propagate the values now. - // - void resolveReferences(); + /// resolveReferences - If there are any field references that refer to fields + /// that have been filled in, we can propagate the values now. + /// + void resolveReferences() { resolveReferencesTo(0); } + + /// resolveReferencesTo - 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); void dump() const; @@ -626,11 +1073,47 @@ public: /// ListInit *getValueAsListInit(const std::string &FieldName) const; + /// getValueAsListOfDefs - 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 getValueAsListOfDefs(const std::string &FieldName) const; + + /// getValueAsListOfInts - 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 getValueAsListOfInts(const std::string &FieldName) const; + + /// getValueAsDef - 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(const std::string &FieldName) const; + + /// getValueAsBit - 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(const std::string &FieldName) const; + /// getValueAsInt - This method looks up the specified field and returns its - /// value as an int, throwing an exception if the field does not exist or if + /// 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(const std::string &FieldName) const; + + /// getValueAsDag - 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. /// - int getValueAsInt(const std::string &FieldName) const; + DagInit *getValueAsDag(const std::string &FieldName) const; + + /// getValueAsCode - This method looks up the specified field and returns + /// its value as the string data in a CodeInit, throwing an exception if the + /// field does not exist or if the value is not a code object. + /// + std::string getValueAsCode(const std::string &FieldName) const; }; std::ostream &operator<<(std::ostream &OS, const Record &R); @@ -640,13 +1123,13 @@ class RecordKeeper { public: ~RecordKeeper() { for (std::map::iterator I = Classes.begin(), - E = Classes.end(); I != E; ++I) + E = Classes.end(); I != E; ++I) delete I->second; for (std::map::iterator I = Defs.begin(), - E = Defs.end(); I != E; ++I) + E = Defs.end(); I != E; ++I) delete I->second; } - + const std::map &getClasses() const { return Classes; } const std::map &getDefs() const { return Defs; } @@ -667,6 +1150,19 @@ public: Defs.insert(std::make_pair(R->getName(), R)); } + /// 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... @@ -680,8 +1176,28 @@ public: void dump() const; }; +/// LessRecord - Sorting predicate to sort record pointers by name. +/// +struct LessRecord { + bool operator()(const Record *Rec1, const Record *Rec2) const { + return Rec1->getName() < Rec2->getName(); + } +}; + +/// LessRecordFieldName - Sorting predicate to sort record pointers by their +/// name field. +/// +struct LessRecordFieldName { + bool operator()(const Record *Rec1, const Record *Rec2) const { + return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name"); + } +}; + + std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK); extern RecordKeeper Records; +} // End llvm namespace + #endif