aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/Record.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/Record.h')
-rw-r--r--utils/TableGen/Record.h448
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