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
getType()115 inline TYPECONST Type *SmartType::getType() const {
116 return type;
117 }
118
getEDIType()119 inline const EDIType *SmartType::getEDIType() const {
120 return &aEDIType;
121 }
122
isTypeConsistent()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
hasInnerPointers()133 inline bool SmartType::hasInnerPointers() const {
134 return aEDIType.hasInnerPointers();
135 }
136
isVoidTy()137 inline bool SmartType::isVoidTy() const {
138 return isTy(type->isVoidTy(), aEDIType.isVoidTy(), "isVoidTy");
139 }
140
isPrimitiveTy()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
isAggregateType()149 inline bool SmartType::isAggregateType() const {
150 return isTy(type->isAggregateType(), aEDIType.isAggregateType(), "isAggregateType");
151 }
152
isFunctionTy()153 inline bool SmartType::isFunctionTy() const {
154 if(isOpaqueTy()) {
155 return false;
156 }
157 return isTy(type->isFunctionTy(), aEDIType.isFunctionTy(), "isFunctionTy");
158 }
159
isStructTy()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
isArrayTy()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
isPointerTy()184 inline bool SmartType::isPointerTy() const {
185 return isTy(type->isPointerTy(), aEDIType.isPointerTy(), "isPointerTy");
186 }
187
isOpaqueTy()188 inline bool SmartType::isOpaqueTy() const {
189 return TypeUtil::isOpaqueTy(type) || aEDIType.isOpaqueTy();
190 }
191
isPaddedTy()192 inline bool SmartType::isPaddedTy() const {
193 if(!isAggregateType() || hasRawTypeRepresentation()) {
194 return false;
195 }
196 return TypeUtil::isPaddedType(type);
197 }
198
getNumElements()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
isUseExceptions()220 inline bool SmartType::isUseExceptions() const {
221 return useExceptions;
222 }
223
verifyTy()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
hasRawTypeRepresentation()237 inline bool SmartType::hasRawTypeRepresentation() const {
238 return rawTypeRepresentation;
239 }
240
241 }
242
243 #endif
244