1 //===- TypeIndex.h ----------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H 11 #define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H 12 13 #include "llvm/Support/Endian.h" 14 #include <cassert> 15 #include <cinttypes> 16 17 namespace llvm { 18 19 class ScopedPrinter; 20 21 namespace codeview { 22 23 class TypeCollection; 24 25 enum class SimpleTypeKind : uint32_t { 26 None = 0x0000, // uncharacterized type (no type) 27 Void = 0x0003, // void 28 NotTranslated = 0x0007, // type not translated by cvpack 29 HResult = 0x0008, // OLE/COM HRESULT 30 31 SignedCharacter = 0x0010, // 8 bit signed 32 UnsignedCharacter = 0x0020, // 8 bit unsigned 33 NarrowCharacter = 0x0070, // really a char 34 WideCharacter = 0x0071, // wide char 35 Character16 = 0x007a, // char16_t 36 Character32 = 0x007b, // char32_t 37 38 SByte = 0x0068, // 8 bit signed int 39 Byte = 0x0069, // 8 bit unsigned int 40 Int16Short = 0x0011, // 16 bit signed 41 UInt16Short = 0x0021, // 16 bit unsigned 42 Int16 = 0x0072, // 16 bit signed int 43 UInt16 = 0x0073, // 16 bit unsigned int 44 Int32Long = 0x0012, // 32 bit signed 45 UInt32Long = 0x0022, // 32 bit unsigned 46 Int32 = 0x0074, // 32 bit signed int 47 UInt32 = 0x0075, // 32 bit unsigned int 48 Int64Quad = 0x0013, // 64 bit signed 49 UInt64Quad = 0x0023, // 64 bit unsigned 50 Int64 = 0x0076, // 64 bit signed int 51 UInt64 = 0x0077, // 64 bit unsigned int 52 Int128Oct = 0x0014, // 128 bit signed int 53 UInt128Oct = 0x0024, // 128 bit unsigned int 54 Int128 = 0x0078, // 128 bit signed int 55 UInt128 = 0x0079, // 128 bit unsigned int 56 57 Float16 = 0x0046, // 16 bit real 58 Float32 = 0x0040, // 32 bit real 59 Float32PartialPrecision = 0x0045, // 32 bit PP real 60 Float48 = 0x0044, // 48 bit real 61 Float64 = 0x0041, // 64 bit real 62 Float80 = 0x0042, // 80 bit real 63 Float128 = 0x0043, // 128 bit real 64 65 Complex16 = 0x0056, // 16 bit complex 66 Complex32 = 0x0050, // 32 bit complex 67 Complex32PartialPrecision = 0x0055, // 32 bit PP complex 68 Complex48 = 0x0054, // 48 bit complex 69 Complex64 = 0x0051, // 64 bit complex 70 Complex80 = 0x0052, // 80 bit complex 71 Complex128 = 0x0053, // 128 bit complex 72 73 Boolean8 = 0x0030, // 8 bit boolean 74 Boolean16 = 0x0031, // 16 bit boolean 75 Boolean32 = 0x0032, // 32 bit boolean 76 Boolean64 = 0x0033, // 64 bit boolean 77 Boolean128 = 0x0034, // 128 bit boolean 78 }; 79 80 enum class SimpleTypeMode : uint32_t { 81 Direct = 0x00000000, // Not a pointer 82 NearPointer = 0x00000100, // Near pointer 83 FarPointer = 0x00000200, // Far pointer 84 HugePointer = 0x00000300, // Huge pointer 85 NearPointer32 = 0x00000400, // 32 bit near pointer 86 FarPointer32 = 0x00000500, // 32 bit far pointer 87 NearPointer64 = 0x00000600, // 64 bit near pointer 88 NearPointer128 = 0x00000700 // 128 bit near pointer 89 }; 90 91 /// A 32-bit type reference. Types are indexed by their order of appearance in 92 /// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types, 93 /// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte. 94 class TypeIndex { 95 public: 96 static const uint32_t FirstNonSimpleIndex = 0x1000; 97 static const uint32_t SimpleKindMask = 0x000000ff; 98 static const uint32_t SimpleModeMask = 0x00000700; 99 100 public: 101 TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {} 102 explicit TypeIndex(uint32_t Index) : Index(Index) {} 103 explicit TypeIndex(SimpleTypeKind Kind) 104 : Index(static_cast<uint32_t>(Kind)) {} 105 TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode) 106 : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {} 107 108 uint32_t getIndex() const { return Index; } 109 void setIndex(uint32_t I) { Index = I; } 110 bool isSimple() const { return Index < FirstNonSimpleIndex; } 111 112 bool isNoneType() const { return *this == None(); } 113 114 uint32_t toArrayIndex() const { 115 assert(!isSimple()); 116 return getIndex() - FirstNonSimpleIndex; 117 } 118 119 static TypeIndex fromArrayIndex(uint32_t Index) { 120 return TypeIndex(Index + FirstNonSimpleIndex); 121 } 122 123 SimpleTypeKind getSimpleKind() const { 124 assert(isSimple()); 125 return static_cast<SimpleTypeKind>(Index & SimpleKindMask); 126 } 127 128 SimpleTypeMode getSimpleMode() const { 129 assert(isSimple()); 130 return static_cast<SimpleTypeMode>(Index & SimpleModeMask); 131 } 132 133 static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); } 134 static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); } 135 static TypeIndex VoidPointer32() { 136 return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32); 137 } 138 static TypeIndex VoidPointer64() { 139 return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64); 140 } 141 142 static TypeIndex SignedCharacter() { 143 return TypeIndex(SimpleTypeKind::SignedCharacter); 144 } 145 static TypeIndex UnsignedCharacter() { 146 return TypeIndex(SimpleTypeKind::UnsignedCharacter); 147 } 148 static TypeIndex NarrowCharacter() { 149 return TypeIndex(SimpleTypeKind::NarrowCharacter); 150 } 151 static TypeIndex WideCharacter() { 152 return TypeIndex(SimpleTypeKind::WideCharacter); 153 } 154 static TypeIndex Int16Short() { 155 return TypeIndex(SimpleTypeKind::Int16Short); 156 } 157 static TypeIndex UInt16Short() { 158 return TypeIndex(SimpleTypeKind::UInt16Short); 159 } 160 static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); } 161 static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); } 162 static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); } 163 static TypeIndex UInt32Long() { 164 return TypeIndex(SimpleTypeKind::UInt32Long); 165 } 166 static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); } 167 static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); } 168 static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); } 169 static TypeIndex UInt64Quad() { 170 return TypeIndex(SimpleTypeKind::UInt64Quad); 171 } 172 173 static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); } 174 static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); } 175 176 TypeIndex &operator+=(unsigned N) { 177 Index += N; 178 return *this; 179 } 180 181 TypeIndex &operator++() { 182 Index += 1; 183 return *this; 184 } 185 186 TypeIndex operator++(int) { 187 TypeIndex Copy = *this; 188 operator++(); 189 return Copy; 190 } 191 192 TypeIndex &operator-=(unsigned N) { 193 assert(Index >= N); 194 Index -= N; 195 return *this; 196 } 197 198 TypeIndex &operator--() { 199 Index -= 1; 200 return *this; 201 } 202 203 TypeIndex operator--(int) { 204 TypeIndex Copy = *this; 205 operator--(); 206 return Copy; 207 } 208 209 friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) { 210 return A.getIndex() == B.getIndex(); 211 } 212 213 friend inline bool operator!=(const TypeIndex &A, const TypeIndex &B) { 214 return A.getIndex() != B.getIndex(); 215 } 216 217 friend inline bool operator<(const TypeIndex &A, const TypeIndex &B) { 218 return A.getIndex() < B.getIndex(); 219 } 220 221 friend inline bool operator<=(const TypeIndex &A, const TypeIndex &B) { 222 return A.getIndex() <= B.getIndex(); 223 } 224 225 friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) { 226 return A.getIndex() > B.getIndex(); 227 } 228 229 friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) { 230 return A.getIndex() >= B.getIndex(); 231 } 232 233 friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) { 234 TypeIndex Result(A); 235 Result += N; 236 return Result; 237 } 238 239 friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) { 240 assert(A.getIndex() >= N); 241 TypeIndex Result(A); 242 Result -= N; 243 return Result; 244 } 245 246 friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) { 247 assert(A >= B); 248 return A.toArrayIndex() - B.toArrayIndex(); 249 } 250 251 static StringRef simpleTypeName(TypeIndex TI); 252 253 private: 254 support::ulittle32_t Index; 255 }; 256 257 // Used for pseudo-indexing an array of type records. An array of such records 258 // sorted by TypeIndex can allow log(N) lookups even though such a type record 259 // stream does not provide random access. 260 struct TypeIndexOffset { 261 TypeIndex Type; 262 support::ulittle32_t Offset; 263 }; 264 265 void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, 266 TypeCollection &Types); 267 } 268 } 269 270 #endif 271