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