1 #ifndef EDITYPE_H
2 #define EDITYPE_H
3
4 #include <pass.h>
5
6 using namespace llvm;
7
8 namespace llvm {
9
10 #define EDITypeLog(M) DEBUG(dbgs() << "EDIType: " << M << "\n")
11 #define EDITypeErr(M) errs() << "EDIType: " << M << "\n"
12
13 #define EDIType_assert(X) do { \
14 if(!(X)) { \
15 errs() << "Assertion failed, dumping object...\n"; \
16 errs() << *this; \
17 } \
18 assert(X); \
19 } while(0)
20
21 class EDIType {
22 public:
23 EDIType(const MDNode *N, bool norm=true, bool checkOpaqueTypes=true);
24 EDIType(bool norm=false, bool checkOpaqueTypes=false);
25 EDIType(const DIType aDIType, bool norm=true, bool checkOpaqueTypes=true);
26
27 bool operator == (const EDIType& aEDIType) const;
28
29 static const bool NORMALIZE = true;
30 static const bool DO_NOT_NORMALIZE = false;
31 static const bool CHECK_OPAQUE_TYPES = true;
32 static const bool DO_NOT_CHECK_OPAQUE_TYPES = false;
33
34 const std::string getDescription(int skipUnions=0, int skipStructs=0, int allowMultiNames=0) const;
35 const EDIType& getContainedType(unsigned i, bool norm=true) const;
36 unsigned getNumContainedTypes() const;
37 const DIDerivedType& getMember(unsigned i) const;
38 bool isUnionOrStructTy(bool isStruct=true, bool isUnion=true) const;
39 bool hasInnerPointers() const;
40 unsigned int getTypeArrayNum() const;
41 DIArray getTypeArray() const;
42 const EDIType* getTopStructType(unsigned index) const;
43
44 unsigned getNumElements() const;
45 unsigned getNumDimensions() const;
46 void setCurrentDimension(unsigned dimension);
47 unsigned getCurrentDimension() const;
48 const DIType *getDIType() const;
49 StringRef getName() const;
50 std::vector<StringRef> getNames() const;
51 StringRef getNamesString() const;
52 std::vector<unsigned> getEnumValues() const;
53 unsigned getTag()const;
54 EDIType getTypeDerivedFrom() const;
55 bool isType() const;
56 bool isBasicType() const;
57 bool isDerivedType() const;
58 bool isCompositeType() const;
59 bool isPrimitiveType() const;
60 bool isAggregateType() const;
61 bool isVoidTy() const;
62 bool isComplexFloatingPointTy() const;
63 bool isFloatingPointTy() const;
64 bool isCharTy() const;
65 bool isIntTy() const;
66 bool isBoolTy() const;
67 bool isIntegerTy() const;
68 bool isFunctionTy() const;
69 bool isArrayTy() const;
70 bool isEnumTy() const;
71 bool isVectorTy() const;
72 bool isUnionTy() const;
73 bool isStructTy() const;
74 bool isPointerTy() const;
75 bool isOpaqueTy() const;
76
77 void print(raw_ostream &OS) const;
78 void printDescription(raw_ostream &OS, int skipUnions=0, int skipStructs=0, int allowMultiNames=0) const;
79 bool equals(const EDIType *other) const;
80
81 static std::string lookupTypedefName(std::string &name);
82 static std::string lookupUnionMemberName(TYPECONST Type* type);
83 static const EDIType* getStructEDITypeByName(std::string &name);
84 static void setModule(Module *M);
85 static void writeTypeSymbolic(raw_string_ostream &OS, TYPECONST Type *type, const Module *M);
86
87 private:
88 DIType aDIType;
89 unsigned currentDimension;
90 bool checkOpaqueTypes;
91 StringRef myName;
92 std::vector<StringRef> myNames;
93 static StringRef voidName;
94 static Module *module;
95 static DebugInfoFinder DIFinder;
96
97 void init(bool norm, bool checkOpaqueTypes);
98 void normalize();
99 void normalizeTypedef();
100 };
101
102 inline raw_ostream &operator<<(raw_ostream &OS, const EDIType &aEDIType) {
103 aEDIType.print(OS);
104 return OS;
105 }
106
getNumElements()107 inline unsigned EDIType::getNumElements() const {
108 if(!isArrayTy() && !isVectorTy()) {
109 return 1;
110 }
111 const DIArray aDIArray = getTypeArray();
112 const DIDescriptor aDIDescriptor = aDIArray.getElement(currentDimension);
113 assert(aDIDescriptor.getTag() == dwarf::DW_TAG_subrange_type);
114
115 return PassUtil::getDbgSubrangeNumElements((DISubrange)aDIDescriptor);
116 }
117
getNumDimensions()118 inline unsigned EDIType::getNumDimensions() const {
119 return isArrayTy() || isVectorTy() ? getTypeArray().getNumElements() : 1;
120 }
121
setCurrentDimension(unsigned dimension)122 inline void EDIType::setCurrentDimension(unsigned dimension) {
123 assert(dimension < getNumDimensions());
124 this->currentDimension = dimension;
125 }
126
getCurrentDimension()127 inline unsigned EDIType::getCurrentDimension() const {
128 return currentDimension;
129 }
130
getDIType()131 inline const DIType *EDIType::getDIType() const {
132 return &aDIType;
133 }
134
getName()135 inline StringRef EDIType::getName() const {
136 return myName;
137 }
138
getNames()139 inline std::vector<StringRef> EDIType::getNames() const {
140 return myNames;
141 }
142
getNamesString()143 inline StringRef EDIType::getNamesString() const {
144 std::string string;
145 raw_string_ostream ostream(string);
146 for(unsigned i=0;i<myNames.size();i++) {
147 if(i>0) ostream << "|";
148 ostream << myNames[i];
149 }
150 ostream.flush();
151 return string;
152 }
153
getEnumValues()154 inline std::vector<unsigned> EDIType::getEnumValues() const {
155 assert(isEnumTy());
156 std::vector<unsigned> enumValues;
157 DIArray aDIArray = getTypeArray();
158 unsigned numValues = aDIArray.getNumElements();
159 for(unsigned i=0;i<numValues;i++) {
160 DIDescriptor aDIDescriptor = aDIArray.getElement(i);
161 assert(aDIDescriptor.getTag() == dwarf::DW_TAG_enumerator);
162 const unsigned value = (unsigned) ((DIEnumerator)aDIDescriptor).getEnumValue();
163 enumValues.push_back(value);
164 }
165 return enumValues;
166 }
167
getTag()168 inline unsigned EDIType::getTag()const {
169 return aDIType.getTag();
170 }
171
getTypeDerivedFrom()172 inline EDIType EDIType::getTypeDerivedFrom() const {
173 EDIType_assert(isDerivedType() || isCompositeType());
174 EDIType subType(PassUtil::getDITypeDerivedFrom((const DIDerivedType)aDIType));
175 return subType;
176 }
177
isType()178 inline bool EDIType::isType() const {
179 return aDIType.isType() || isVoidTy();
180 }
181
isBasicType()182 inline bool EDIType::isBasicType() const {
183 return aDIType.isBasicType();
184 }
185
isDerivedType()186 inline bool EDIType::isDerivedType() const {
187 return aDIType.isDerivedType() && !aDIType.isCompositeType();
188 }
189
isCompositeType()190 inline bool EDIType::isCompositeType() const {
191 return aDIType.isCompositeType();
192 }
193
isPrimitiveType()194 inline bool EDIType::isPrimitiveType() const {
195 return (isVoidTy() || isFloatingPointTy());
196 }
197
isAggregateType()198 inline bool EDIType::isAggregateType() const {
199 return isUnionOrStructTy() || isArrayTy() || isVectorTy();
200 }
201
isVoidTy()202 inline bool EDIType::isVoidTy() const {
203 return !aDIType.isValid(); //xxx we should keep track of this to spot all the i8* = void*
204 }
205
isComplexFloatingPointTy()206 inline bool EDIType::isComplexFloatingPointTy() const {
207 if(!isBasicType()) return false;
208 return (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_complex_float);
209 }
210
isFloatingPointTy()211 inline bool EDIType::isFloatingPointTy() const {
212 if(!isBasicType()) return false;
213 return EDIType::isComplexFloatingPointTy() || (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_float);
214 }
215
isCharTy()216 inline bool EDIType::isCharTy() const {
217 if(!isBasicType()) return false;
218 return (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_signed_char ||
219 ((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_unsigned_char);
220 }
221
isIntTy()222 inline bool EDIType::isIntTy() const {
223 if(!isBasicType()) return false;
224 return (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_signed ||
225 ((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_unsigned);
226 }
227
isBoolTy()228 inline bool EDIType::isBoolTy() const {
229 if(!isBasicType()) return false;
230 return (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_boolean);
231 }
232
isIntegerTy()233 inline bool EDIType::isIntegerTy() const {
234 return (isCharTy() || isIntTy() || isBoolTy());
235 }
236
isFunctionTy()237 inline bool EDIType::isFunctionTy() const {
238 return (getTag() == dwarf::DW_TAG_subroutine_type && !isOpaqueTy());
239 }
240
isArrayTy()241 inline bool EDIType::isArrayTy() const {
242 return (getTag() == dwarf::DW_TAG_array_type && !isOpaqueTy());
243 }
244
isEnumTy()245 inline bool EDIType::isEnumTy() const {
246 return (getTag() == dwarf::DW_TAG_enumeration_type && !isOpaqueTy());
247 }
248
isVectorTy()249 inline bool EDIType::isVectorTy() const {
250 return (PassUtil::isDbgVectorTy(aDIType) && !isOpaqueTy());
251 }
252
isUnionTy()253 inline bool EDIType::isUnionTy() const {
254 return isUnionOrStructTy(false, true);
255 }
256
isStructTy()257 inline bool EDIType::isStructTy() const {
258 return isUnionOrStructTy(true, false);
259 }
260
isPointerTy()261 inline bool EDIType::isPointerTy() const {
262 return (getTag() == dwarf::DW_TAG_pointer_type);
263 }
264
isOpaqueTy()265 inline bool EDIType::isOpaqueTy() const {
266 return (isCompositeType() && getTypeArrayNum() == 0);
267 }
268
writeTypeSymbolic(raw_string_ostream & OS,TYPECONST Type * type,const Module * M)269 inline void EDIType::writeTypeSymbolic(raw_string_ostream &OS, TYPECONST Type *type, const Module *M) {
270 return PassUtil::writeTypeSymbolic(OS, type, M);
271 }
272
273 }
274
275 #endif
276