1 #ifndef TYPE_INFO_H
2 #define TYPE_INFO_H
3 
4 #include <magic/magic.h>
5 #include <magic_common.h>
6 #include <magic/support/SmartType.h>
7 #include <magic/support/TypeUtil.h>
8 
9 using namespace llvm;
10 
11 #define TypeInfoErr(M) errs() << "TypeInfo: " << M << "\n"
12 
13 #define FUNCTIONS_USE_HASH_TYPE_STRINGS 1
14 #define ROOT_TYPES_HAVE_TYPE_STRINGS    0
15 #define DEBUG_CAST_LOOKUPS              0
16 
17 #define TYPEINFO_PERSISTENT             0x01
18 
19 namespace llvm {
20 
21 class TypeInfo {
22   public:
23       TypeInfo(const SmartType *aSmartType, int persistent=0);
24       TypeInfo(TYPECONST FunctionType *FT, int persistent=0);
25       TypeInfo(TYPECONST PointerType *PT, int persistent=0);
26       TypeInfo(TYPECONST ArrayType *AT, int persistent=0);
27       TypeInfo(TYPECONST IntegerType *IT, int persistent=0);
28       TypeInfo(TYPECONST StructType *OpaqueST, int persistent=0);
29       void init(int persistent);
30 
31       const SmartType *getSmartType() const;
32       TYPECONST Type *getType() const;
33       unsigned getNumContainedTypes() const;
34       unsigned getNumChildTypes() const;
35       TypeInfo *getContainedType(unsigned i) const;
36       std::vector<GlobalValue*> getParents() const;
37       std::string getTypeString() const;
38       std::string getDescription() const;
39       std::string getVerboseDescription() const;
40       std::string getName() const;
41       std::vector<std::string> getNames() const;
42       std::string getNamesString() const;
43       std::vector<std::string> getMemberNames() const;
44       std::vector<int> getValueSet() const;
45       std::vector<TypeInfo*> getCastTypes() const;
46       unsigned getTypeID() const;
47       unsigned getFlags() const;
48       unsigned getBitWidth() const;
49       bool equals(TYPECONST TypeInfo *other) const;
50       bool hasRawTypeRepresentation() const;
51 
52       std::string formatMemberName(const std::string &memberName, unsigned &numAnonMembers);
53       void setValueSet(const std::vector<int> &valueSet);
54       void setContainedTypes(const std::vector<TypeInfo*> &containedTypes);
55       void addParent(GlobalValue* parent);
56       void addParents(const std::vector<GlobalValue*> &parents);
57       bool removeParent(GlobalValue* parent);
58       bool removeAllParents();
59       void setPersistent();
60       bool splitByParentValueSet(std::vector<TypeInfo*> &splitTypeInfos, std::set<GlobalVariable*> &globalVariablesWithAddressTaken);
61 
62       static unsigned getMaxNameLength();
63       static unsigned getMaxTypeStringLength();
64       static void setIntCastTypes(std::map<TYPECONST Type*, std::set<int> > &intCastTypes);
65       static void setBitCastTypes(std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastTypes);
66 
67   private:
68       const SmartType *aSmartType;
69       TYPECONST Type *aType;
70       bool forceTypeDescription;
71       mutable std::string typeDescription;
72       std::string name;
73       std::vector<std::string> names;
74       std::vector<std::string> memberNames;
75       std::vector<int> valueSet;
76       std::vector<TypeInfo*> containedTypes;
77       std::vector<GlobalValue*> parents;
78       unsigned bitWidth;
79       unsigned typeID;
80       unsigned numElements;
81       unsigned flags;
82       static unsigned maxNameLength;
83       static unsigned maxTypeStringLength;
84       static std::map<TYPECONST Type*, std::set<int> > intCastTypes;
85       static std::map<TYPECONST Type*, std::set<TYPECONST Type*> > bitCastTypes;
86       static std::map<TYPECONST Type*, std::set<TypeInfo*> > typeMap;
87 
88       TypeInfo() {}
89 };
90 
91 inline TypeInfo::TypeInfo(const SmartType *aSmartType, int persistent) {
92     unsigned i;
93     assert(aSmartType);
94     this->aSmartType = aSmartType;
95     this->aType = aSmartType->getType();
96     bool rawTypeRepresentation = aSmartType->hasRawTypeRepresentation();
97     forceTypeDescription = aSmartType->isFunctionTy();
98     name = aSmartType->getEDIType()->getName();
99     std::vector<StringRef> nameRefs = aSmartType->getEDIType()->getNames();
100     for(i=0;i<nameRefs.size();i++) {
101         if(nameRefs[i].size() > maxNameLength) {
102             maxNameLength = nameRefs[i].size();
103         }
104         names.push_back(nameRefs[i]);
105     }
106     if(aSmartType->isStructTy()) {
107         if(!rawTypeRepresentation) {
108             const EDIType* aEDIType = aSmartType->getEDIType();
109             unsigned numContainedTypes = aSmartType->getNumContainedTypes();
110             unsigned numAnonMembers = 0;
111             if(aEDIType->isUnionTy()) {
112                 assert(numContainedTypes == 1);
113                 i=aSmartType->getUnionMemberIdx();
114                 const DIDerivedType subDIType = aSmartType->getMember(i);
115                 memberNames.push_back(formatMemberName(subDIType.getName(), numAnonMembers));
116             }
117             else {
118                 assert(aEDIType->isStructTy());
119                 i=0;
120                 for(;i<numContainedTypes;i++) {
121                     const DIDerivedType subDIType = aSmartType->getMember(i);
122                     memberNames.push_back(formatMemberName(subDIType.getName(), numAnonMembers));
123                 }
124             }
125         }
126         else {
127             memberNames.push_back("raw");
128         }
129     }
130     if(aSmartType->getEDIType()->isEnumTy()) {
131         std::vector<unsigned> enumValues = aSmartType->getEDIType()->getEnumValues();
132         valueSet.push_back(enumValues.size()); //push length as the first value
133         for(unsigned i=0;i<enumValues.size();i++) {
134             valueSet.push_back((int)enumValues[i]);
135         }
136     }
137     bitWidth = TypeUtil::typeToBits(aSmartType->getType());
138     const EDIType *aEDIType = aSmartType->getEDIType();
139     typeID = 0;
140     flags = 0;
141     if(aSmartType->isOpaqueTy()) {
142         typeID = MAGIC_TYPE_OPAQUE;
143     }
144     else if(aEDIType->isVoidTy()) {
145         typeID = MAGIC_TYPE_VOID;
146     }
147     else if(aSmartType->isFunctionTy()) {
148         typeID = MAGIC_TYPE_FUNCTION;
149     }
150     else if(aSmartType->isStructTy()) {
151         if(aEDIType->isUnionTy()) {
152             typeID = MAGIC_TYPE_UNION;
153         }
154         else if(aEDIType->isStructTy()) {
155             typeID = MAGIC_TYPE_STRUCT;
156 #if MAGIC_VARSIZED_STRUCTS_SUPPORT
157             if(!rawTypeRepresentation) {
158                 assert(this->aType->getNumContainedTypes() > 0);
159                 TYPECONST Type *lastSubType = this->aType->getContainedType(this->aType->getNumContainedTypes()-1);
160                 if(lastSubType->isArrayTy() && ((ArrayType*)lastSubType)->getNumElements() <= 1) {
161                     flags |= MAGIC_TYPE_VARSIZE;
162                 }
163             }
164 #endif
165         }
166     }
167     else if(aSmartType->isPointerTy()) {
168         typeID = MAGIC_TYPE_POINTER;
169     }
170     else if(aSmartType->isArrayTy()) {
171         typeID = MAGIC_TYPE_ARRAY;
172     }
173     else if(aEDIType->isFloatingPointTy()) {
174         typeID = MAGIC_TYPE_FLOAT;
175     }
176     else if(aEDIType->isIntegerTy()) {
177         typeID = MAGIC_TYPE_INTEGER;
178     }
179     else if(aEDIType->isEnumTy()) {
180         typeID = MAGIC_TYPE_ENUM;
181     }
182     else if(aEDIType->isVectorTy()) {
183         typeID = MAGIC_TYPE_VECTOR;
184     }
185     assert(typeID);
186     if(typeID == MAGIC_TYPE_INTEGER || typeID == MAGIC_TYPE_ENUM) {
187         if(getNamesString().find("unsigned") != std::string::npos) {
188             flags |= MAGIC_TYPE_UNSIGNED;
189         }
190     }
191     numElements = aSmartType->getNumElements();
192     init(persistent);
193 }
194 
195 inline TypeInfo::TypeInfo(TYPECONST FunctionType *FT, int persistent) {
196     assert(FT);
197     aSmartType = NULL;
198     aType = FT;
199     forceTypeDescription = true;
200     bitWidth = 0;
201     typeID = MAGIC_TYPE_FUNCTION;
202     numElements = 0;
203     flags = MAGIC_TYPE_EXTERNAL;
204     init(persistent);
205 }
206 
207 inline TypeInfo::TypeInfo(TYPECONST PointerType *PT, int persistent) {
208     assert(PT);
209     aSmartType = NULL;
210     aType = PT;
211     forceTypeDescription = false;
212     bitWidth = 0;
213     typeID = MAGIC_TYPE_POINTER;
214     numElements = 0;
215     flags = MAGIC_TYPE_EXTERNAL;
216     init(persistent);
217 }
218 
219 inline TypeInfo::TypeInfo(TYPECONST ArrayType *AT, int persistent) {
220     assert(AT);
221     aSmartType = NULL;
222     aType = AT;
223     forceTypeDescription = false;
224     bitWidth = 0;
225     typeID = MAGIC_TYPE_ARRAY;
226     numElements = AT->getNumElements();
227     flags = MAGIC_TYPE_EXTERNAL;
228     init(persistent);
229 }
230 
231 inline TypeInfo::TypeInfo(TYPECONST IntegerType *IT, int persistent) {
232     assert(IT);
233     aSmartType = NULL;
234     aType = IT;
235     forceTypeDescription = true;
236     bitWidth = IT->getBitWidth();
237     typeID = MAGIC_TYPE_INTEGER;
238     numElements = 0;
239     flags = MAGIC_TYPE_EXTERNAL;
240     init(persistent);
241 }
242 
243 inline TypeInfo::TypeInfo(TYPECONST StructType *OpaqueST, int persistent) {
244     assert(OpaqueST);
245     assert(TypeUtil::isOpaqueTy(OpaqueST));
246     aSmartType = NULL;
247     aType = OpaqueST;
248     forceTypeDescription = true;
249     bitWidth = 0;
250     typeID = MAGIC_TYPE_OPAQUE;
251     numElements = 0;
252     flags = MAGIC_TYPE_EXTERNAL;
253     init(persistent);
254 }
255 
256 inline void TypeInfo::init(int persistent) {
257     std::map<TYPECONST Type*, std::set<int> >::iterator intCastTypesIt;
258     //set persistent if necessary
259     if(persistent) {
260         setPersistent();
261     }
262     //initialize value set for pointers casted to int
263     if(aType->isPointerTy()) {
264         intCastTypesIt = intCastTypes.find(aType);
265         if(intCastTypesIt != intCastTypes.end()) {
266             std::set<int> &pointerValues = intCastTypesIt->second;
267             assert(pointerValues.size() > 0);
268             flags |= MAGIC_TYPE_INT_CAST;
269             if(pointerValues.size() > 1 || *(pointerValues.begin()) != 0) {
270                 valueSet.push_back(pointerValues.size()); //push length as the first value
271                 for(std::set<int>::iterator it=pointerValues.begin() ; it != pointerValues.end(); it++) {
272                     assert(*it != 0);
273                     valueSet.push_back(*it);
274                 }
275             }
276         }
277     }
278     //adjust flags
279     bool hasInnerPointers = aSmartType ? aSmartType->hasInnerPointers() : TypeUtil::hasInnerPointers(aType);
280     if(!hasInnerPointers) {
281         flags |= MAGIC_TYPE_NO_INNER_PTRS;
282     }
283 }
284 
285 inline const SmartType *TypeInfo::getSmartType() const {
286     return aSmartType;
287 }
288 
289 inline TYPECONST Type *TypeInfo::getType() const {
290     return aType;
291 }
292 
293 inline unsigned TypeInfo::getNumContainedTypes() const {
294     return containedTypes.size();
295 }
296 
297 inline unsigned TypeInfo::getNumChildTypes() const {
298     return typeID == MAGIC_TYPE_ARRAY ? numElements : containedTypes.size();
299 }
300 
301 inline TypeInfo *TypeInfo::getContainedType(unsigned i) const {
302     assert(i<containedTypes.size());
303     return containedTypes[i];
304 }
305 
306 inline std::vector<GlobalValue*> TypeInfo::getParents() const {
307     return parents;
308 }
309 
310 inline std::string TypeInfo::getTypeString() const {
311     std::string typeString = forceTypeDescription || aType->getNumContainedTypes() == 0 ? getDescription() : "";
312     if(MAGIC_SHRINK_TYPE_STR && typeString.size() > MAGIC_MAX_TYPE_STR_LEN) {
313         typeString = typeString.substr(0, MAGIC_MAX_TYPE_STR_LEN-3) + "...";
314     }
315     if(typeString.size() > maxTypeStringLength) {
316         maxTypeStringLength = typeString.size();
317     }
318     return typeString;
319 }
320 
321 inline std::string TypeInfo::getDescription() const {
322     if(typeDescription.size() == 0) {
323         if(aType->isFunctionTy() && FUNCTIONS_USE_HASH_TYPE_STRINGS) {
324             unsigned hash = TypeUtil::getHash(aType);
325             raw_string_ostream ostream(typeDescription);
326             ostream << "hash_" << hash;
327             ostream.flush();
328         }
329         else {
330             typeDescription = TypeUtil::getDescription(aType);
331         }
332     }
333     return typeDescription;
334 }
335 
336 inline std::string TypeInfo::getVerboseDescription() const {
337     return aSmartType ? aSmartType->getDescription() : getDescription();
338 }
339 
340 inline std::string TypeInfo::getName() const {
341     return name;
342 }
343 
344 inline std::vector<std::string> TypeInfo::getNames() const {
345     return names;
346 }
347 
348 inline std::string TypeInfo::getNamesString() const {
349     std::string string;
350     raw_string_ostream ostream(string);
351     for(unsigned i=0;i<names.size();i++) {
352         if(i>0) ostream << "|";
353         ostream << names[i];
354     }
355     ostream.flush();
356     return string;
357 }
358 
359 inline std::vector<std::string> TypeInfo::getMemberNames() const {
360     for(unsigned i=0;i<memberNames.size();i++) {
361         if(memberNames[i].size() > maxNameLength) {
362             maxNameLength = memberNames[i].size();
363         }
364     }
365     return memberNames;
366 }
367 
368 inline std::vector<int> TypeInfo::getValueSet() const {
369     return valueSet;
370 }
371 
372 inline std::vector<TypeInfo*> TypeInfo::getCastTypes() const {
373     std::vector<TypeInfo*> castTypes;
374     std::map<TYPECONST Type*, std::set<TYPECONST Type*> >::iterator bitCastTypesIt;
375     std::map<TYPECONST Type*, std::set<TypeInfo*> >::iterator typeMapIt;
376     if(!aType->isPointerTy()) {
377         return castTypes;
378     }
379     //XXX to-do: match only original struct name during lookup by looking at the original bitcast instruction
380     //the following lookups do not distinguish between struct x = {18} and struct y = {i8}
381     //the number of false positives generated seems to be fairly small, anyway
382     bitCastTypesIt = bitCastTypes.find(aType);
383     if(bitCastTypesIt == bitCastTypes.end()) {
384         return castTypes;
385     }
386     std::set<TYPECONST Type*> bitCastSet = bitCastTypesIt->second;
387 #if MAGIC_INDEX_TRANSITIVE_BIT_CASTS
388     std::vector<TYPECONST Type*> bitCasts;
389     for(std::set<TYPECONST Type*>::iterator it=bitCastSet.begin();it!=bitCastSet.end();it++) {
390         bitCasts.push_back(*it);
391     }
392     while(!bitCasts.empty()) {
393         TYPECONST Type* bcType = bitCasts.front();
394         bitCasts.erase(bitCasts.begin());
395         bitCastTypesIt = bitCastTypes.find(bcType);
396         if(bitCastTypesIt != bitCastTypes.end()) {
397             std::set<TYPECONST Type*> set = bitCastTypesIt->second;
398             for(std::set<TYPECONST Type*>::iterator it=set.begin();it!=set.end();it++) {
399                 unsigned bitCastSetSize = bitCastSet.size();
400                 TYPECONST Type *newBcType = *it;
401                 if(newBcType == aType) {
402                     continue;
403                 }
404                 bitCastSet.insert(newBcType);
405                 if(bitCastSet.size() != bitCastSetSize) {
406                     bitCasts.push_back(newBcType);
407                 }
408             }
409         }
410     }
411 #endif
412 
413 #if DEBUG_CAST_LOOKUPS
414     if(aType->getContainedType(0)->isStructTy()) {
415         TypeInfoErr("--- type is struct* " << getContainedType(0)->getName());
416     }
417     else if(aType->getContainedType(0)->isPointerTy() && aType->getContainedType(0)->getContainedType(0)->isStructTy()) {
418         TypeInfoErr("--- type is struct** " << getContainedType(0)->getContainedType(0)->getName());
419     }
420     else {
421         TypeInfoErr("--- type is " << getDescription());
422     }
423 #endif
424 
425     for(std::set<TYPECONST Type*>::iterator it=bitCastSet.begin();it!=bitCastSet.end();it++) {
426         TYPECONST Type* type = *it;
427         assert(type->isPointerTy());
428         typeMapIt = typeMap.find(type->getContainedType(0));
429         if(typeMapIt == typeMap.end()) {
430 
431 #if DEBUG_CAST_LOOKUPS
432             TypeInfoErr("*** cast target type not found: " << TypeUtil::getDescription(type->getContainedType(0)));
433 #endif
434 
435             continue;
436         }
437         std::set<TypeInfo*> *typeInfoSet = &(typeMapIt->second);
438         for(std::set<TypeInfo*>::iterator it2=typeInfoSet->begin();it2!=typeInfoSet->end();it2++) {
439             TypeInfo* typeInfo = *it2;
440             assert(typeInfo->getType() != getType()->getContainedType(0));
441 
442 #if DEBUG_CAST_LOOKUPS
443             if(typeInfo->getType()->isStructTy()) {
444                 TypeInfoErr(">>> cast target type info is struct " << typeInfo->getName());
445             }
446             else if(typeInfo->getType()->isPointerTy() && typeInfo->getType()->getContainedType(0)->isStructTy()) {
447                 TypeInfoErr(">>> cast target type info is struct* " << typeInfo->getContainedType(0)->getName());
448             }
449             else {
450                 TypeInfoErr(">>> cast target type info is " << typeInfo->getDescription());
451             }
452 #endif
453             castTypes.push_back(typeInfo);
454 
455 #if MAGIC_COMPACT_COMP_TYPES
456             /* This is safe as long as we check for compatible (LLVM) types at runtime. */
457             break;
458 #endif
459         }
460     }
461     if(castTypes.size() > 0) { //push delimiter
462         castTypes.push_back(NULL);
463     }
464     return castTypes;
465 }
466 
467 inline unsigned TypeInfo::getTypeID() const {
468     return typeID;
469 }
470 
471 inline unsigned TypeInfo::getFlags() const {
472     return flags;
473 }
474 
475 inline unsigned TypeInfo::getBitWidth() const {
476     return bitWidth;
477 }
478 
479 inline bool TypeInfo::equals(TYPECONST TypeInfo *other) const {
480     if(aSmartType && other->getSmartType()) {
481         return aSmartType->equals(other->getSmartType());
482     }
483     return (flags & (~MAGIC_TYPE_IS_ROOT)) == (other->getFlags() & (~MAGIC_TYPE_IS_ROOT))
484         && !getDescription().compare(other->getDescription());
485 }
486 
487 inline bool TypeInfo::hasRawTypeRepresentation() const {
488     return aSmartType && aSmartType->hasRawTypeRepresentation();
489 }
490 
491 inline std::string TypeInfo::formatMemberName(const std::string &memberName, unsigned &numAnonMembers) {
492     if (memberName.compare("")) {
493         return memberName;
494     }
495     std::string name(memberName);
496     raw_string_ostream ostream(name);
497     ostream << MAGIC_ANON_MEMBER_PREFIX << "." << (numAnonMembers+1);
498     ostream.flush();
499     numAnonMembers++;
500 
501     return name;
502 }
503 
504 inline void TypeInfo::setValueSet(const std::vector<int> &valueSet) {
505     this->valueSet = valueSet;
506 }
507 
508 inline void TypeInfo::setContainedTypes(const std::vector<TypeInfo*> &containedTypes) {
509     this->containedTypes = containedTypes;
510 }
511 
512 inline void TypeInfo::addParent(GlobalValue* parent) {
513     assert((typeID == MAGIC_TYPE_FUNCTION && dyn_cast<Function>(parent))
514         || (typeID != MAGIC_TYPE_FUNCTION && dyn_cast<GlobalVariable>(parent)));
515     this->parents.push_back(parent);
516     flags |= MAGIC_TYPE_IS_ROOT;
517 
518 #if ROOT_TYPES_HAVE_TYPE_STRINGS
519     forceTypeDescription = true;
520 #endif
521 }
522 
523 inline void TypeInfo::addParents(const std::vector<GlobalValue*> &parents) {
524     for(unsigned i=0;i<parents.size();i++) {
525         addParent(parents[i]);
526     }
527 }
528 
529 inline bool TypeInfo::removeParent(GlobalValue* parent)
530 {
531     std::vector<GlobalValue*> originalParents = this->parents;
532     this->parents.clear();
533     for(unsigned i=0;i<originalParents.size();i++) {
534         if(originalParents[i] != parent) {
535             this->parents.push_back(originalParents[i]);
536         }
537     }
538     int sizeDiff = originalParents.size() - this->parents.size();
539     assert(sizeDiff == 0 || sizeDiff == 1);
540     return (sizeDiff == 1);
541 }
542 
543 inline bool TypeInfo::removeAllParents()
544 {
545     if(this->parents.size() > 0) {
546         this->parents.clear();
547         return true;
548     }
549     return false;
550 }
551 
552 inline void TypeInfo::setPersistent() {
553     std::map<TYPECONST Type*, std::set<TypeInfo*> >::iterator typeMapIt;
554     typeMapIt = typeMap.find(aType);
555     if(typeMapIt == typeMap.end()) {
556         std::set<TypeInfo*> set;
557         set.insert(this);
558         typeMap.insert(std::pair<TYPECONST Type*, std::set<TypeInfo*> >(aType, set));
559     }
560     else {
561         std::set<TypeInfo*> *set;
562         set = &(typeMapIt->second);
563         set->insert(this);
564     }
565 }
566 
567 inline bool TypeInfo::splitByParentValueSet(std::vector<TypeInfo*> &splitTypeInfos, std::set<GlobalVariable*> &globalVariablesWithAddressTaken) {
568     std::map<std::vector<int>, std::vector<GlobalVariable*> > valueSetMap;
569     std::map<std::vector<int>, std::vector<GlobalVariable*> >::iterator valueSetMapIt;
570     std::vector<int> valueSet;
571     splitTypeInfos.push_back(this);
572     if(!isa<IntegerType>(aType)) {
573         return false;
574     }
575     assert(valueSet.size() == 0);
576     for(unsigned i=0;i<parents.size();i++) {
577         if(GlobalVariable *GV = dyn_cast<GlobalVariable>(parents[i])) {
578             bool hasAddressTaken = globalVariablesWithAddressTaken.find(GV) != globalVariablesWithAddressTaken.end();
579             if(hasAddressTaken) {
580                 continue;
581             }
582             valueSet.clear();
583             bool valueSetFound = MagicUtil::lookupValueSet(GV, valueSet);
584             if(!valueSetFound) {
585                 continue;
586             }
587             valueSetMapIt = valueSetMap.find(valueSet);
588             if(valueSetMapIt == valueSetMap.end()) {
589                 std::vector<GlobalVariable*> vector;
590                 valueSetMap.insert(std::pair<std::vector<int>, std::vector<GlobalVariable*> >(valueSet, vector));
591                 valueSetMapIt = valueSetMap.find(valueSet);
592                 assert(valueSetMapIt != valueSetMap.end());
593             }
594             std::vector<GlobalVariable*> *globalsVector = &valueSetMapIt->second;
595             globalsVector->push_back(GV);
596         }
597     }
598     if(valueSetMap.size() == 0) {
599         return false;
600     }
601     for(valueSetMapIt = valueSetMap.begin(); valueSetMapIt!=valueSetMap.end(); valueSetMapIt++) {
602         const std::vector<int> &values = valueSetMapIt->first;
603         const std::vector<GlobalVariable*> &globalVariables = valueSetMapIt->second;
604         TypeInfo *aTypeInfo = new TypeInfo(*this);
605         aTypeInfo->setValueSet(values);
606         aTypeInfo->removeAllParents();
607         for(unsigned i=0;i<globalVariables.size();i++) {
608             GlobalVariable* GV = globalVariables[i];
609             bool parentRemoved = this->removeParent(GV);
610             assert(parentRemoved);
611             aTypeInfo->addParent(GV);
612         }
613         splitTypeInfos.push_back(aTypeInfo);
614     }
615     return true;
616 }
617 
618 inline unsigned TypeInfo::getMaxNameLength() {
619     return TypeInfo::maxNameLength;
620 }
621 
622 inline unsigned TypeInfo::getMaxTypeStringLength() {
623     return TypeInfo::maxTypeStringLength;
624 }
625 
626 inline void TypeInfo::setIntCastTypes(std::map<TYPECONST Type*, std::set<int> > &intCastTypes) {
627     TypeInfo::intCastTypes = intCastTypes;
628 }
629 
630 inline void TypeInfo::setBitCastTypes(std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastTypes) {
631     TypeInfo::bitCastTypes = bitCastTypes;
632 }
633 
634 }
635 
636 #endif
637