1 #include <magic_common.h>
2 #include <magic/support/SmartType.h>
3 #include <limits.h>
4 
5 using namespace llvm;
6 
7 namespace llvm {
8 
9 #define DEBUG_EQUALS        0
10 #define DEBUG_BFAS          0
11 #define DEBUG_UNIONS        0
12 int debugEquals = 0;
13 
14 //===----------------------------------------------------------------------===//
15 // Constructors, destructor, and operators
16 //===----------------------------------------------------------------------===//
SmartType(const SmartType & et)17 SmartType::SmartType(const SmartType& et) {
18     cloneFrom(et);
19 }
20 
SmartType(TYPECONST Type * type,const DIType * aDIType,bool useExceptions,bool forceRawTypeRepresentation)21 SmartType::SmartType(TYPECONST Type *type, const DIType *aDIType, bool useExceptions, bool forceRawTypeRepresentation) {
22     EDIType tmp(*aDIType);
23     init(type, &tmp, useExceptions, forceRawTypeRepresentation);
24     normalize();
25 }
26 
SmartType(TYPECONST Type * type,const EDIType * aEDIType,bool useExceptions,bool forceRawTypeRepresentation)27 SmartType::SmartType(TYPECONST Type *type, const EDIType *aEDIType, bool useExceptions, bool forceRawTypeRepresentation) {
28     init(type, aEDIType, useExceptions, forceRawTypeRepresentation);
29     normalize();
30 }
31 
~SmartType()32 SmartType::~SmartType() {
33     if(hasExplicitContainedEDITypes) {
34         for(unsigned i=0;i<explicitContainedEDITypes.size();i++) {
35             const EDIType* aEDIType = explicitContainedEDITypes[i];
36             delete aEDIType;
37         }
38     }
39 }
40 
operator =(const SmartType & et)41 SmartType& SmartType::operator=(const SmartType& et) {
42     if (this != &et) {
43         cloneFrom(et);
44     }
45     return *this;
46 }
47 
cloneFrom(const SmartType & et)48 void SmartType::cloneFrom(const SmartType& et) {
49     init(et.type, &et.aEDIType, et.useExceptions, false);
50     if(et.hasExplicitContainedEDITypes) {
51         hasExplicitContainedEDITypes = true;
52         for(unsigned i=0;i<et.explicitContainedEDITypes.size();i++) {
53             const EDIType* aEDIType = et.explicitContainedEDITypes[i];
54             explicitContainedEDITypes.push_back(new EDIType(*aEDIType));
55         }
56     }
57     isInconsistent = et.isInconsistent;
58     rawTypeRepresentation = et.rawTypeRepresentation;
59     bfas = et.bfas;
60 }
61 
62 //===----------------------------------------------------------------------===//
63 // Getters
64 //===----------------------------------------------------------------------===//
65 
getDescription() const66 const std::string SmartType::getDescription() const {
67     return TypeUtil::getDescription(type, &aEDIType);
68 }
69 
getContainedType(unsigned i) const70 const SmartType* SmartType::getContainedType(unsigned i) const {
71     assert(!rawTypeRepresentation);
72     bool hasBitFields = false;
73     TYPECONST Type *subType = type->getContainedType(i);
74     const SmartType* retSmartType = NULL;
75     if(hasExplicitContainedEDITypes) {
76         const EDIType subEDIType(*(explicitContainedEDITypes[i]));
77         retSmartType = new SmartType(subType, &subEDIType, useExceptions);
78     }
79     else {
80         if(aEDIType.isUnionTy()) {
81             assert(i == 0);
82             i = unionMemberIdx;
83         }
84         else if(bfas.size() > 0) {
85             i = getBFAFreeIdx(i, bfas);
86             hasBitFields = true;
87         }
88         const EDIType subEDIType(aEDIType.getContainedType(i));
89         retSmartType = new SmartType(subType, &subEDIType, useExceptions, hasBitFields && subEDIType.isIntegerTy() && subType->isArrayTy());
90     }
91     return retSmartType;
92 }
93 
getNumContainedTypes() const94 unsigned SmartType::getNumContainedTypes() const {
95     if(rawTypeRepresentation || aEDIType.isComplexFloatingPointTy() || isOpaqueTy()) {
96         return 0;
97     }
98     unsigned numContainedTypes = type->getNumContainedTypes();
99     unsigned numContainedEDITypes;
100     if(hasExplicitContainedEDITypes) {
101         numContainedEDITypes = explicitContainedEDITypes.size();
102     }
103     else {
104         if(aEDIType.isUnionTy()) {
105             numContainedEDITypes = 1;
106         }
107         else {
108             numContainedEDITypes = aEDIType.getNumContainedTypes();
109             if(bfas.size() > 0) {
110                 for(unsigned i=0;i<bfas.size();i++) {
111                     numContainedEDITypes -= (bfas[i].getSize() - 1);
112                 }
113             }
114         }
115     }
116     if(numContainedTypes == numContainedEDITypes+1 && isPaddedTy()) {
117         numContainedTypes--;
118     }
119     if(numContainedTypes != numContainedEDITypes) {
120         if(isArrayTy() && TypeUtil::isArrayAsStructTy(type)) {
121             numContainedTypes = 1;
122         }
123     }
124     SmartType_assert(numContainedTypes == numContainedEDITypes);
125     return numContainedTypes;
126 }
127 
getMember(unsigned i) const128 const DIDerivedType& SmartType::getMember(unsigned i) const {
129     assert(!rawTypeRepresentation);
130     if(bfas.size() > 0) {
131         i = getBFAFreeIdx(i, bfas);
132     }
133     return aEDIType.getMember(i);
134 }
135 
getUnionMemberIdx() const136 unsigned SmartType::getUnionMemberIdx() const {
137     assert(!rawTypeRepresentation);
138     SmartType_assert(isTy(type->isStructTy(), aEDIType.isUnionTy(), "getUnionMemberIdx"));
139     SmartType_assert(getNumContainedTypes() == 1);
140     TYPECONST Type* uMemberType = type->getContainedType(0);
141     unsigned numSubEDITypes = aEDIType.getNumContainedTypes();
142     std::vector<unsigned> indexes;
143     int maxWeakConsistencyLevel = -1;
144     unsigned maxWeakConsistencyIndex = -1;
145     int maxWeakConsistencyLevelEntries;
146     unsigned index;
147     for(unsigned i=0;i<numSubEDITypes;i++) {
148         int weakConsistencyLevel;
149         EDIType subEDIType = aEDIType.getContainedType(i);
150         if(isTypeConsistent(uMemberType, &subEDIType, true, &weakConsistencyLevel)) {
151             indexes.push_back(i);
152             if(weakConsistencyLevel > maxWeakConsistencyLevel) {
153                 maxWeakConsistencyLevel = weakConsistencyLevel;
154                 maxWeakConsistencyIndex = i;
155                 maxWeakConsistencyLevelEntries = 1;
156             }
157             else if(weakConsistencyLevel == maxWeakConsistencyLevel) {
158                 maxWeakConsistencyLevelEntries++;
159             }
160         }
161     }
162     if(indexes.size() == 0) {
163         //try to match names if we failed before
164         std::string name = EDIType::lookupUnionMemberName(type);
165         if(name.compare("")) {
166             for(unsigned i=0;i<numSubEDITypes;i++) {
167                 EDIType subEDIType = aEDIType.getContainedType(i);
168                 if(!subEDIType.getName().compare(name)) {
169                     indexes.push_back(i);
170                     maxWeakConsistencyIndex = i;
171                 }
172             }
173         }
174     }
175     if(indexes.size() == 0) {
176         //No valid union member found
177 #if DEBUG_UNIONS
178         SmartTypeErr("getUnionMemberIdx: resorting to a raw type. No valid union member found for: " << getDescription());
179 #endif
180         return UINT_MAX;
181     }
182     index = maxWeakConsistencyIndex;
183     if(indexes.size() > 1) {
184         SmartTypeLog("getUnionMemberIdx: warning: multiple valid union members found, automatically selecting the first most-consistent member:");
185         SmartTypeLog(" - target member type is: " << TypeUtil::getDescription(uMemberType));
186         SmartTypeLog(" - selected index is: " << index);
187         for(unsigned i=0;i<indexes.size();i++) {
188             EDIType subEDIType = aEDIType.getContainedType(indexes[i]);
189             SmartTypeLog(" - " << indexes[i] << ". " << TypeUtil::getDescription(&subEDIType));
190         }
191     }
192 
193     return index;
194 }
195 
getTopStructType(unsigned index) const196 const SmartType* SmartType::getTopStructType(unsigned index) const {
197     TYPECONST Type *topType = TypeUtil::lookupTopStructType(type, index);
198     const EDIType *topEDIType = aEDIType.getTopStructType(index);
199     assert((topType && topEDIType) || (!topType && !topEDIType));
200     if(topType) {
201         const SmartType* retSmartType = new SmartType(topType, topEDIType);
202         return retSmartType;
203     }
204     return NULL;
205 }
206 
207 //===----------------------------------------------------------------------===//
208 // Other public methods
209 //===----------------------------------------------------------------------===//
210 
verify() const211 void SmartType::verify() const {
212     SmartType_assert(isTypeConsistent());
213 }
214 
print(raw_ostream & OS) const215 void SmartType::print(raw_ostream &OS) const {
216      OS << getDescription();
217 }
218 
equals(const SmartType * other,bool isDebug) const219 bool SmartType::equals(const SmartType* other, bool isDebug) const {
220     static std::set<std::pair<MDNode*, MDNode*> > compatibleMDNodes;
221     static std::set<std::pair<MDNode*, MDNode*> >::iterator compatibleMDNodesIt;
222 #if DEBUG_EQUALS
223     if(debugEquals) SmartTypeErr("COMPARING :" << getDescription() << " VS " << other->getDescription());
224 #endif
225     if(type != other->getType()) {
226 #if DEBUG_EQUALS
227         if(debugEquals) SmartTypeErr("----> false1");
228 #endif
229         return false;
230     }
231     if(isOpaqueTy() || other->isOpaqueTy()) {
232         return isOpaqueTy() && other->isOpaqueTy();
233     }
234     if(aEDIType.getTag() != other->getEDIType()->getTag()) {
235 #if DEBUG_EQUALS
236         if(debugEquals) SmartTypeErr("----> false1b");
237 #endif
238         return false;
239     }
240     if(isFunctionTy() && (!isTypeConsistent() || !other->isTypeConsistent())) {
241         //we just compare the types for inconsistent functions types
242         return true;
243     }
244     if(hasRawTypeRepresentation() || other->hasRawTypeRepresentation()) {
245         return !aEDIType.getNamesString().compare(other->getEDIType()->getNamesString());
246     }
247     unsigned numContainedTypes = getNumContainedTypes();
248     unsigned otherNumContainedTypes = other->getNumContainedTypes();
249     if(numContainedTypes != otherNumContainedTypes) {
250 #if DEBUG_EQUALS
251         if(debugEquals) SmartTypeErr("----> false2");
252 #endif
253         return false;
254     }
255     unsigned numElements = aEDIType.getNumElements();
256     unsigned otherNumElements = other->getEDIType()->getNumElements();
257     if(numElements != otherNumElements) {
258 #if DEBUG_EQUALS
259         if(debugEquals) SmartTypeErr("----> false2b");
260 #endif
261         return false;
262     }
263     std::string name = aEDIType.getName();
264     std::string otherName = other->getEDIType()->getName();
265     if(name.compare(otherName)) {
266 #if DEBUG_EQUALS
267         if(debugEquals) SmartTypeErr("----> false3: " <<  name <<  " vs " <<  otherName);
268 #endif
269         return false;
270     }
271     if(aEDIType.getNames().size() > 1 || other->getEDIType()->getNames().size() > 1) {
272         std::string namesString = aEDIType.getNamesString();
273         std::string otherNamesString = other->getEDIType()->getNamesString();
274         if(namesString.compare(otherNamesString)) {
275 #if DEBUG_EQUALS
276             if(debugEquals) SmartTypeErr("----> false4: " <<  namesString <<  " vs " <<  otherNamesString);
277 #endif
278             return false;
279         }
280     }
281     if(numContainedTypes == 0) {
282 #if DEBUG_EQUALS
283         if(debugEquals) SmartTypeErr("----> true4");
284 #endif
285         return true;
286     }
287     MDNode *node = *(aEDIType.getDIType());
288     MDNode *otherNode = *(other->getEDIType()->getDIType());
289     if(node == otherNode) {
290         return true;
291     }
292     for(unsigned i=0;i<SmartType::equalsNestedTypes.size();i++) {
293         if(type == SmartType::equalsNestedTypes[i]) {
294 #if DEBUG_EQUALS
295             if(debugEquals) SmartTypeErr("----> true5");
296 #endif
297             return true;
298         }
299     }
300     //before digging the type tree, see if we have these 2 metadata nodes in cache
301     //this gives us an impressive speedup
302     MDNode *minNode = node < otherNode ? node : otherNode;
303     MDNode *maxNode = node < otherNode ? otherNode : node;
304     compatibleMDNodesIt = compatibleMDNodes.find(std::pair<MDNode*, MDNode*>(minNode, maxNode));
305     if(compatibleMDNodesIt != compatibleMDNodes.end()) {
306         return true;
307     }
308     SmartType::equalsNestedTypes.push_back(type);
309     const SmartType* containedType = NULL;
310     const SmartType* otherContainedType = NULL;
311     bool sameContainedTypes = true;
312     for(unsigned i=0;i<numContainedTypes;i++) {
313         containedType = getContainedType(i);
314         otherContainedType = other->getContainedType(i);
315         sameContainedTypes = containedType->equals(otherContainedType);
316         delete containedType;
317         delete otherContainedType;
318         if(!sameContainedTypes) {
319             break;
320         }
321     }
322     SmartType::equalsNestedTypes.pop_back();
323     if(!sameContainedTypes) {
324 #if DEBUG_EQUALS
325         if(debugEquals) SmartTypeErr("----> false6");
326 #endif
327         return false;
328     }
329 #if DEBUG_EQUALS
330     if(debugEquals) SmartTypeErr("----> true7");
331 #endif
332     compatibleMDNodes.insert(std::pair<MDNode*, MDNode*>(minNode, maxNode));
333     return true;
334 }
335 
336 //===----------------------------------------------------------------------===//
337 // Public static methods
338 //===----------------------------------------------------------------------===//
339 
getSmartTypeFromGV(Module & M,GlobalVariable * GV,DIGlobalVariable * DIG)340 const SmartType* SmartType::getSmartTypeFromGV(Module &M, GlobalVariable *GV, DIGlobalVariable *DIG) {
341     //ignore anonymous strings
342     if(GV->getName().startswith(".str")) {
343         return NULL;
344     }
345     MDNode *DIGV = PassUtil::findDbgGlobalDeclare(GV);
346     if (!DIGV) {
347         return NULL;
348     }
349     DIGlobalVariable Var(DIGV);
350     DIType aDIType = PassUtil::getDITypeFromRef(Var.getType());
351     const SmartType* retSmartType = new SmartType(GV->getType()->getElementType(), &aDIType);
352     if(DIG) {
353         *DIG = Var;
354     }
355     return retSmartType;
356 }
357 
getSmartTypeFromLV(Module & M,AllocaInst * AI,DIVariable * DIV)358 const SmartType* SmartType::getSmartTypeFromLV(Module &M, AllocaInst *AI, DIVariable *DIV) {
359     const DbgDeclareInst *DDI = FindAllocaDbgDeclare(AI);
360     if (!DDI) {
361         return NULL;
362     }
363     if(DDI == (const DbgDeclareInst *) -1) {
364         return (const SmartType*)-1;
365     }
366     DIVariable Var(cast<MDNode>(DDI->getVariable()));
367     DIType aDIType = PassUtil::getDITypeFromRef(Var.getType());
368     if(DIV) {
369         *DIV = Var;
370     }
371     const SmartType* aSmartType = new SmartType(AI->getAllocatedType(), &aDIType);
372     return aSmartType;
373 }
374 
getSmartTypeFromFunction(Module & M,Function * F,DISubprogram * DIS)375 const SmartType* SmartType::getSmartTypeFromFunction(Module &M, Function *F, DISubprogram *DIS) {
376     MDNode *DIF = PassUtil::findDbgSubprogramDeclare(F);
377     if (!DIF) {
378         return NULL;
379     }
380     DISubprogram Sub(DIF);
381     DIType aDIType = Sub.getType();
382     const SmartType* retSmartType = new SmartType(F->getType()->getElementType(), &aDIType);
383     if(DIS) {
384         *DIS = Sub;
385     }
386     return retSmartType;
387 }
388 
getStructSmartTypeByName(Module & M,GlobalVariable * GV,std::string & name,bool isUnion)389 const SmartType* SmartType::getStructSmartTypeByName(Module &M, GlobalVariable* GV, std::string &name, bool isUnion) {
390     std::string structName((isUnion ? "union." : "struct.") + name);
391 
392     TYPECONST Type *targetType = M.getTypeByName(structName);
393     const EDIType *targetEDIType = EDIType::getStructEDITypeByName(name);
394 
395     const SmartType *retSmartType = NULL;
396     if(targetType && targetEDIType) {
397         retSmartType = new SmartType(targetType, targetEDIType);
398     }
399     return retSmartType;
400 }
401 
getTopStructSmartTypes(Module & M,GlobalVariable * GV)402 std::vector<const SmartType*>* SmartType::getTopStructSmartTypes(Module &M, GlobalVariable* GV) {
403     std::vector<std::string> names;
404     std::vector<unsigned> flags;
405     TypeUtil::parseTopStructTypes(M, GV->getType()->getElementType(), &names, &flags);
406     std::vector<const SmartType*> *vector = new std::vector<const SmartType*>;
407     for(unsigned i=0;i<names.size();i++) {
408         std::string entryName = names[i];
409         unsigned entryFlags = flags[i];
410         const SmartType *aSmartType = NULL;
411         if(!(entryFlags & TypeUtil::TYPE_ANONYMOUS) && !(entryFlags & TypeUtil::TYPE_UNNAMED)) {
412             aSmartType = getStructSmartTypeByName(M, GV, entryName, (entryFlags & TypeUtil::TYPE_UNION));
413         }
414         if(aSmartType == NULL) {
415             //this method can fail due to name clashing but is the only one possible for anonymous or unnamed struct types
416             const SmartType *GVSmartType = getSmartTypeFromGV(M, GV);
417             assert(GVSmartType && "Unable to find a match for anonymous or unnamed struct type");
418             aSmartType = GVSmartType->getTopStructType(i);
419             delete GVSmartType;
420             assert(aSmartType != NULL);
421         }
422         vector->push_back(aSmartType);
423     }
424 
425     return vector;
426 }
427 
428 //===----------------------------------------------------------------------===//
429 // Private methods
430 //===----------------------------------------------------------------------===//
431 
init(TYPECONST Type * type,const EDIType * aEDIType,bool useExceptions,bool forceRawTypeRepresentation)432 void SmartType::init(TYPECONST Type *type, const EDIType *aEDIType, bool useExceptions, bool forceRawTypeRepresentation) {
433     this->type = type;
434     this->aEDIType = *aEDIType;
435     this->useExceptions = useExceptions;
436     hasExplicitContainedEDITypes = false;
437     isInconsistent = false;
438     rawTypeRepresentation = false;
439     unionMemberIdx = 0;
440     if(aEDIType->isUnionTy()) {
441         if(forceRawUnions) {
442             rawTypeRepresentation = true;
443         }
444         else {
445             unionMemberIdx = getUnionMemberIdx();
446             if(unionMemberIdx == UINT_MAX) {
447                 rawTypeRepresentation = true;
448                 unionMemberIdx = 0;
449             }
450         }
451     }
452     else if(forceRawTypeRepresentation || (forceRawBitfields && BitFieldAggregation::hasBitFields(type, &(this->aEDIType)))) {
453         rawTypeRepresentation = true;
454     }
455 }
456 
normalize()457 void SmartType::normalize() {
458     if(isFunctionTy() && !hasExplicitContainedEDITypes) {
459         flattenFunctionTy();
460         hasExplicitContainedEDITypes = true;
461     }
462     if(!hasExplicitContainedEDITypes && !rawTypeRepresentation) {
463         if(!BitFieldAggregation::getBitFieldAggregations(type, &aEDIType, bfas, true)) {
464             //failed to determine bfas
465 #if DEBUG_BFAS
466             SmartTypeErr("normalize: resorting to a raw type. Cannot determine bfas for: " << getDescription());
467 #endif
468             rawTypeRepresentation = true;
469         }
470     }
471 }
472 
flattenFunctionTy()473 void SmartType::flattenFunctionTy() {
474     SmartType_assert(isFunctionTy() && !hasExplicitContainedEDITypes);
475     SmartType_assert(explicitContainedEDITypes.size() == 0);
476 #if MAGIC_FLATTEN_FUNCTION_ARGS
477     int ret = flattenFunctionArgs(type, &aEDIType, 0);
478     if(ret < 0 || explicitContainedEDITypes.size() != type->getNumContainedTypes()) {
479         SmartTypeLog("Warning: function flattening produced an inconsistent type!");
480         isInconsistent = true;
481     }
482 #else
483     isInconsistent = true;
484 #endif
485 }
486 
flattenFunctionArgs(TYPECONST Type * type,const EDIType * aEDIType,unsigned nextContainedType)487 int SmartType::flattenFunctionArgs(TYPECONST Type *type, const EDIType *aEDIType, unsigned nextContainedType) {
488     unsigned containedTypes = type->getNumContainedTypes();
489     unsigned containedEDITypes = aEDIType->isUnionTy() ? 1 : aEDIType->getNumContainedTypes();
490     unsigned containedEDIOptions = aEDIType->isUnionTy() ? aEDIType->getNumContainedTypes() : 1;
491     int ret;
492 
493     unsigned nextContainedEDIType = 0;
494     while(nextContainedEDIType < containedEDITypes) {
495         SmartType_assert(nextContainedType < containedTypes);
496         TYPECONST Type *containedType = type->getContainedType(nextContainedType);
497         unsigned currExplicitEDITypes = explicitContainedEDITypes.size();
498         unsigned i;
499         for(i=nextContainedEDIType;i<nextContainedEDIType+containedEDIOptions;i++) {
500             const EDIType containedEDIType = aEDIType->getContainedType(i);
501             if(isTypeConsistent(containedType, &containedEDIType)) {
502                 explicitContainedEDITypes.push_back(new EDIType(containedEDIType));
503                 break;
504             }
505             if(!containedEDIType.isAggregateType()) {
506                 continue;
507             }
508             ret = flattenFunctionArgs(type, &containedEDIType, nextContainedType);
509             if(ret == 0) {
510                 break;
511             }
512         }
513         if(i >= nextContainedEDIType+containedEDIOptions) {
514             while(explicitContainedEDITypes.size() > currExplicitEDITypes) {
515                 EDIType* aEDIType = explicitContainedEDITypes[explicitContainedEDITypes.size()-1];
516                 explicitContainedEDITypes.pop_back();
517                 delete aEDIType;
518             }
519             return -1;
520         }
521         nextContainedType += (explicitContainedEDITypes.size() - currExplicitEDITypes);
522         nextContainedEDIType++;
523     }
524     return 0;
525 }
526 
isTy(bool isTyType,bool isTyEDIType,const char * source) const527 bool SmartType::isTy(bool isTyType, bool isTyEDIType, const char* source) const {
528     bool check = (isTyType && isTyEDIType) || (!isTyType && !isTyEDIType);
529     if(!check) {
530         SmartTypeErr(source << " failed");
531     }
532     SmartType_assert(check);
533     return isTyType;
534 }
535 
536 //===----------------------------------------------------------------------===//
537 // Private static methods
538 //===----------------------------------------------------------------------===//
getBFAFreeIdx(unsigned i,const std::vector<BitFieldAggregation> & inputBfas)539 unsigned SmartType::getBFAFreeIdx(unsigned i, const std::vector<BitFieldAggregation> &inputBfas) {
540     for(unsigned j=0;j<inputBfas.size();j++) {
541         if(i<inputBfas[j].getEDITypeIndex()) {
542             break;
543         }
544         else if(i>inputBfas[j].getEDITypeIndex()) {
545             i += (inputBfas[j].getSize() - 1);
546         }
547         else {
548             i = inputBfas[j].getRepresentativeEDITypeIndex();
549             break;
550         }
551     }
552     return i;
553 }
554 
isRawTypeConsistent(TYPECONST Type * type,const EDIType * aEDIType)555 bool SmartType::isRawTypeConsistent(TYPECONST Type *type, const EDIType *aEDIType) {
556     if(aEDIType->isVoidTy()) {
557         return type->isVoidTy() || (type->isIntegerTy() && ((IntegerType*)type)->getBitWidth() == 8);
558     }
559     if(type->isFloatingPointTy()) {
560         return aEDIType->isFloatingPointTy();
561     }
562     if(type->isIntegerTy()) {
563         if(aEDIType->isCharTy() || aEDIType->isBoolTy()) {
564             return (((IntegerType*)type)->getBitWidth() <= 8);
565         }
566         return aEDIType->isIntegerTy() || aEDIType->isEnumTy();
567     }
568     if(type->isFunctionTy()) {
569         return aEDIType->isFunctionTy();
570     }
571     if(TypeUtil::isOpaqueTy(type)) {
572         return (aEDIType->isOpaqueTy());
573     }
574     return false;
575 }
576 
isTypeConsistent2(std::vector<TYPECONST Type * > & nestedTypes,std::vector<const EDIType * > & nestedEDITypes,const SmartType * aSmartType)577 bool SmartType::isTypeConsistent2(std::vector<TYPECONST Type*> &nestedTypes, std::vector<const EDIType*> &nestedEDITypes, const SmartType *aSmartType) {
578     assert(aSmartType->isUseExceptions());
579     TYPECONST Type *type = aSmartType->getType();
580     const EDIType *aEDIType = aSmartType->getEDIType();
581     if(aEDIType->isPointerTy() || aEDIType->isUnionOrStructTy()) {
582         for(unsigned j=0;j<nestedTypes.size();j++) {
583             if(nestedTypes[j] == type && nestedEDITypes[j]->equals(aEDIType)) {
584                 return true;
585             }
586         }
587     }
588 
589     unsigned nTypes = type->getNumContainedTypes();
590     unsigned nEDITypes = aEDIType->getNumContainedTypes();
591     if(nTypes == 0 || nEDITypes == 0) {
592         if(nTypes != 0 || nEDITypes != 0) {
593             return false;
594         }
595         return isRawTypeConsistent(type, aEDIType);
596     }
597     if(!aSmartType->verifyTy()) {
598         return false;
599     }
600     unsigned numContainedTypes = aSmartType->getNumContainedTypes();
601     nestedTypes.push_back(type);
602     nestedEDITypes.push_back(aEDIType);
603     for(unsigned i=0;i<numContainedTypes;i++) {
604         const SmartType *containedSmartType = aSmartType->getContainedType(i);
605         assert(containedSmartType->isUseExceptions());
606         SmartType clonedSmartType(*containedSmartType);
607         assert(clonedSmartType.isUseExceptions());
608         delete containedSmartType;
609         if(!isTypeConsistent2(nestedTypes, nestedEDITypes, &clonedSmartType)) {
610             return false;
611         }
612     }
613     nestedTypes.pop_back();
614     nestedEDITypes.pop_back();
615     return true;
616 }
617 
isTypeConsistent2(TYPECONST Type * type,const EDIType * aEDIType)618 bool SmartType::isTypeConsistent2(TYPECONST Type *type, const EDIType *aEDIType) {
619     /* Exception-handling based isTypeConsistent(). Broken with -fno-exceptions. */
620     static std::vector<TYPECONST Type*> nestedTypes;
621     static std::vector<const EDIType*> nestedEDITypes;
622     static unsigned level = 0;
623 
624     if(level == 0) {
625         nestedTypes.clear();
626         nestedEDITypes.clear();
627     }
628 
629     bool checkTypeConsistent = false;
630     bool useExceptions = true;
631     level++;
632     assert(useExceptions);
633     TRY(
634         const SmartType aSmartType(type, aEDIType, useExceptions);
635         checkTypeConsistent = isTypeConsistent2(nestedTypes, nestedEDITypes, &aSmartType);
636     )
637     CATCH(std::exception& e,
638         checkTypeConsistent = false;
639     )
640     level--;
641     return checkTypeConsistent;
642 }
643 
isTypeConsistent(TYPECONST Type * type,const EDIType * aEDIType,bool useBfas,int * weakConsistencyLevel)644 bool SmartType::isTypeConsistent(TYPECONST Type *type, const EDIType *aEDIType, bool useBfas, int *weakConsistencyLevel) {
645     static std::vector<TYPECONST Type*> nestedTypes;
646     static std::vector<const EDIType*> nestedEDITypes;
647     static unsigned level = 0;
648 
649     if(level == 0) {
650         if(weakConsistencyLevel) {
651             *weakConsistencyLevel = INT_MAX;
652         }
653     }
654 
655     if(aEDIType->isPointerTy() || aEDIType->isUnionOrStructTy()) {
656         for(unsigned j=0;j<nestedTypes.size();j++) {
657             if(nestedTypes[j] == type && nestedEDITypes[j]->equals(aEDIType)) {
658                 return true;
659             }
660         }
661     }
662 
663     unsigned nTypes = type->getNumContainedTypes();
664     unsigned nEDITypes = aEDIType->getNumContainedTypes();
665     if(nTypes == 0 || nEDITypes == 0) {
666         if(nTypes != 0 || nEDITypes != 0) {
667             return false;
668         }
669         return isRawTypeConsistent(type, aEDIType);
670     }
671 
672     if(aEDIType->isOpaqueTy()) {
673         return (TypeUtil::isOpaqueTy(type));
674     }
675 
676     bool isArrayOrVectorTy = aEDIType->isArrayTy() || aEDIType->isVectorTy();
677     unsigned nEDINumElements = aEDIType->getNumElements();
678     if(aEDIType->isDerivedType() || isArrayOrVectorTy) {
679         TYPECONST Type *nextType = type;
680         if(aEDIType->isPointerTy()) {
681             if(!type->isPointerTy()) {
682                 return false;
683             }
684             nextType = type->getContainedType(0);
685         }
686         else if(aEDIType->isArrayTy()) {
687             if(!type->isArrayTy() || ((ArrayType*)type)->getNumElements() != nEDINumElements) {
688                 return false;
689             }
690             nextType = type->getContainedType(0);
691         }
692         else if(aEDIType->isVectorTy()) {
693             if(!type->isVectorTy() || ((VectorType*)type)->getNumElements() != nEDINumElements) {
694                 return false;
695             }
696             nextType = type->getContainedType(0);
697         }
698         const EDIType aEDISubType(aEDIType->getContainedType(0));
699         nestedEDITypes.push_back(aEDIType);
700         nestedTypes.push_back(type);
701         level++;
702         bool ret = isTypeConsistent(nextType, &aEDISubType, useBfas, weakConsistencyLevel);
703         level--;
704         nestedTypes.pop_back();
705         nestedEDITypes.pop_back();
706         return ret;
707     }
708     else if(aEDIType->isCompositeType()) {
709         if(!aEDIType->isUnionOrStructTy() && !aEDIType->isVectorTy() && !aEDIType->isFunctionTy()) {
710             return false;
711         }
712         if(aEDIType->isUnionOrStructTy() && !type->isStructTy()) {
713             return false;
714         }
715         if(aEDIType->isVectorTy() && !type->isVectorTy()) {
716             return false;
717         }
718         if(aEDIType->isFunctionTy() && !type->isFunctionTy()) {
719             return false;
720         }
721         if(aEDIType->isUnionTy() || aEDIType->isFunctionTy()) {
722             if(weakConsistencyLevel) {
723                 *weakConsistencyLevel = level;
724             }
725             return true; //xxx we should be less conservative here
726         }
727         unsigned numContainedEDITypes = aEDIType->getNumContainedTypes();
728         std::vector<BitFieldAggregation> myBfas;
729         if(numContainedEDITypes != type->getNumContainedTypes()) {
730             if(!useBfas) {
731                 return false;
732             }
733             if(!BitFieldAggregation::getBitFieldAggregations(type, aEDIType, myBfas, true)) {
734                 return false;
735             }
736             for(unsigned i=0;i<myBfas.size();i++) {
737                 numContainedEDITypes -= (myBfas[i].getSize() - 1);
738             }
739             if(numContainedEDITypes != type->getNumContainedTypes()) {
740                 return false;
741             }
742             nestedEDITypes.push_back(aEDIType);
743             nestedTypes.push_back(type);
744             level++;
745             for(unsigned i=0;i<numContainedEDITypes;i++) {
746                 const EDIType aEDISubType(aEDIType->getContainedType(getBFAFreeIdx(i, myBfas)));
747                 if(!isTypeConsistent(type->getContainedType(i), &aEDISubType, useBfas, weakConsistencyLevel)) {
748                     level--;
749                     nestedTypes.pop_back();
750                     nestedEDITypes.pop_back();
751                     return false;
752                 }
753             }
754             level--;
755             nestedTypes.pop_back();
756             nestedEDITypes.pop_back();
757             return true;
758         }
759         nestedEDITypes.push_back(aEDIType);
760         nestedTypes.push_back(type);
761         level++;
762         for(unsigned i=0;i<numContainedEDITypes;i++) {
763             const EDIType aEDISubType(aEDIType->getContainedType(i));
764             if(!isTypeConsistent(type->getContainedType(i), &aEDISubType, useBfas, weakConsistencyLevel)) {
765                 level--;
766                 nestedTypes.pop_back();
767                 nestedEDITypes.pop_back();
768                 return false;
769             }
770         }
771         level--;
772         nestedTypes.pop_back();
773         nestedEDITypes.pop_back();
774         return true;
775     }
776     return false;
777 }
778 
779 std::vector<TYPECONST Type*> SmartType::equalsNestedTypes;
780 
781 }
782