1 #ifndef SMART_TYPE_H 2 #define SMART_TYPE_H 3 4 #include <pass.h> 5 #include <magic/support/EDIType.h> 6 #include <magic/support/TypeUtil.h> 7 #include <magic/support/BitFieldAggregation.h> 8 9 using namespace llvm; 10 11 namespace llvm { 12 13 #define SmartTypeLog(M) DEBUG(dbgs() << "SmartType: " << M << "\n") 14 #define SmartTypeErr(M) errs() << "SmartType: " << M << "\n" 15 16 #if HAVE_EXCEPTIONS 17 #define THROW(E) throw E 18 #define TRY(B) try{ B } 19 #define CATCH(E, B) catch(E){ B } 20 #else 21 #define THROW(E) assert(0 && "throw: Exceptions disabled") 22 #define TRY(B) assert(0 && "try: Exceptions disabled"); 23 #define CATCH(E, B) assert(0 && "catch: Exceptions disabled"); 24 #endif 25 26 #define SmartType_assert(X) do { \ 27 if(!(X)) { \ 28 if(useExceptions) { \ 29 THROW(std::exception()); \ 30 } \ 31 errs() << "Assertion failed, dumping object...\n"; \ 32 errs() << "Name is: " << this->aEDIType.getName() << "\n"; \ 33 errs() << *this; \ 34 } \ 35 assert(X); \ 36 } while(0) 37 38 class SmartType { 39 public: 40 SmartType(const SmartType& et); 41 SmartType(TYPECONST Type *type, const DIType *aDIType, bool useExceptions=false, bool forceRawTypeRepresentation=false); 42 SmartType(TYPECONST Type *type, const EDIType *aEDIType, bool useExceptions=false, bool forceRawTypeRepresentation=false); 43 ~SmartType(); 44 45 SmartType& operator=(const SmartType& et); 46 void cloneFrom(const SmartType& et); 47 48 const std::string getDescription() const; 49 const SmartType* getContainedType(unsigned i) const; 50 unsigned getNumContainedTypes() const; 51 const DIDerivedType& getMember(unsigned i) const; 52 unsigned getUnionMemberIdx() const; 53 const SmartType* getTopStructType(unsigned index) const; 54 55 TYPECONST Type *getType() const; 56 const EDIType *getEDIType() const; 57 bool isTypeConsistent() const; 58 bool hasInnerPointers() const; 59 bool isVoidTy() const; 60 bool isPrimitiveTy() const; 61 bool isAggregateType() const; 62 bool isFunctionTy() const; 63 bool isStructTy() const; 64 bool isArrayTy() const; 65 bool isPointerTy() const; 66 bool isOpaqueTy() const; 67 bool isPaddedTy() const; 68 unsigned getNumElements() const; 69 bool isUseExceptions() const; 70 71 void verify() const; 72 bool verifyTy() const; 73 void print(raw_ostream &OS) const; 74 bool equals(const SmartType* other, bool isDebug=false) const; 75 bool hasRawTypeRepresentation() const; 76 77 static const SmartType* getSmartTypeFromGV(Module &M, GlobalVariable *GV, DIGlobalVariable *DIG = NULL); 78 static const SmartType* getSmartTypeFromLV(Module &M, AllocaInst *AI, DIVariable *DIV = NULL); 79 static const SmartType* getSmartTypeFromFunction(Module &M, Function *F, DISubprogram *DIS = NULL); 80 static const SmartType* getStructSmartTypeByName(Module &M, GlobalVariable* GV, std::string &name, bool isUnion=false); 81 static std::vector<const SmartType*>* getTopStructSmartTypes(Module &M, GlobalVariable* GV); 82 static bool isTypeConsistent(TYPECONST Type *type, const EDIType *aEDIType, bool useBfas=true, int *weakConsistencyLevel=NULL); 83 84 private: 85 TYPECONST Type *type; 86 EDIType aEDIType; 87 bool hasExplicitContainedEDITypes; 88 bool isInconsistent; 89 std::vector<EDIType*> explicitContainedEDITypes; 90 std::vector<BitFieldAggregation> bfas; 91 bool useExceptions; 92 bool rawTypeRepresentation; 93 unsigned unionMemberIdx; 94 static std::vector<TYPECONST Type*> equalsNestedTypes; 95 static bool forceRawUnions; 96 static bool forceRawBitfields; 97 98 void init(TYPECONST Type *type, const EDIType *aEDIType, bool useExceptions, bool forceRawTypeRepresentation); 99 void normalize(); 100 void flattenFunctionTy(); 101 int flattenFunctionArgs(TYPECONST Type *type, const EDIType *aEDIType, unsigned nextContainedType); 102 bool isTy(bool isTyType, bool isTyEDIType, const char* source) const; 103 104 static unsigned getBFAFreeIdx(unsigned i, const std::vector<BitFieldAggregation> &inputBfas); 105 static bool isRawTypeConsistent(TYPECONST Type *type, const EDIType *aEDIType); 106 static bool isTypeConsistent2(TYPECONST Type *type, const EDIType *aEDIType); 107 static bool isTypeConsistent2(std::vector<TYPECONST Type*> &nestedTypes, std::vector<const EDIType*> &nestedEDITypes, const SmartType *aSmartType); 108 }; 109 110 inline raw_ostream &operator<<(raw_ostream &OS, const SmartType &aSmartType) { 111 aSmartType.print(OS); 112 return OS; 113 } 114 115 inline TYPECONST Type *SmartType::getType() const { 116 return type; 117 } 118 119 inline const EDIType *SmartType::getEDIType() const { 120 return &aEDIType; 121 } 122 123 inline bool SmartType::isTypeConsistent() const { 124 if(isInconsistent) { 125 return false; 126 } 127 if(isFunctionTy() || hasRawTypeRepresentation()) { 128 return true; 129 } 130 return isTypeConsistent(type, &aEDIType); 131 } 132 133 inline bool SmartType::hasInnerPointers() const { 134 return aEDIType.hasInnerPointers(); 135 } 136 137 inline bool SmartType::isVoidTy() const { 138 return isTy(type->isVoidTy(), aEDIType.isVoidTy(), "isVoidTy"); 139 } 140 141 inline bool SmartType::isPrimitiveTy() const { 142 if(aEDIType.isComplexFloatingPointTy()) { 143 assert(type->isStructTy()); 144 return true; 145 } 146 return isTy(PassUtil::isPrimitiveTy(type), aEDIType.isPrimitiveType(), "isPrimitiveTy"); 147 } 148 149 inline bool SmartType::isAggregateType() const { 150 return isTy(type->isAggregateType(), aEDIType.isAggregateType(), "isAggregateType"); 151 } 152 153 inline bool SmartType::isFunctionTy() const { 154 if(isOpaqueTy()) { 155 return false; 156 } 157 return isTy(type->isFunctionTy(), aEDIType.isFunctionTy(), "isFunctionTy"); 158 } 159 160 inline bool SmartType::isStructTy() const { 161 if(aEDIType.isComplexFloatingPointTy()) { 162 assert(type->isStructTy()); 163 return false; 164 } 165 if(aEDIType.isArrayTy() && TypeUtil::isArrayAsStructTy(type)) { 166 return false; 167 } 168 if(isOpaqueTy()) { 169 return false; 170 } 171 return isTy(type->isStructTy(), aEDIType.isUnionOrStructTy(), "isStructTy"); 172 } 173 174 inline bool SmartType::isArrayTy() const { 175 if(aEDIType.isArrayTy() && TypeUtil::isArrayAsStructTy(type)) { 176 return true; 177 } 178 if (hasRawTypeRepresentation()) { // only possible for structs and bitfields 179 return false; 180 } 181 return isTy(type->isArrayTy(), aEDIType.isArrayTy(), "isArrayTy"); 182 } 183 184 inline bool SmartType::isPointerTy() const { 185 return isTy(type->isPointerTy(), aEDIType.isPointerTy(), "isPointerTy"); 186 } 187 188 inline bool SmartType::isOpaqueTy() const { 189 return TypeUtil::isOpaqueTy(type) || aEDIType.isOpaqueTy(); 190 } 191 192 inline bool SmartType::isPaddedTy() const { 193 if(!isAggregateType() || hasRawTypeRepresentation()) { 194 return false; 195 } 196 return TypeUtil::isPaddedType(type); 197 } 198 199 inline unsigned SmartType::getNumElements() const { 200 if(!isArrayTy()) { 201 return 0; 202 } 203 unsigned EDINumElements = aEDIType.getNumElements(); 204 unsigned numElements; 205 if(type->isArrayTy()) { 206 numElements = ((ArrayType*)type)->getNumElements(); 207 } 208 else { 209 assert(type->isStructTy()); 210 numElements = type->getNumContainedTypes(); 211 } 212 if(numElements == 0) { 213 assert(EDINumElements <= 1 || EDINumElements==UINT_MAX); 214 return 0; 215 } 216 assert(numElements == EDINumElements); 217 return numElements; 218 } 219 220 inline bool SmartType::isUseExceptions() const { 221 return useExceptions; 222 } 223 224 inline bool SmartType::verifyTy() const { 225 if(isVoidTy()) return true; 226 if(isPrimitiveTy()) return true; 227 if(isAggregateType()) return true; 228 if(isFunctionTy()) return true; 229 if(isStructTy()) return true; 230 if(isArrayTy()) return true; 231 if(isPointerTy()) return true; 232 if(isOpaqueTy()) return true; 233 234 return false; 235 } 236 237 inline bool SmartType::hasRawTypeRepresentation() const { 238 return rawTypeRepresentation; 239 } 240 241 } 242 243 #endif 244