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