Add comments
[oota-llvm.git] / utils / 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
52 /// BitRecTy - 'bit' - Represent a single bit
53 ///
54 struct BitRecTy : public RecTy {
55   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
56   Init *convertValue(BitInit *BI) { return (Init*)BI; }
57   Init *convertValue(BitsInit *BI);
58   Init *convertValue(IntInit *II);
59   Init *convertValue(VarInit *VI);
60
61   void print(std::ostream &OS) const { OS << "bit"; }
62 };
63
64
65 /// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
66 ///
67 class BitsRecTy : public RecTy {
68   unsigned Size;
69 public:
70   BitsRecTy(unsigned Sz) : Size(Sz) {}
71
72   unsigned getNumBits() const { return Size; }
73
74   Init *convertValue(UnsetInit *UI);
75   Init *convertValue(BitInit *UI);
76   Init *convertValue(BitsInit *BI);
77   Init *convertValue(IntInit *II);
78   Init *convertValue(VarInit *VI);
79
80   void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
81 };
82
83
84 /// IntRecTy - 'int' - Represent an integer value of no particular size
85 ///
86 struct IntRecTy : public RecTy {
87   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
88   Init *convertValue(IntInit *II) { return (Init*)II; }
89   Init *convertValue(BitsInit *BI);
90   Init *convertValue(VarInit *VI);
91
92   void print(std::ostream &OS) const { OS << "int"; }
93 };
94
95 /// StringRecTy - 'string' - Represent an string value
96 ///
97 struct StringRecTy : public RecTy {
98   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
99   Init *convertValue(StringInit *SI) { return (Init*)SI; }
100   Init *convertValue(VarInit *VI);
101   void print(std::ostream &OS) const { OS << "string"; }
102 };
103
104 /// ListRecTy - 'list<class>' - Represent a list defs, all of which must be
105 /// derived from the specified class.
106 ///
107 class ListRecTy : public RecTy {
108   Record *Class;
109 public:
110   ListRecTy(Record *C) : Class(C) {}
111   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
112   Init *convertValue(ListInit *LI);
113   
114   void print(std::ostream &OS) const;
115 };
116
117 /// RecordRecTy - '<classname>' - Represent an instance of a class, such as:
118 /// (R32 X = EAX).
119 ///
120 class RecordRecTy : public RecTy {
121   Record *Rec;
122 public:
123   RecordRecTy(Record *R) : Rec(R) {}
124
125   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
126   Init *convertValue(   DefInit *DI);
127
128   void print(std::ostream &OS) const;
129 };
130
131
132
133 //===----------------------------------------------------------------------===//
134 //  Initializer Classes
135 //===----------------------------------------------------------------------===//
136
137 struct Init {
138   virtual ~Init() {}
139
140   virtual bool isComplete() const = 0;
141   virtual void print(std::ostream &OS) const = 0;
142   void dump() const;
143
144   virtual Init *convertInitializerTo(RecTy *Ty) = 0;
145   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits) {
146     return 0;
147   }
148
149   virtual Init *resolveReferences(Record &R) { return this; }
150 };
151
152 inline std::ostream &operator<<(std::ostream &OS, const Init &I) {
153   I.print(OS); return OS;
154 }
155
156
157 /// UnsetInit - ? - Represents an uninitialized value
158 ///
159 struct UnsetInit : public Init {
160   virtual Init *convertInitializerTo(RecTy *Ty) {
161     return Ty->convertValue(this);
162   }
163
164   virtual bool isComplete() const { return false; }
165   virtual void print(std::ostream &OS) const { OS << "?"; }
166 };
167
168
169 /// BitInit - true/false - Represent a concrete initializer for a bit.
170 ///
171 class BitInit : public Init {
172   bool Value;
173 public:
174   BitInit(bool V) : Value(V) {}
175
176   bool getValue() const { return Value; }
177
178   virtual Init *convertInitializerTo(RecTy *Ty) {
179     return Ty->convertValue(this);
180   }
181
182   virtual bool isComplete() const { return true; }
183   virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); }
184 };
185
186 /// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
187 /// It contains a vector of bits, whose size is determined by the type.
188 ///
189 class BitsInit : public Init {
190   std::vector<Init*> Bits;
191 public:
192   BitsInit(unsigned Size) : Bits(Size) {}
193
194   unsigned getNumBits() const { return Bits.size(); }
195
196   Init *getBit(unsigned Bit) const {
197     assert(Bit < Bits.size() && "Bit index out of range!");
198     return Bits[Bit];
199   }
200   void setBit(unsigned Bit, Init *V) {
201     assert(Bit < Bits.size() && "Bit index out of range!");
202     Bits[Bit] = V;
203   }
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 {
211     for (unsigned i = 0; i != getNumBits(); ++i)
212       if (!getBit(i)->isComplete()) return false;
213     return true;
214   }
215   virtual void print(std::ostream &OS) const;
216
217   virtual Init *resolveReferences(Record &R);
218
219   // printXX - Print this bitstream with the specified format, returning true if
220   // it is not possible.
221   bool printInHex(std::ostream &OS) const;
222   bool printAsVariable(std::ostream &OS) const;
223   bool printAsUnset(std::ostream &OS) const;
224 };
225
226
227 /// IntInit - 7 - Represent an initalization by a literal integer value.
228 ///
229 class IntInit : public Init {
230   int Value;
231 public:
232   IntInit(int V) : Value(V) {}
233
234   int getValue() const { return Value; }
235
236   virtual Init *convertInitializerTo(RecTy *Ty) {
237     return Ty->convertValue(this);
238   }
239   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
240
241   virtual bool isComplete() const { return true; }
242   virtual void print(std::ostream &OS) const { OS << Value; }
243 };
244
245
246 /// StringInit - "foo" - Represent an initialization by a string value.
247 ///
248 class StringInit : public Init {
249   std::string Value;
250 public:
251   StringInit(const std::string &V) : Value(V) {}
252
253   virtual Init *convertInitializerTo(RecTy *Ty) {
254     return Ty->convertValue(this);
255   }
256
257   virtual bool isComplete() const { return true; }
258   virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; }
259 };
260
261 /// ListInit - [AL, AH, CL] - Represent a list of defs
262 ///
263 class ListInit : public Init {
264   std::vector<Record*> Records;
265 public:
266   ListInit(std::vector<Record*> &Rs) {
267     Records.swap(Rs);
268   }
269
270   unsigned getSize() const { return Records.size(); }
271   Record  *getElement(unsigned i) const {
272     assert(i < Records.size() && "List element index out of range!");
273     return Records[i];
274   }
275
276   virtual Init *convertInitializerTo(RecTy *Ty) {
277     return Ty->convertValue(this);
278   }
279
280   virtual bool isComplete() const { return true; }
281   virtual void print(std::ostream &OS) const;
282 };
283
284 /// VarInit - 'Opcode' - Represent a reference to an entire variable object.
285 ///
286 class VarInit : public Init {
287   std::string VarName;
288   RecTy *Ty;
289 public:
290   VarInit(const std::string &VN, RecTy *T) : VarName(VN), Ty(T) {}
291   
292   virtual Init *convertInitializerTo(RecTy *Ty) {
293     return Ty->convertValue(this);
294   }
295
296   const std::string &getName() const { return VarName; }
297   RecTy *getType() const { return Ty; }
298
299   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
300   
301   virtual bool isComplete() const { return true; }
302   virtual void print(std::ostream &OS) const { OS << VarName; }
303 };
304
305
306 /// VarBitInit - Opcode{0} - Represent access to one bit of a variable
307 ///
308 class VarBitInit : public Init {
309   VarInit *VI;
310   unsigned Bit;
311 public:
312   VarBitInit(VarInit *V, unsigned B) : VI(V), Bit(B) {}
313
314   virtual Init *convertInitializerTo(RecTy *Ty) {
315     return Ty->convertValue(this);
316   }
317
318   VarInit *getVariable() const { return VI; }
319   unsigned getBitNum() const { return Bit; }
320   
321   virtual bool isComplete() const { return true; }
322   virtual void print(std::ostream &OS) const {
323     VI->print(OS); OS << "{" << Bit << "}";
324   }
325   virtual Init *resolveReferences(Record &R);
326 };
327
328
329 /// DefInit - AL - Represent a reference to a 'def' in the description
330 ///
331 class DefInit : public Init {
332   Record *Def;
333 public:
334   DefInit(Record *D) : Def(D) {}
335   
336   virtual Init *convertInitializerTo(RecTy *Ty) {
337     return Ty->convertValue(this);
338   }
339
340   Record *getDef() const { return Def; }
341
342   //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
343   
344   virtual bool isComplete() const { return true; }
345   virtual void print(std::ostream &OS) const;
346 };
347
348
349
350 //===----------------------------------------------------------------------===//
351 //  High-Level Classes
352 //===----------------------------------------------------------------------===//
353
354 class RecordVal {
355   std::string Name;
356   RecTy *Ty;
357   unsigned Prefix;
358   Init *Value;
359 public:
360   RecordVal(const std::string &N, RecTy *T, unsigned P);
361   ~RecordVal() { /*delete Ty; delete Value; Bad for copy ctor!*/ }
362
363   const std::string &getName() const { return Name; }
364
365   unsigned getPrefix() const { return Prefix; }
366   RecTy *getType() const { return Ty; }
367   Init *getValue() const { return Value; }
368
369   bool setValue(Init *V) {
370     if (V) {
371       Value = V->convertInitializerTo(Ty);
372       return Value == 0;
373     }
374     Value = 0;
375     return false;
376   }
377
378   void dump() const;
379   void print(std::ostream &OS, bool PrintSem = true) const;
380 };
381
382 inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) {
383   RV.print(OS << "  ");
384   return OS;
385 }
386
387 struct Record {
388   const std::string Name;
389   std::vector<std::string> TemplateArgs;
390   std::vector<RecordVal> Values;
391   std::vector<Record*> SuperClasses;
392 public:
393
394   Record(const std::string &N) : Name(N) {}
395   ~Record() {}
396
397   const std::string &getName() const { return Name; }
398   const std::vector<std::string> &getTemplateArgs() const {
399     return TemplateArgs;
400   }
401   const std::vector<RecordVal> &getValues() const { return Values; }
402   const std::vector<Record*>   &getSuperClasses() const { return SuperClasses; }
403
404   bool isTemplateArg(const std::string &Name) const {
405     for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
406       if (TemplateArgs[i] == Name) return true;
407     return false;
408   }
409
410   const RecordVal *getValue(const std::string &Name) const {
411     for (unsigned i = 0, e = Values.size(); i != e; ++i)
412       if (Values[i].getName() == Name) return &Values[i];
413     return 0;
414   }
415   RecordVal *getValue(const std::string &Name) {
416     for (unsigned i = 0, e = Values.size(); i != e; ++i)
417       if (Values[i].getName() == Name) return &Values[i];
418     return 0;
419   }
420
421   void addTemplateArg(const std::string &Name) {
422     assert(!isTemplateArg(Name) && "Template arg already defined!");
423     TemplateArgs.push_back(Name);
424   }
425
426   void addValue(const RecordVal &RV) {
427     assert(getValue(RV.getName()) == 0 && "Value already added!");
428     Values.push_back(RV);
429   }
430
431   bool isSubClassOf(Record *R) const {
432     for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
433       if (SuperClasses[i] == R)
434         return true;
435     return false;
436   }
437
438   void addSuperClass(Record *R) {
439     assert(!isSubClassOf(R) && "Already subclassing record!");
440     SuperClasses.push_back(R);
441   }
442
443   // resolveReferences - If there are any field references that refer to fields
444   // that have been filled in, we can propagate the values now.
445   //
446   void resolveReferences();
447
448   void dump() const;
449 };
450
451 std::ostream &operator<<(std::ostream &OS, const Record &R);
452
453 class RecordKeeper {
454   std::map<std::string, Record*> Classes, Defs;
455 public:
456   ~RecordKeeper() {
457     for (std::map<std::string, Record*>::iterator I = Classes.begin(),
458            E = Classes.end(); I != E; ++I)
459       delete I->second;
460     for (std::map<std::string, Record*>::iterator I = Defs.begin(),
461            E = Defs.end(); I != E; ++I)
462       delete I->second;
463   }
464   
465   const std::map<std::string, Record*> &getClasses() const { return Classes; }
466   const std::map<std::string, Record*> &getDefs() const { return Defs; }
467
468   Record *getClass(const std::string &Name) const {
469     std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
470     return I == Classes.end() ? 0 : I->second;
471   }
472   Record *getDef(const std::string &Name) const {
473     std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
474     return I == Defs.end() ? 0 : I->second;
475   }
476   void addClass(Record *R) {
477     assert(getClass(R->getName()) == 0 && "Class already exists!");
478     Classes.insert(std::make_pair(R->getName(), R));
479   }
480   void addDef(Record *R) {
481     assert(getDef(R->getName()) == 0 && "Def already exists!");
482     Defs.insert(std::make_pair(R->getName(), R));
483   }
484
485   void dump() const;
486 };
487
488 std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK);
489
490 extern RecordKeeper Records;
491
492 #endif