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