Add support for casting operators
[oota-llvm.git] / lib / VMCore / ConstantPool.cpp
1 //===-- iConstPool.cpp - Implement ConstPool instructions --------*- C++ -*--=//
2 //
3 // This file implements the ConstPool* classes...
4 //
5 //===----------------------------------------------------------------------===//
6
7 #define __STDC_LIMIT_MACROS           // Get defs for INT64_MAX and friends...
8 #include "llvm/ConstPoolVals.h"
9 #include "llvm/ConstantPool.h"
10 #include "llvm/Tools/StringExtras.h"  // itostr
11 #include "llvm/DerivedTypes.h"
12 #include "llvm/SymbolTable.h"
13 #include <algorithm>
14 #include <assert.h>
15
16 //===----------------------------------------------------------------------===//
17 //                             ConstantPool Class
18 //===----------------------------------------------------------------------===//
19
20 void ConstantPool::setParent(SymTabValue *STV) {
21   Parent = STV;
22   for (unsigned i = 0; i < Planes.size(); i++)
23     Planes[i]->setParent(Parent);  
24 }
25
26 const Value *ConstantPool::getParentV() const { return Parent->getSTVParent(); }
27 Value *ConstantPool::getParentV() { return Parent->getSTVParent(); }
28
29
30
31 // Constant getPlane - Returns true if the type plane does not exist, otherwise
32 // updates the pointer to point to the correct plane.
33 //
34 bool ConstantPool::getPlane(const Type *T, const PlaneType *&Plane) const {
35   unsigned Ty = T->getUniqueID();
36   if (Ty >= Planes.size()) return true;
37   Plane = Planes[Ty];
38   return false;
39 }
40
41 // Constant getPlane - Returns true if the type plane does not exist, otherwise
42 // updates the pointer to point to the correct plane.
43 //
44 bool ConstantPool::getPlane(const Type *T, PlaneType *&Plane) {
45   unsigned Ty = T->getUniqueID();
46   if (Ty >= Planes.size()) return true;
47   Plane = Planes[Ty];
48   return false;
49 }
50
51 void ConstantPool::resize(unsigned size) {
52   unsigned oldSize = Planes.size();
53   Planes.resize(size, 0);
54   while (oldSize < size)
55     Planes[oldSize++] = new PlaneType(Parent, Parent);
56 }
57
58 ConstantPool::PlaneType &ConstantPool::getPlane(const Type *T) {
59   unsigned Ty = T->getUniqueID();
60   if (Ty >= Planes.size()) resize(Ty+1);
61   return *Planes[Ty];
62 }
63
64 // insert - Add constant into the symbol table...
65 void ConstantPool::insert(ConstPoolVal *N) {
66   unsigned Ty = N->getType()->getUniqueID();
67   if (Ty >= Planes.size()) resize(Ty+1);
68   Planes[Ty]->push_back(N);
69 }
70
71 bool ConstantPool::remove(ConstPoolVal *N) {
72   unsigned Ty = N->getType()->getUniqueID();
73   if (Ty >= Planes.size()) return true;     // Doesn't contain any of that type
74
75   PlaneType::iterator I = ::find(Planes[Ty]->begin(), Planes[Ty]->end(), N);
76   if (I == Planes[Ty]->end()) return true;
77   Planes[Ty]->remove(I);
78   return false;
79 }
80
81 void ConstantPool::delete_all() {
82   dropAllReferences();
83   for (unsigned i = 0; i < Planes.size(); i++) {
84     Planes[i]->delete_all();
85     Planes[i]->setParent(0);
86     delete Planes[i];
87   }
88   Planes.clear();
89 }
90
91 void ConstantPool::dropAllReferences() {
92   for (unsigned i = 0; i < Planes.size(); i++)
93     for_each(Planes[i]->begin(), Planes[i]->end(),
94              mem_fun(&ConstPoolVal::dropAllReferences));
95 }
96
97 struct EqualsConstant {
98   const ConstPoolVal *v;
99   inline EqualsConstant(const ConstPoolVal *V) { v = V; }
100   inline bool operator()(const ConstPoolVal *V) const {
101     return v->equals(V);
102   }
103 };
104
105
106 ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) {
107   const PlaneType *P;
108   if (getPlane(V->getType(), P)) return 0;
109   PlaneType::const_iterator PI = find_if(P->begin(), P->end(), 
110                                          EqualsConstant(V));
111   if (PI == P->end()) return 0;
112   return *PI;
113 }
114
115 const ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) const {
116   const PlaneType *P;
117   if (getPlane(V->getType(), P)) return 0;
118   PlaneType::const_iterator PI = find_if(P->begin(), P->end(), 
119                                          EqualsConstant(V));
120   if (PI == P->end()) return 0;
121   return *PI;
122 }
123
124 ConstPoolVal *ConstantPool::find(const Type *Ty) {
125   const PlaneType *P;
126   if (getPlane(Type::TypeTy, P)) return 0;
127
128   // TODO: This is kinda silly
129   ConstPoolType V(Ty);
130
131   PlaneType::const_iterator PI = 
132     find_if(P->begin(), P->end(), EqualsConstant(&V));
133   if (PI == P->end()) return 0;
134   return *PI;
135 }
136
137 const ConstPoolVal *ConstantPool::find(const Type *Ty) const {
138   const PlaneType *P;
139   if (getPlane(Type::TypeTy, P)) return 0;
140
141   // TODO: This is kinda silly
142   ConstPoolType V(Ty);
143
144   PlaneType::const_iterator PI = 
145     find_if(P->begin(), P->end(), EqualsConstant(&V));
146   if (PI == P->end()) return 0;
147   return *PI;
148 }
149
150 struct EqualsType {
151   const Type *T;
152   inline EqualsType(const Type *t) { T = t; }
153   inline bool operator()(const ConstPoolVal *CPV) const {
154     return static_cast<const ConstPoolType*>(CPV)->getValue() == T;
155   }
156 };
157
158 // ensureTypeAvailable - This is used to make sure that the specified type is
159 // in the constant pool.  If it is not already in the constant pool, it is
160 // added.
161 //
162 const Type *ConstantPool::ensureTypeAvailable(const Type *Ty) {
163   // Get the type type plane...
164   PlaneType &P = getPlane(Type::TypeTy);
165   PlaneType::const_iterator PI = find_if(P.begin(), P.end(), EqualsType(Ty));
166                                          
167   if (PI == P.end()) {
168     ConstPoolVal *CPT = new ConstPoolType(Ty);
169     insert(CPT);
170   }
171   return Ty;
172 }
173
174 //===----------------------------------------------------------------------===//
175 //                              ConstPoolVal Class
176 //===----------------------------------------------------------------------===//
177
178 // Specialize setName to take care of symbol table majik
179 void ConstPoolVal::setName(const string &name) {
180   SymTabValue *P;
181   if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
182   Value::setName(name);
183   if (P && hasName()) P->getSymbolTable()->insert(this);
184 }
185
186 // Static constructor to create a '0' constant of arbitrary type...
187 ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
188   switch (Ty->getPrimitiveID()) {
189   case Type::BoolTyID:   return new ConstPoolBool(false);
190   case Type::SByteTyID:
191   case Type::ShortTyID:
192   case Type::IntTyID:
193   case Type::LongTyID:   return new ConstPoolSInt(Ty, 0);
194
195   case Type::UByteTyID:
196   case Type::UShortTyID:
197   case Type::UIntTyID:
198   case Type::ULongTyID:  return new ConstPoolUInt(Ty, 0);
199
200   case Type::FloatTyID:
201   case Type::DoubleTyID: return new ConstPoolFP(Ty, 0);
202   default:
203     return 0;
204   }
205 }
206
207
208
209 //===----------------------------------------------------------------------===//
210 //                            ConstPoolXXX Classes
211 //===----------------------------------------------------------------------===//
212
213 //===----------------------------------------------------------------------===//
214 //                             Normal Constructors
215
216 ConstPoolBool::ConstPoolBool(bool V, const string &Name = "") 
217   : ConstPoolVal(Type::BoolTy, Name) {
218   Val = V;
219 }
220
221 ConstPoolInt::ConstPoolInt(const Type *Ty, uint64_t V, const string &Name)
222   : ConstPoolVal(Ty, Name) { Val.Unsigned = V; }
223 ConstPoolInt::ConstPoolInt(const Type *Ty, int64_t V, const string &Name)
224   : ConstPoolVal(Ty, Name) { Val.Signed = V; }
225
226 ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V, const string &Name)
227   : ConstPoolInt(Ty, V, Name) {
228   //cerr << "value = " << (int)V << ": " << Ty->getName() << endl;
229   assert(isValueValidForType(Ty, V) && "Value too large for type!");
230 }
231
232 ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name)
233   : ConstPoolInt(Ty, V, Name) {
234   //cerr << "Uvalue = " << (int)V << ": " << Ty->getName() << endl;
235   assert(isValueValidForType(Ty, V) && "Value too large for type!");
236 }
237
238 ConstPoolFP::ConstPoolFP(const Type *Ty, double V, const string &Name)
239   : ConstPoolVal(Ty, Name) {
240   assert(isValueValidForType(Ty, V) && "Value too large for type!");
241   Val = V;
242 }
243
244 ConstPoolType::ConstPoolType(const Type *V, const string &Name) 
245   : ConstPoolVal(Type::TypeTy, Name), Val(V) {
246 }
247
248 ConstPoolArray::ConstPoolArray(const ArrayType *T, 
249                                vector<ConstPoolVal*> &V, 
250                                const string &Name)
251   : ConstPoolVal(T, Name) {
252   for (unsigned i = 0; i < V.size(); i++) {
253     assert(V[i]->getType() == T->getElementType());
254     Operands.push_back(Use(V[i], this));
255   }
256 }
257
258 ConstPoolStruct::ConstPoolStruct(const StructType *T, 
259                                  vector<ConstPoolVal*> &V, 
260                                  const string &Name)
261   : ConstPoolVal(T, Name) {
262   const StructType::ElementTypes &ETypes = T->getElementTypes();
263
264   for (unsigned i = 0; i < V.size(); i++) {
265     assert(V[i]->getType() == ETypes[i]);
266     Operands.push_back(Use(V[i], this));
267   }
268 }
269
270
271 //===----------------------------------------------------------------------===//
272 //                               Copy Constructors
273
274 ConstPoolBool::ConstPoolBool(const ConstPoolBool &CPB)
275   : ConstPoolVal(Type::BoolTy) {
276   Val = CPB.Val;
277 }
278
279 ConstPoolInt::ConstPoolInt(const ConstPoolInt &CPI)
280   : ConstPoolVal(CPI.getType()) {
281   Val.Signed = CPI.Val.Signed;
282 }
283
284 ConstPoolFP::ConstPoolFP(const ConstPoolFP &CPFP)
285   : ConstPoolVal(CPFP.getType()) {
286   Val = CPFP.Val;
287 }
288
289 ConstPoolType::ConstPoolType(const ConstPoolType &CPT) 
290   : ConstPoolVal(Type::TypeTy), Val(CPT.Val) {
291 }
292
293 ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
294   : ConstPoolVal(CPA.getType()) {
295   for (unsigned i = 0; i < CPA.Operands.size(); i++)
296     Operands.push_back(Use(CPA.Operands[i], this));
297 }
298
299 ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
300   : ConstPoolVal(CPS.getType()) {
301   for (unsigned i = 0; i < CPS.Operands.size(); i++)
302     Operands.push_back(Use(CPS.Operands[i], this));
303 }
304
305 //===----------------------------------------------------------------------===//
306 //                          getStrValue implementations
307
308 string ConstPoolBool::getStrValue() const {
309   return Val ? "true" : "false";
310 }
311
312 string ConstPoolSInt::getStrValue() const {
313   return itostr(Val.Signed);
314 }
315
316 string ConstPoolUInt::getStrValue() const {
317   return utostr(Val.Unsigned);
318 }
319
320 string ConstPoolFP::getStrValue() const {
321   return ftostr(Val);
322 }
323
324 string ConstPoolType::getStrValue() const {
325   return Val->getName();
326 }
327
328 string ConstPoolArray::getStrValue() const {
329   string Result = "[";
330   if (Operands.size()) {
331     Result += " " + Operands[0]->getType()->getName() + 
332               " " + Operands[0]->castConstantAsserting()->getStrValue();
333     for (unsigned i = 1; i < Operands.size(); i++)
334       Result += ", " + Operands[i]->getType()->getName() + 
335                  " " + Operands[i]->castConstantAsserting()->getStrValue();
336   }
337
338   return Result + " ]";
339 }
340
341 string ConstPoolStruct::getStrValue() const {
342   string Result = "{";
343   if (Operands.size()) {
344     Result += " " + Operands[0]->getType()->getName() + 
345               " " + Operands[0]->castConstantAsserting()->getStrValue();
346     for (unsigned i = 1; i < Operands.size(); i++)
347       Result += ", " + Operands[i]->getType()->getName() + 
348                  " " + Operands[i]->castConstantAsserting()->getStrValue();
349   }
350
351   return Result + " }";
352 }
353
354 //===----------------------------------------------------------------------===//
355 //                             equals implementations
356
357 bool ConstPoolBool::equals(const ConstPoolVal *V) const {
358   assert(getType() == V->getType());
359   return ((ConstPoolBool*)V)->getValue() == Val;
360 }
361
362 bool ConstPoolInt::equals(const ConstPoolVal *V) const {
363   assert(getType() == V->getType());
364   return ((ConstPoolInt*)V)->Val.Signed == Val.Signed;
365 }
366
367 bool ConstPoolFP::equals(const ConstPoolVal *V) const {
368   assert(getType() == V->getType());
369   return ((ConstPoolFP*)V)->getValue() == Val;
370 }
371
372 bool ConstPoolType::equals(const ConstPoolVal *V) const {
373   assert(getType() == V->getType());
374   return ((ConstPoolType*)V)->getValue() == Val;
375 }
376
377 bool ConstPoolArray::equals(const ConstPoolVal *V) const {
378   assert(getType() == V->getType());
379   ConstPoolArray *AV = (ConstPoolArray*)V;
380   if (Operands.size() != AV->Operands.size()) return false;
381   for (unsigned i = 0; i < Operands.size(); i++)
382     if (!Operands[i]->castConstantAsserting()->equals(
383                AV->Operands[i]->castConstantAsserting()))
384       return false;
385
386   return true;
387 }
388
389 bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
390   assert(getType() == V->getType());
391   ConstPoolStruct *SV = (ConstPoolStruct*)V;
392   if (Operands.size() != SV->Operands.size()) return false;
393   for (unsigned i = 0; i < Operands.size(); i++)
394     if (!Operands[i]->castConstantAsserting()->equals(
395            SV->Operands[i]->castConstantAsserting()))
396       return false;
397
398   return true;
399 }
400
401 //===----------------------------------------------------------------------===//
402 //                      isValueValidForType implementations
403
404 bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
405   switch (Ty->getPrimitiveID()) {
406   default:
407     return false;         // These can't be represented as integers!!!
408
409     // Signed types...
410   case Type::SByteTyID:
411     return (Val <= INT8_MAX && Val >= INT8_MIN);
412   case Type::ShortTyID:
413     return (Val <= INT16_MAX && Val >= INT16_MIN);
414   case Type::IntTyID:
415     return (Val <= INT32_MAX && Val >= INT32_MIN);
416   case Type::LongTyID:
417     return true;          // This is the largest type...
418   }
419   assert(0 && "WTF?");
420   return false;
421 }
422
423 bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
424   switch (Ty->getPrimitiveID()) {
425   default:
426     return false;         // These can't be represented as integers!!!
427
428     // Unsigned types...
429   case Type::UByteTyID:
430     return (Val <= UINT8_MAX);
431   case Type::UShortTyID:
432     return (Val <= UINT16_MAX);
433   case Type::UIntTyID:
434     return (Val <= UINT32_MAX);
435   case Type::ULongTyID:
436     return true;          // This is the largest type...
437   }
438   assert(0 && "WTF?");
439   return false;
440 }
441
442 bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
443   switch (Ty->getPrimitiveID()) {
444   default:
445     return false;         // These can't be represented as floating point!
446
447     // TODO: Figure out how to test if a double can be cast to a float!
448   case Type::FloatTyID:
449     /*
450     return (Val <= UINT8_MAX);
451     */
452   case Type::DoubleTyID:
453     return true;          // This is the largest type...
454   }
455 };
456
457
458 //===----------------------------------------------------------------------===//
459 //                      Extra Method implementations
460
461 ConstPoolInt *ConstPoolInt::get(const Type *Ty, unsigned char V) {
462   assert(V <= 127 && "equals: Can only be used with very small constants!");
463   if (Ty->isSigned()) return new ConstPoolSInt(Ty, V);
464   return new ConstPoolUInt(Ty, V);
465 }