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