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