//===- Record.h - Classes to represent Table Records ------------*- C++ -*-===// // // //===----------------------------------------------------------------------===// #ifndef RECORD_H #define RECORD_H #include #include #include #include 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 &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 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 &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 &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 Records; public: ListInit(std::vector &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 &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 &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 TemplateArgs; std::vector Values; std::vector SuperClasses; public: Record(const std::string &N) : Name(N) {} ~Record() {} const std::string &getName() const { return Name; } const std::vector &getTemplateArgs() const { return TemplateArgs; } const std::vector &getValues() const { return Values; } const std::vector &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 Classes, Defs; public: ~RecordKeeper() { for (std::map::iterator I = Classes.begin(), E = Classes.end(); I != E; ++I) delete I->second; for (std::map::iterator I = Defs.begin(), E = Defs.end(); I != E; ++I) delete I->second; } const std::map &getClasses() const { return Classes; } const std::map &getDefs() const { return Defs; } Record *getClass(const std::string &Name) const { std::map::const_iterator I = Classes.find(Name); return I == Classes.end() ? 0 : I->second; } Record *getDef(const std::string &Name) const { std::map::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