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