diff options
Diffstat (limited to 'utils/TableGen/Record.h')
-rw-r--r-- | utils/TableGen/Record.h | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h new file mode 100644 index 0000000..a3f8c0b --- /dev/null +++ b/utils/TableGen/Record.h @@ -0,0 +1,448 @@ +//===- Record.h - Classes to represent Table Records ------------*- C++ -*-===// +// +// +//===----------------------------------------------------------------------===// + +#ifndef RECORD_H +#define RECORD_H + +#include <string> +#include <vector> +#include <map> +#include <iostream> +class Init; +class UnsetInit; +class BitInit; +class BitsInit; +class IntInit; +class StringInit; +class ListInit; +class VarInit; +class VarBitInit; +class DefInit; +class Record; + +//===----------------------------------------------------------------------===// +// Type Classes +//===----------------------------------------------------------------------===// + +struct RecTy { + virtual ~RecTy() {} + + 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( VarInit *VI) { return 0; } + virtual Init *convertValue(VarBitInit *VB) { return 0; } + virtual Init *convertValue( DefInit *DI) { return 0; } + + virtual void print(std::ostream &OS) const = 0; + void dump() const; +}; + +inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) { + Ty.print(OS); + return OS; +} + +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(VarInit *VI); + + void print(std::ostream &OS) const { OS << "bit"; } +}; + +class BitsRecTy : public RecTy { + unsigned Size; +public: + 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(VarInit *VI); + + void print(std::ostream &OS) const { OS << "bits<" << 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(VarInit *VI); + + void print(std::ostream &OS) const { OS << "int"; } +}; + +struct StringRecTy : public RecTy { + Init *convertValue(UnsetInit *UI) { return (Init*)UI; } + Init *convertValue(StringInit *SI) { return (Init*)SI; } + Init *convertValue(VarInit *VI); + void print(std::ostream &OS) const { OS << "string"; } +}; + +class ListRecTy : public RecTy { + Record *Class; +public: + ListRecTy(Record *C) : Class(C) {} + Init *convertValue(UnsetInit *UI) { return (Init*)UI; } + Init *convertValue(ListInit *LI); + + void print(std::ostream &OS) const; +}; + +class RecordRecTy : public RecTy { + Record *Rec; +public: + RecordRecTy(Record *R) : Rec(R) {} + + Init *convertValue(UnsetInit *UI) { return (Init*)UI; } + Init *convertValue( DefInit *DI); + + void print(std::ostream &OS) const; +}; + +//===----------------------------------------------------------------------===// +// Initializer Classes +//===----------------------------------------------------------------------===// + +struct Init { + virtual ~Init() {} + + virtual bool isComplete() const = 0; + virtual void print(std::ostream &OS) const = 0; + void dump() const; + + virtual Init *convertInitializerTo(RecTy *Ty) = 0; + virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits) { + return 0; + } + + virtual Init *resolveReferences(Record &R) { return this; } +}; + +inline std::ostream &operator<<(std::ostream &OS, const Init &I) { + I.print(OS); return OS; +} + +struct UnsetInit : public Init { + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual bool isComplete() const { return false; } + virtual void print(std::ostream &OS) const { OS << "?"; } +}; + +class BitInit : public Init { + bool Value; +public: + BitInit(bool V) : Value(V) {} + + bool getValue() const { return Value; } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); } +}; + +class BitsInit : public Init { + std::vector<Init*> Bits; +public: + BitsInit(unsigned Size) : Bits(Size) {} + + unsigned getNumBits() const { return Bits.size(); } + + Init *getBit(unsigned Bit) const { + assert(Bit < Bits.size() && "Bit index out of range!"); + return Bits[Bit]; + } + void setBit(unsigned Bit, Init *V) { + assert(Bit < Bits.size() && "Bit index out of range!"); + Bits[Bit] = V; + } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); + + virtual bool isComplete() const { + for (unsigned i = 0; i != getNumBits(); ++i) + if (!getBit(i)->isComplete()) return false; + return true; + } + virtual void print(std::ostream &OS) const; + + virtual Init *resolveReferences(Record &R); + + // printXX - Print this bitstream with the specified format, returning true if + // it is not possible. + bool printInHex(std::ostream &OS) const; + bool printAsVariable(std::ostream &OS) const; + bool printAsUnset(std::ostream &OS) const; +}; + +class IntInit : public Init { + int Value; +public: + IntInit(int V) : Value(V) {} + + int getValue() const { return Value; } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const { OS << Value; } +}; + +class StringInit : public Init { + std::string Value; +public: + StringInit(const std::string &V) : Value(V) {} + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; } +}; + +class ListInit : public Init { + std::vector<Record*> Records; +public: + ListInit(std::vector<Record*> &Rs) { + Records.swap(Rs); + } + + unsigned getSize() const { return Records.size(); } + Record *getElement(unsigned i) const { + assert(i < Records.size() && "List element index out of range!"); + return Records[i]; + } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const; +}; + +class VarInit : public Init { + std::string VarName; + RecTy *Ty; +public: + VarInit(const std::string &VN, RecTy *T) : VarName(VN), Ty(T) {} + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + const std::string &getName() const { return VarName; } + RecTy *getType() const { return Ty; } + + virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const { OS << VarName; } +}; + +class VarBitInit : public Init { + VarInit *VI; + unsigned Bit; +public: + VarBitInit(VarInit *V, unsigned B) : VI(V), Bit(B) {} + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + VarInit *getVariable() const { return VI; } + unsigned getBitNum() const { return Bit; } + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const { + VI->print(OS); OS << "{" << Bit << "}"; + } + virtual Init *resolveReferences(Record &R); +}; + +class DefInit : public Init { + Record *Def; +public: + DefInit(Record *D) : Def(D) {} + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + Record *getDef() const { return Def; } + + //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const; +}; + + + +//===----------------------------------------------------------------------===// +// High-Level Classes +//===----------------------------------------------------------------------===// + +class RecordVal { + std::string Name; + RecTy *Ty; + unsigned Prefix; + Init *Value; +public: + RecordVal(const std::string &N, RecTy *T, unsigned P); + ~RecordVal() { /*delete Ty; delete Value; Bad for copy ctor!*/ } + + const std::string &getName() const { return Name; } + + unsigned getPrefix() const { return Prefix; } + RecTy *getType() const { return Ty; } + Init *getValue() const { return Value; } + + bool setValue(Init *V) { + if (V) { + Value = V->convertInitializerTo(Ty); + return Value == 0; + } + Value = 0; + return false; + } + + void dump() const; + void print(std::ostream &OS, bool PrintSem = true) const; +}; + +inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) { + RV.print(OS << " "); + return OS; +} + +struct Record { + const std::string Name; + std::vector<std::string> TemplateArgs; + std::vector<RecordVal> Values; + std::vector<Record*> SuperClasses; +public: + + Record(const std::string &N) : Name(N) {} + ~Record() {} + + const std::string &getName() const { return Name; } + const std::vector<std::string> &getTemplateArgs() const { + return TemplateArgs; + } + const std::vector<RecordVal> &getValues() const { return Values; } + const std::vector<Record*> &getSuperClasses() const { return SuperClasses; } + + bool isTemplateArg(const std::string &Name) const { + for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) + if (TemplateArgs[i] == Name) return true; + return false; + } + + const RecordVal *getValue(const std::string &Name) const { + for (unsigned i = 0, e = Values.size(); i != e; ++i) + if (Values[i].getName() == Name) return &Values[i]; + return 0; + } + RecordVal *getValue(const std::string &Name) { + for (unsigned i = 0, e = Values.size(); i != e; ++i) + if (Values[i].getName() == Name) return &Values[i]; + return 0; + } + + void addTemplateArg(const std::string &Name) { + assert(!isTemplateArg(Name) && "Template arg already defined!"); + TemplateArgs.push_back(Name); + } + + void addValue(const RecordVal &RV) { + assert(getValue(RV.getName()) == 0 && "Value already added!"); + Values.push_back(RV); + } + + bool isSubClassOf(Record *R) const { + for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) + if (SuperClasses[i] == R) + return true; + return false; + } + + void addSuperClass(Record *R) { + assert(!isSubClassOf(R) && "Already subclassing record!"); + 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(); + + void dump() const; +}; + +std::ostream &operator<<(std::ostream &OS, const Record &R); + +class RecordKeeper { + std::map<std::string, Record*> 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; } + + Record *getClass(const std::string &Name) const { + std::map<std::string, Record*>::const_iterator I = Classes.find(Name); + return I == Classes.end() ? 0 : I->second; + } + Record *getDef(const std::string &Name) const { + std::map<std::string, Record*>::const_iterator I = Defs.find(Name); + return I == Defs.end() ? 0 : I->second; + } + void addClass(Record *R) { + assert(getClass(R->getName()) == 0 && "Class already exists!"); + Classes.insert(std::make_pair(R->getName(), R)); + } + void addDef(Record *R) { + assert(getDef(R->getName()) == 0 && "Def already exists!"); + Defs.insert(std::make_pair(R->getName(), R)); + } + + void dump() const; +}; + +std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK); + +extern RecordKeeper Records; + +#endif |