Allow printing partially constructed bitsets
[oota-llvm.git] / support / tools / TableGen / Record.cpp
1 //===- Record.cpp - Record implementation ---------------------------------===//
2 //
3 //
4 //===----------------------------------------------------------------------===//
5
6 #include "Record.h"
7
8 //===----------------------------------------------------------------------===//
9 //    Type implementations
10 //===----------------------------------------------------------------------===//
11
12 void RecTy::dump() const { print(std::cerr); }
13
14 Init *BitRecTy::convertValue(BitsInit *BI) {
15   if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
16   return BI->getBit(0);
17 }
18
19 Init *BitRecTy::convertValue(IntInit *II) {
20   int Val = II->getValue();
21   if (Val != 0 && Val != 1) return 0;  // Only accept 0 or 1 for a bit!
22   
23   return new BitInit(Val != 0); 
24 }
25
26 Init *BitRecTy::convertValue(TypedInit *VI) {
27   if (dynamic_cast<BitRecTy*>(VI->getType()))
28     return VI;  // Accept variable if it is already of bit type!
29   return 0;
30 }
31
32 Init *BitsRecTy::convertValue(UnsetInit *UI) {
33   BitsInit *Ret = new BitsInit(Size);
34
35   for (unsigned i = 0; i != Size; ++i)
36     Ret->setBit(i, new UnsetInit());
37   return Ret;
38 }
39
40 Init *BitsRecTy::convertValue(BitInit *UI) {
41   if (Size != 1) return 0;  // Can only convert single bit...
42   BitsInit *Ret = new BitsInit(1);
43   Ret->setBit(0, UI);
44   return Ret;
45 }
46
47 // convertValue from Int initializer to bits type: Split the integer up into the
48 // appropriate bits...
49 //
50 Init *BitsRecTy::convertValue(IntInit *II) {
51   int Value = II->getValue();
52
53   BitsInit *Ret = new BitsInit(Size);
54   for (unsigned i = 0; i != Size; ++i)
55     Ret->setBit(i, new BitInit(Value & (1 << i)));
56   return Ret;
57 }
58
59 Init *BitsRecTy::convertValue(BitsInit *BI) {
60   // If the number of bits is right, return it.  Otherwise we need to expand or
61   // truncate...
62   if (BI->getNumBits() == Size) return BI;
63   return 0;
64 }
65
66 Init *BitsRecTy::convertValue(TypedInit *VI) {
67   if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
68     if (BRT->Size == Size) {
69       BitsInit *Ret = new BitsInit(Size);
70       for (unsigned i = 0; i != Size; ++i)
71         Ret->setBit(i, new VarBitInit(VI, i));
72       return Ret;
73     }
74   if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
75     BitsInit *Ret = new BitsInit(1);
76     Ret->setBit(0, VI);
77     return Ret;
78   }
79       
80   return 0;
81 }
82
83 Init *IntRecTy::convertValue(BitsInit *BI) {
84   int Result = 0;
85   for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 
86     if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
87       Result |= Bit->getValue() << i;
88     } else {
89       return 0;
90     }
91   return new IntInit(Result);
92 }
93
94 Init *IntRecTy::convertValue(TypedInit *TI) {
95   if (dynamic_cast<IntRecTy*>(TI->getType()))
96     return TI;  // Accept variable if already of the right type!
97   return 0;
98 }
99
100 Init *StringRecTy::convertValue(TypedInit *TI) {
101   if (dynamic_cast<StringRecTy*>(TI->getType()))
102     return TI;  // Accept variable if already of the right type!
103   return 0;
104 }
105
106 void ListRecTy::print(std::ostream &OS) const {
107   OS << "list<" << Class->getName() << ">";
108 }
109
110 Init *ListRecTy::convertValue(ListInit *LI) {
111   // Verify that all of the elements of the list are subclasses of the
112   // appopriate class!
113   for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
114     if (!LI->getElement(i)->isSubClassOf(Class))
115       return 0;
116   return LI;
117 }
118
119 void RecordRecTy::print(std::ostream &OS) const {
120   OS << Rec->getName();
121 }
122
123 Init *RecordRecTy::convertValue(DefInit *DI) {
124   // Ensure that DI is a subclass of Rec.
125   if (!DI->getDef()->isSubClassOf(Rec))
126     return 0;
127   return DI;
128 }
129
130 //===----------------------------------------------------------------------===//
131 //    Initializer implementations
132 //===----------------------------------------------------------------------===//
133
134 void Init::dump() const { return print(std::cerr); }
135
136 Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
137   BitsInit *BI = new BitsInit(Bits.size());
138   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
139     if (Bits[i] >= getNumBits()) {
140       delete BI;
141       return 0;
142     }
143     BI->setBit(i, getBit(Bits[i]));
144   }
145   return BI;
146 }
147
148 void BitsInit::print(std::ostream &OS) const {
149   //if (!printInHex(OS)) return;
150   //if (!printAsVariable(OS)) return;
151   //if (!printAsUnset(OS)) return;
152
153   OS << "{ ";
154   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
155     if (i) OS << ", ";
156     if (Init *Bit = getBit(e-i-1))
157       Bit->print(OS);
158     else
159       OS << "*";
160   }
161   OS << " }";
162 }
163
164 bool BitsInit::printInHex(std::ostream &OS) const {
165   // First, attempt to convert the value into an integer value...
166   int Result = 0;
167   for (unsigned i = 0, e = getNumBits(); i != e; ++i) 
168     if (BitInit *Bit = dynamic_cast<BitInit*>(getBit(i))) {
169       Result |= Bit->getValue() << i;
170     } else {
171       return true;
172     }
173
174   OS << "0x" << std::hex << Result << std::dec;
175   return false;
176 }
177
178 bool BitsInit::printAsVariable(std::ostream &OS) const {
179   // Get the variable that we may be set equal to...
180   assert(getNumBits() != 0);
181   VarBitInit *FirstBit = dynamic_cast<VarBitInit*>(getBit(0));
182   if (FirstBit == 0) return true;
183   TypedInit *Var = FirstBit->getVariable();
184
185   // Check to make sure the types are compatible.
186   BitsRecTy *Ty = dynamic_cast<BitsRecTy*>(FirstBit->getVariable()->getType());
187   if (Ty == 0) return true;
188   if (Ty->getNumBits() != getNumBits()) return true; // Incompatible types!
189
190   // Check to make sure all bits are referring to the right bits in the variable
191   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
192     VarBitInit *Bit = dynamic_cast<VarBitInit*>(getBit(i));
193     if (Bit == 0 || Bit->getVariable() != Var || Bit->getBitNum() != i)
194       return true;
195   }
196
197   Var->print(OS);
198   return false;
199 }
200
201 bool BitsInit::printAsUnset(std::ostream &OS) const {
202   for (unsigned i = 0, e = getNumBits(); i != e; ++i) 
203     if (!dynamic_cast<UnsetInit*>(getBit(i)))
204       return true;
205   OS << "?";
206   return false;
207 }
208
209 Init *BitsInit::resolveReferences(Record &R) {
210   bool Changed = false;
211   BitsInit *New = new BitsInit(getNumBits());
212
213   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
214     Init *B;
215     Init *CurBit = getBit(i);
216
217     do {
218       B = CurBit;
219       CurBit = CurBit->resolveReferences(R);
220       Changed |= B != CurBit;
221     } while (B != CurBit);
222     New->setBit(i, CurBit);
223   }
224
225   if (Changed)
226     return New;
227   delete New;
228   return this;
229 }
230
231 Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
232   BitsInit *BI = new BitsInit(Bits.size());
233
234   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
235     if (Bits[i] >= 32) {
236       delete BI;
237       return 0;
238     }
239     BI->setBit(i, new BitInit(Value & (1 << Bits[i])));
240   }
241   return BI;
242 }
243
244 void ListInit::print(std::ostream &OS) const {
245   OS << "[";
246   for (unsigned i = 0, e = Records.size(); i != e; ++i) {
247     if (i) OS << ", ";
248     OS << Records[i]->getName();
249   }
250   OS << "]";
251 }
252
253 Init *VarInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
254   BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
255   if (T == 0) return 0;  // Cannot subscript a non-bits variable...
256   unsigned NumBits = T->getNumBits();
257
258   BitsInit *BI = new BitsInit(Bits.size());
259   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
260     if (Bits[i] >= NumBits) {
261       delete BI;
262       return 0;
263     }
264     BI->setBit(i, new VarBitInit(this, Bits[i]));
265   }
266   return BI;
267 }
268
269 Init *VarInit::resolveBitReference(Record &R, unsigned Bit) {
270   if (R.isTemplateArg(getName()))
271     return this;
272
273   RecordVal *RV = R.getValue(getName());
274   assert(RV && "Reference to a non-existant variable?");
275   assert(dynamic_cast<BitsInit*>(RV->getValue()));
276   BitsInit *BI = (BitsInit*)RV->getValue();
277   
278   assert(Bit < BI->getNumBits() && "Bit reference out of range!");
279   Init *B = BI->getBit(Bit);
280
281   if (!dynamic_cast<UnsetInit*>(B))  // If the bit is not set...
282     return B;                        // Replace the VarBitInit with it.
283   return this;
284 }
285
286 RecTy *VarInit::getFieldType(const std::string &FieldName) const {
287   if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
288     if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
289       return RV->getType();
290   return 0;
291 }
292
293 Init *VarInit::getFieldInit(Record &R, const std::string &FieldName) const {
294   if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
295     if (const RecordVal *RV = R.getValue(VarName))
296       if (Init *I = RV->getValue()->getFieldInit(R, FieldName))
297         return I;
298       else
299         return (Init*)this;
300   return 0;
301 }
302
303
304
305 Init *VarBitInit::resolveReferences(Record &R) {
306   Init *I = getVariable()->resolveBitReference(R, getBitNum());
307   if (I != getVariable())
308     return I;
309   return this;
310 }
311
312 RecTy *DefInit::getFieldType(const std::string &FieldName) const {
313   if (const RecordVal *RV = Def->getValue(FieldName))
314     return RV->getType();
315   return 0;
316 }
317
318 Init *DefInit::getFieldInit(Record &R, const std::string &FieldName) const {
319   return Def->getValue(FieldName)->getValue();
320 }
321
322
323 void DefInit::print(std::ostream &OS) const {
324   OS << Def->getName();
325 }
326
327 Init *FieldInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
328   BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
329   if (T == 0) return 0;  // Cannot subscript a non-bits field...
330   unsigned NumBits = T->getNumBits();
331
332   BitsInit *BI = new BitsInit(Bits.size());
333   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
334     if (Bits[i] >= NumBits) {
335       delete BI;
336       return 0;
337     }
338     BI->setBit(i, new VarBitInit(this, Bits[i]));
339   }
340   return BI;
341 }
342
343 Init *FieldInit::resolveBitReference(Record &R, unsigned Bit) {
344   Init *BitsVal = Rec->getFieldInit(R, FieldName);
345   assert(BitsVal && "No initializer found!");
346
347   if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
348     assert(Bit < BI->getNumBits() && "Bit reference out of range!");
349     Init *B = BI->getBit(Bit);
350     
351     if (dynamic_cast<BitInit*>(B))  // If the bit is set...
352       return B;                     // Replace the VarBitInit with it.
353   }
354   return this;
355 }
356
357
358 //===----------------------------------------------------------------------===//
359 //    Other implementations
360 //===----------------------------------------------------------------------===//
361
362 RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
363   : Name(N), Ty(T), Prefix(P) {
364   Value = Ty->convertValue(new UnsetInit());
365   assert(Value && "Cannot create unset value for current type!");
366 }
367
368 void RecordVal::dump() const { std::cerr << *this; }
369
370 void RecordVal::print(std::ostream &OS, bool PrintSem) const {
371   if (getPrefix()) OS << "field ";
372   OS << *getType() << " " << getName();
373   if (getValue()) {
374     OS << " = " << *getValue();
375   }
376   if (PrintSem) OS << ";\n";
377 }
378
379 // resolveReferences - If there are any field references that refer to fields
380 // that have been filled in, we can propagate the values now.
381 //
382 void Record::resolveReferences() {
383   for (unsigned i = 0, e = Values.size(); i != e; ++i)
384     Values[i].setValue(Values[i].getValue()->resolveReferences(*this));
385 }
386
387 void Record::dump() const { std::cerr << *this; }
388
389 std::ostream &operator<<(std::ostream &OS, const Record &R) {
390   OS << R.getName();
391
392   const std::vector<std::string> &TArgs = R.getTemplateArgs();
393   if (!TArgs.empty()) {
394     OS << "<";
395     for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
396       if (i) OS << ", ";
397       const RecordVal *RV = R.getValue(TArgs[i]);
398       assert(RV && "Template argument record not found??");
399       RV->print(OS, false);
400     }
401     OS << ">";
402   }
403
404   OS << " {";
405   const std::vector<Record*> &SC = R.getSuperClasses();
406   if (!SC.empty()) {
407     OS << "\t//";
408     for (unsigned i = 0, e = SC.size(); i != e; ++i)
409       OS << " " << SC[i]->getName();
410   }
411   OS << "\n";
412
413   const std::vector<RecordVal> &Vals = R.getValues();
414   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
415     if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
416       OS << Vals[i];
417   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
418     if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
419       OS << Vals[i];
420
421   return OS << "}\n";
422 }
423
424 void RecordKeeper::dump() const { std::cerr << *this; }
425
426 std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK) {
427   OS << "------------- Classes -----------------\n";
428   const std::map<std::string, Record*> &Classes = RK.getClasses();
429   for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
430          E = Classes.end(); I != E; ++I)
431     OS << "class " << *I->second;
432   
433   OS << "------------- Defs -----------------\n";
434   const std::map<std::string, Record*> &Defs = RK.getDefs();
435   for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
436          E = Defs.end(); I != E; ++I)
437     OS << "def " << *I->second;
438   return OS;
439 }