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 
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 
118 inline unsigned EDIType::getNumDimensions() const {
119     return isArrayTy() || isVectorTy() ? getTypeArray().getNumElements() : 1;
120 }
121 
122 inline void EDIType::setCurrentDimension(unsigned dimension) {
123     assert(dimension < getNumDimensions());
124     this->currentDimension = dimension;
125 }
126 
127 inline unsigned EDIType::getCurrentDimension() const {
128     return currentDimension;
129 }
130 
131 inline const DIType *EDIType::getDIType() const {
132     return &aDIType;
133 }
134 
135 inline StringRef EDIType::getName() const {
136     return myName;
137 }
138 
139 inline std::vector<StringRef> EDIType::getNames() const {
140     return myNames;
141 }
142 
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 
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 
168 inline unsigned EDIType::getTag()const {
169     return aDIType.getTag();
170 }
171 
172 inline EDIType EDIType::getTypeDerivedFrom() const {
173     EDIType_assert(isDerivedType() || isCompositeType());
174     EDIType subType(PassUtil::getDITypeDerivedFrom((const DIDerivedType)aDIType));
175     return subType;
176 }
177 
178 inline bool EDIType::isType() const {
179     return aDIType.isType() || isVoidTy();
180 }
181 
182 inline bool EDIType::isBasicType() const {
183     return aDIType.isBasicType();
184 }
185 
186 inline bool EDIType::isDerivedType() const {
187     return aDIType.isDerivedType() && !aDIType.isCompositeType();
188 }
189 
190 inline bool EDIType::isCompositeType() const {
191     return aDIType.isCompositeType();
192 }
193 
194 inline bool EDIType::isPrimitiveType() const {
195     return (isVoidTy() || isFloatingPointTy());
196 }
197 
198 inline bool EDIType::isAggregateType() const {
199     return isUnionOrStructTy() || isArrayTy() || isVectorTy();
200 }
201 
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 
206 inline bool EDIType::isComplexFloatingPointTy() const {
207     if(!isBasicType()) return false;
208     return (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_complex_float);
209 }
210 
211 inline bool EDIType::isFloatingPointTy() const {
212     if(!isBasicType()) return false;
213     return EDIType::isComplexFloatingPointTy() || (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_float);
214 }
215 
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 
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 
228 inline bool EDIType::isBoolTy() const {
229     if(!isBasicType()) return false;
230     return (((DIBasicType)aDIType).getEncoding() == dwarf::DW_ATE_boolean);
231 }
232 
233 inline bool EDIType::isIntegerTy() const {
234     return (isCharTy() || isIntTy() || isBoolTy());
235 }
236 
237 inline bool EDIType::isFunctionTy() const {
238     return (getTag() == dwarf::DW_TAG_subroutine_type && !isOpaqueTy());
239 }
240 
241 inline bool EDIType::isArrayTy() const {
242     return (getTag() == dwarf::DW_TAG_array_type && !isOpaqueTy());
243 }
244 
245 inline bool EDIType::isEnumTy() const {
246     return (getTag() == dwarf::DW_TAG_enumeration_type && !isOpaqueTy());
247 }
248 
249 inline bool EDIType::isVectorTy() const {
250     return (PassUtil::isDbgVectorTy(aDIType) && !isOpaqueTy());
251 }
252 
253 inline bool EDIType::isUnionTy() const {
254     return isUnionOrStructTy(false, true);
255 }
256 
257 inline bool EDIType::isStructTy() const {
258     return isUnionOrStructTy(true, false);
259 }
260 
261 inline bool EDIType::isPointerTy() const {
262     return (getTag() == dwarf::DW_TAG_pointer_type);
263 }
264 
265 inline bool EDIType::isOpaqueTy() const {
266     return (isCompositeType() && getTypeArrayNum() == 0);
267 }
268 
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