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