Initial checkin of TableGen utility
[oota-llvm.git] / support / tools / TableGen / Record.h
1 //===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
2 //
3 //
4 //===----------------------------------------------------------------------===//
5
6 #ifndef RECORD_H
7 #define RECORD_H
8
9 #include <string>
10 #include <vector>
11 #include <map>
12 #include <iostream>
13 class Init;
14 class UnsetInit;
15 class BitInit;
16 class BitsInit;
17 class IntInit;
18 class StringInit;
19 class ListInit;
20 class VarInit;
21 class VarBitInit;
22 class DefInit;
23 class Record;
24
25 //===----------------------------------------------------------------------===//
26 //  Type Classes
27 //===----------------------------------------------------------------------===//
28
29 struct RecTy {
30   virtual ~RecTy() {}
31
32   virtual Init *convertValue( UnsetInit *UI) { return 0; }
33   virtual Init *convertValue(   BitInit *BI) { return 0; }
34   virtual Init *convertValue(  BitsInit *BI) { return 0; }
35   virtual Init *convertValue(   IntInit *II) { return 0; }
36   virtual Init *convertValue(StringInit *SI) { return 0; }
37   virtual Init *convertValue(  ListInit *LI) { return 0; }
38   virtual Init *convertValue(   VarInit *VI) { return 0; }
39   virtual Init *convertValue(VarBitInit *VB) { return 0; }
40   virtual Init *convertValue(   DefInit *DI) { return 0; }
41
42   virtual void print(std::ostream &OS) const = 0;
43   void dump() const;
44 };
45
46 inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
47   Ty.print(OS);
48   return OS;
49 }
50
51 struct BitRecTy : public RecTy {
52   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
53   Init *convertValue(BitInit *BI) { return (Init*)BI; }
54   Init *convertValue(BitsInit *BI);
55   Init *convertValue(IntInit *II);
56   Init *convertValue(VarInit *VI);
57
58   void print(std::ostream &OS) const { OS << "bit"; }
59 };
60
61 class BitsRecTy : public RecTy {
62   unsigned Size;
63 public:
64   BitsRecTy(unsigned Sz) : Size(Sz) {}
65
66   unsigned getNumBits() const { return Size; }
67
68   Init *convertValue(UnsetInit *UI);
69   Init *convertValue(BitInit *UI);
70   Init *convertValue(BitsInit *BI);
71   Init *convertValue(IntInit *II);
72   Init *convertValue(VarInit *VI);
73
74   void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
75 };
76
77 struct IntRecTy : public RecTy {
78   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
79   Init *convertValue(IntInit *II) { return (Init*)II; }
80   Init *convertValue(BitsInit *BI);
81   Init *convertValue(VarInit *VI);
82
83   void print(std::ostream &OS) const { OS << "int"; }
84 };
85
86 struct StringRecTy : public RecTy {
87   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
88   Init *convertValue(StringInit *SI) { return (Init*)SI; }
89   Init *convertValue(VarInit *VI);
90   void print(std::ostream &OS) const { OS << "string"; }
91 };
92
93 class ListRecTy : public RecTy {
94   Record *Class;
95 public:
96   ListRecTy(Record *C) : Class(C) {}
97   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
98   Init *convertValue(ListInit *LI);
99   
100   void print(std::ostream &OS) const;
101 };
102
103 class RecordRecTy : public RecTy {
104   Record *Rec;
105 public:
106   RecordRecTy(Record *R) : Rec(R) {}
107
108   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
109   Init *convertValue(   DefInit *DI);
110
111   void print(std::ostream &OS) const;
112 };
113
114 //===----------------------------------------------------------------------===//
115 //  Initializer Classes
116 //===----------------------------------------------------------------------===//
117
118 struct Init {
119   virtual ~Init() {}
120
121   virtual bool isComplete() const = 0;
122   virtual void print(std::ostream &OS) const = 0;
123   void dump() const;
124
125   virtual Init *convertInitializerTo(RecTy *Ty) = 0;
126   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits) {
127     return 0;
128   }
129
130   virtual Init *resolveReferences(Record &R) { return this; }
131 };
132
133 inline std::ostream &operator<<(std::ostream &OS, const Init &I) {
134   I.print(OS); return OS;
135 }
136
137 struct UnsetInit : public Init {
138   virtual Init *convertInitializerTo(RecTy *Ty) {
139     return Ty->convertValue(this);
140   }
141
142   virtual bool isComplete() const { return false; }
143   virtual void print(std::ostream &OS) const { OS << "?"; }
144 };
145
146 class BitInit : public Init {
147   bool Value;
148 public:
149   BitInit(bool V) : Value(V) {}
150
151   bool getValue() const { return Value; }
152
153   virtual Init *convertInitializerTo(RecTy *Ty) {
154     return Ty->convertValue(this);
155   }
156
157   virtual bool isComplete() const { return true; }
158   virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); }
159 };
160
161 class BitsInit : public Init {
162   std::vector<Init*> Bits;
163 public:
164   BitsInit(unsigned Size) : Bits(Size) {}
165
166   unsigned getNumBits() const { return Bits.size(); }
167
168   Init *getBit(unsigned Bit) const {
169     assert(Bit < Bits.size() && "Bit index out of range!");
170     return Bits[Bit];
171   }
172   void setBit(unsigned Bit, Init *V) {
173     assert(Bit < Bits.size() && "Bit index out of range!");
174     Bits[Bit] = V;
175   }
176
177   virtual Init *convertInitializerTo(RecTy *Ty) {
178     return Ty->convertValue(this);
179   }
180   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
181
182   virtual bool isComplete() const {
183     for (unsigned i = 0; i != getNumBits(); ++i)
184       if (!getBit(i)->isComplete()) return false;
185     return true;
186   }
187   virtual void print(std::ostream &OS) const;
188
189   virtual Init *resolveReferences(Record &R);
190
191   // printXX - Print this bitstream with the specified format, returning true if
192   // it is not possible.
193   bool printInHex(std::ostream &OS) const;
194   bool printAsVariable(std::ostream &OS) const;
195   bool printAsUnset(std::ostream &OS) const;
196 };
197
198 class IntInit : public Init {
199   int Value;
200 public:
201   IntInit(int V) : Value(V) {}
202
203   int getValue() const { return Value; }
204
205   virtual Init *convertInitializerTo(RecTy *Ty) {
206     return Ty->convertValue(this);
207   }
208   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
209
210   virtual bool isComplete() const { return true; }
211   virtual void print(std::ostream &OS) const { OS << Value; }
212 };
213
214 class StringInit : public Init {
215   std::string Value;
216 public:
217   StringInit(const std::string &V) : Value(V) {}
218
219   virtual Init *convertInitializerTo(RecTy *Ty) {
220     return Ty->convertValue(this);
221   }
222
223   virtual bool isComplete() const { return true; }
224   virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; }
225 };
226
227 class ListInit : public Init {
228   std::vector<Record*> Records;
229 public:
230   ListInit(std::vector<Record*> &Rs) {
231     Records.swap(Rs);
232   }
233
234   unsigned getSize() const { return Records.size(); }
235   Record  *getElement(unsigned i) const {
236     assert(i < Records.size() && "List element index out of range!");
237     return Records[i];
238   }
239
240   virtual Init *convertInitializerTo(RecTy *Ty) {
241     return Ty->convertValue(this);
242   }
243
244   virtual bool isComplete() const { return true; }
245   virtual void print(std::ostream &OS) const;
246 };
247
248 class VarInit : public Init {
249   std::string VarName;
250   RecTy *Ty;
251 public:
252   VarInit(const std::string &VN, RecTy *T) : VarName(VN), Ty(T) {}
253   
254   virtual Init *convertInitializerTo(RecTy *Ty) {
255     return Ty->convertValue(this);
256   }
257
258   const std::string &getName() const { return VarName; }
259   RecTy *getType() const { return Ty; }
260
261   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
262   
263   virtual bool isComplete() const { return true; }
264   virtual void print(std::ostream &OS) const { OS << VarName; }
265 };
266
267 class VarBitInit : public Init {
268   VarInit *VI;
269   unsigned Bit;
270 public:
271   VarBitInit(VarInit *V, unsigned B) : VI(V), Bit(B) {}
272
273   virtual Init *convertInitializerTo(RecTy *Ty) {
274     return Ty->convertValue(this);
275   }
276
277   VarInit *getVariable() const { return VI; }
278   unsigned getBitNum() const { return Bit; }
279   
280   virtual bool isComplete() const { return true; }
281   virtual void print(std::ostream &OS) const {
282     VI->print(OS); OS << "{" << Bit << "}";
283   }
284   virtual Init *resolveReferences(Record &R);
285 };
286
287 class DefInit : public Init {
288   Record *Def;
289 public:
290   DefInit(Record *D) : Def(D) {}
291   
292   virtual Init *convertInitializerTo(RecTy *Ty) {
293     return Ty->convertValue(this);
294   }
295
296   Record *getDef() const { return Def; }
297
298   //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
299   
300   virtual bool isComplete() const { return true; }
301   virtual void print(std::ostream &OS) const;
302 };
303
304
305
306 //===----------------------------------------------------------------------===//
307 //  High-Level Classes
308 //===----------------------------------------------------------------------===//
309
310 class RecordVal {
311   std::string Name;
312   RecTy *Ty;
313   unsigned Prefix;
314   Init *Value;
315 public:
316   RecordVal(const std::string &N, RecTy *T, unsigned P);
317   ~RecordVal() { /*delete Ty; delete Value; Bad for copy ctor!*/ }
318
319   const std::string &getName() const { return Name; }
320
321   unsigned getPrefix() const { return Prefix; }
322   RecTy *getType() const { return Ty; }
323   Init *getValue() const { return Value; }
324
325   bool setValue(Init *V) {
326     if (V) {
327       Value = V->convertInitializerTo(Ty);
328       return Value == 0;
329     }
330     Value = 0;
331     return false;
332   }
333
334   void dump() const;
335   void print(std::ostream &OS, bool PrintSem = true) const;
336 };
337
338 inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) {
339   RV.print(OS << "  ");
340   return OS;
341 }
342
343 struct Record {
344   const std::string Name;
345   std::vector<std::string> TemplateArgs;
346   std::vector<RecordVal> Values;
347   std::vector<Record*> SuperClasses;
348 public:
349
350   Record(const std::string &N) : Name(N) {}
351   ~Record() {}
352
353   const std::string &getName() const { return Name; }
354   const std::vector<std::string> &getTemplateArgs() const {
355     return TemplateArgs;
356   }
357   const std::vector<RecordVal> &getValues() const { return Values; }
358   const std::vector<Record*>   &getSuperClasses() const { return SuperClasses; }
359
360   bool isTemplateArg(const std::string &Name) const {
361     for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
362       if (TemplateArgs[i] == Name) return true;
363     return false;
364   }
365
366   const RecordVal *getValue(const std::string &Name) const {
367     for (unsigned i = 0, e = Values.size(); i != e; ++i)
368       if (Values[i].getName() == Name) return &Values[i];
369     return 0;
370   }
371   RecordVal *getValue(const std::string &Name) {
372     for (unsigned i = 0, e = Values.size(); i != e; ++i)
373       if (Values[i].getName() == Name) return &Values[i];
374     return 0;
375   }
376
377   void addTemplateArg(const std::string &Name) {
378     assert(!isTemplateArg(Name) && "Template arg already defined!");
379     TemplateArgs.push_back(Name);
380   }
381
382   void addValue(const RecordVal &RV) {
383     assert(getValue(RV.getName()) == 0 && "Value already added!");
384     Values.push_back(RV);
385   }
386
387   bool isSubClassOf(Record *R) const {
388     for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
389       if (SuperClasses[i] == R)
390         return true;
391     return false;
392   }
393
394   void addSuperClass(Record *R) {
395     assert(!isSubClassOf(R) && "Already subclassing record!");
396     SuperClasses.push_back(R);
397   }
398
399   // resolveReferences - If there are any field references that refer to fields
400   // that have been filled in, we can propagate the values now.
401   //
402   void resolveReferences();
403
404   void dump() const;
405 };
406
407 std::ostream &operator<<(std::ostream &OS, const Record &R);
408
409 class RecordKeeper {
410   std::map<std::string, Record*> Classes, Defs;
411 public:
412   ~RecordKeeper() {
413     for (std::map<std::string, Record*>::iterator I = Classes.begin(),
414            E = Classes.end(); I != E; ++I)
415       delete I->second;
416     for (std::map<std::string, Record*>::iterator I = Defs.begin(),
417            E = Defs.end(); I != E; ++I)
418       delete I->second;
419   }
420   
421   const std::map<std::string, Record*> &getClasses() const { return Classes; }
422   const std::map<std::string, Record*> &getDefs() const { return Defs; }
423
424   Record *getClass(const std::string &Name) const {
425     std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
426     return I == Classes.end() ? 0 : I->second;
427   }
428   Record *getDef(const std::string &Name) const {
429     std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
430     return I == Defs.end() ? 0 : I->second;
431   }
432   void addClass(Record *R) {
433     assert(getClass(R->getName()) == 0 && "Class already exists!");
434     Classes.insert(std::make_pair(R->getName(), R));
435   }
436   void addDef(Record *R) {
437     assert(getDef(R->getName()) == 0 && "Def already exists!");
438     Defs.insert(std::make_pair(R->getName(), R));
439   }
440
441   void dump() const;
442 };
443
444 std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK);
445
446 extern RecordKeeper Records;
447
448 #endif