1 //===- TypeIndex.h ----------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
10 #define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
12 #include "llvm/ADT/DenseMapInfo.h"
13 #include "llvm/Support/Endian.h"
26 enum class SimpleTypeKind
: uint32_t {
27 None
= 0x0000, // uncharacterized type (no type)
28 Void
= 0x0003, // void
29 NotTranslated
= 0x0007, // type not translated by cvpack
30 HResult
= 0x0008, // OLE/COM HRESULT
32 SignedCharacter
= 0x0010, // 8 bit signed
33 UnsignedCharacter
= 0x0020, // 8 bit unsigned
34 NarrowCharacter
= 0x0070, // really a char
35 WideCharacter
= 0x0071, // wide char
36 Character16
= 0x007a, // char16_t
37 Character32
= 0x007b, // char32_t
39 SByte
= 0x0068, // 8 bit signed int
40 Byte
= 0x0069, // 8 bit unsigned int
41 Int16Short
= 0x0011, // 16 bit signed
42 UInt16Short
= 0x0021, // 16 bit unsigned
43 Int16
= 0x0072, // 16 bit signed int
44 UInt16
= 0x0073, // 16 bit unsigned int
45 Int32Long
= 0x0012, // 32 bit signed
46 UInt32Long
= 0x0022, // 32 bit unsigned
47 Int32
= 0x0074, // 32 bit signed int
48 UInt32
= 0x0075, // 32 bit unsigned int
49 Int64Quad
= 0x0013, // 64 bit signed
50 UInt64Quad
= 0x0023, // 64 bit unsigned
51 Int64
= 0x0076, // 64 bit signed int
52 UInt64
= 0x0077, // 64 bit unsigned int
53 Int128Oct
= 0x0014, // 128 bit signed int
54 UInt128Oct
= 0x0024, // 128 bit unsigned int
55 Int128
= 0x0078, // 128 bit signed int
56 UInt128
= 0x0079, // 128 bit unsigned int
58 Float16
= 0x0046, // 16 bit real
59 Float32
= 0x0040, // 32 bit real
60 Float32PartialPrecision
= 0x0045, // 32 bit PP real
61 Float48
= 0x0044, // 48 bit real
62 Float64
= 0x0041, // 64 bit real
63 Float80
= 0x0042, // 80 bit real
64 Float128
= 0x0043, // 128 bit real
66 Complex16
= 0x0056, // 16 bit complex
67 Complex32
= 0x0050, // 32 bit complex
68 Complex32PartialPrecision
= 0x0055, // 32 bit PP complex
69 Complex48
= 0x0054, // 48 bit complex
70 Complex64
= 0x0051, // 64 bit complex
71 Complex80
= 0x0052, // 80 bit complex
72 Complex128
= 0x0053, // 128 bit complex
74 Boolean8
= 0x0030, // 8 bit boolean
75 Boolean16
= 0x0031, // 16 bit boolean
76 Boolean32
= 0x0032, // 32 bit boolean
77 Boolean64
= 0x0033, // 64 bit boolean
78 Boolean128
= 0x0034, // 128 bit boolean
81 enum class SimpleTypeMode
: uint32_t {
82 Direct
= 0x00000000, // Not a pointer
83 NearPointer
= 0x00000100, // Near pointer
84 FarPointer
= 0x00000200, // Far pointer
85 HugePointer
= 0x00000300, // Huge pointer
86 NearPointer32
= 0x00000400, // 32 bit near pointer
87 FarPointer32
= 0x00000500, // 32 bit far pointer
88 NearPointer64
= 0x00000600, // 64 bit near pointer
89 NearPointer128
= 0x00000700 // 128 bit near pointer
92 /// A 32-bit type reference. Types are indexed by their order of appearance in
93 /// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types,
94 /// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte.
97 static const uint32_t FirstNonSimpleIndex
= 0x1000;
98 static const uint32_t SimpleKindMask
= 0x000000ff;
99 static const uint32_t SimpleModeMask
= 0x00000700;
100 static const uint32_t DecoratedItemIdMask
= 0x80000000;
103 TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None
)) {}
104 explicit TypeIndex(uint32_t Index
) : Index(Index
) {}
105 explicit TypeIndex(SimpleTypeKind Kind
)
106 : Index(static_cast<uint32_t>(Kind
)) {}
107 TypeIndex(SimpleTypeKind Kind
, SimpleTypeMode Mode
)
108 : Index(static_cast<uint32_t>(Kind
) | static_cast<uint32_t>(Mode
)) {}
110 uint32_t getIndex() const { return Index
; }
111 void setIndex(uint32_t I
) { Index
= I
; }
112 bool isSimple() const { return Index
< FirstNonSimpleIndex
; }
113 bool isDecoratedItemId() const { return !!(Index
& DecoratedItemIdMask
); }
115 bool isNoneType() const { return *this == None(); }
117 uint32_t toArrayIndex() const {
119 return getIndex() - FirstNonSimpleIndex
;
122 static TypeIndex
fromArrayIndex(uint32_t Index
) {
123 return TypeIndex(Index
+ FirstNonSimpleIndex
);
126 SimpleTypeKind
getSimpleKind() const {
128 return static_cast<SimpleTypeKind
>(Index
& SimpleKindMask
);
131 SimpleTypeMode
getSimpleMode() const {
133 return static_cast<SimpleTypeMode
>(Index
& SimpleModeMask
);
136 TypeIndex
makeDirect() const { return TypeIndex
{getSimpleKind()}; }
138 static TypeIndex
None() { return TypeIndex(SimpleTypeKind::None
); }
139 static TypeIndex
Void() { return TypeIndex(SimpleTypeKind::Void
); }
140 static TypeIndex
VoidPointer32() {
141 return TypeIndex(SimpleTypeKind::Void
, SimpleTypeMode::NearPointer32
);
143 static TypeIndex
VoidPointer64() {
144 return TypeIndex(SimpleTypeKind::Void
, SimpleTypeMode::NearPointer64
);
147 static TypeIndex
NullptrT() {
148 // std::nullptr_t uses the pointer mode that doesn't indicate bit-width,
149 // presumably because std::nullptr_t is intended to be compatible with any
151 return TypeIndex(SimpleTypeKind::Void
, SimpleTypeMode::NearPointer
);
154 static TypeIndex
SignedCharacter() {
155 return TypeIndex(SimpleTypeKind::SignedCharacter
);
157 static TypeIndex
UnsignedCharacter() {
158 return TypeIndex(SimpleTypeKind::UnsignedCharacter
);
160 static TypeIndex
NarrowCharacter() {
161 return TypeIndex(SimpleTypeKind::NarrowCharacter
);
163 static TypeIndex
WideCharacter() {
164 return TypeIndex(SimpleTypeKind::WideCharacter
);
166 static TypeIndex
Int16Short() {
167 return TypeIndex(SimpleTypeKind::Int16Short
);
169 static TypeIndex
UInt16Short() {
170 return TypeIndex(SimpleTypeKind::UInt16Short
);
172 static TypeIndex
Int32() { return TypeIndex(SimpleTypeKind::Int32
); }
173 static TypeIndex
UInt32() { return TypeIndex(SimpleTypeKind::UInt32
); }
174 static TypeIndex
Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long
); }
175 static TypeIndex
UInt32Long() {
176 return TypeIndex(SimpleTypeKind::UInt32Long
);
178 static TypeIndex
Int64() { return TypeIndex(SimpleTypeKind::Int64
); }
179 static TypeIndex
UInt64() { return TypeIndex(SimpleTypeKind::UInt64
); }
180 static TypeIndex
Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad
); }
181 static TypeIndex
UInt64Quad() {
182 return TypeIndex(SimpleTypeKind::UInt64Quad
);
185 static TypeIndex
Float32() { return TypeIndex(SimpleTypeKind::Float32
); }
186 static TypeIndex
Float64() { return TypeIndex(SimpleTypeKind::Float64
); }
188 TypeIndex
&operator+=(unsigned N
) {
193 TypeIndex
&operator++() {
198 TypeIndex
operator++(int) {
199 TypeIndex Copy
= *this;
204 TypeIndex
&operator-=(unsigned N
) {
210 TypeIndex
&operator--() {
215 TypeIndex
operator--(int) {
216 TypeIndex Copy
= *this;
221 friend inline bool operator==(const TypeIndex
&A
, const TypeIndex
&B
) {
222 return A
.getIndex() == B
.getIndex();
225 friend inline bool operator!=(const TypeIndex
&A
, const TypeIndex
&B
) {
226 return A
.getIndex() != B
.getIndex();
229 friend inline bool operator<(const TypeIndex
&A
, const TypeIndex
&B
) {
230 return A
.getIndex() < B
.getIndex();
233 friend inline bool operator<=(const TypeIndex
&A
, const TypeIndex
&B
) {
234 return A
.getIndex() <= B
.getIndex();
237 friend inline bool operator>(const TypeIndex
&A
, const TypeIndex
&B
) {
238 return A
.getIndex() > B
.getIndex();
241 friend inline bool operator>=(const TypeIndex
&A
, const TypeIndex
&B
) {
242 return A
.getIndex() >= B
.getIndex();
245 friend inline TypeIndex
operator+(const TypeIndex
&A
, uint32_t N
) {
251 friend inline TypeIndex
operator-(const TypeIndex
&A
, uint32_t N
) {
252 assert(A
.getIndex() >= N
);
258 friend inline uint32_t operator-(const TypeIndex
&A
, const TypeIndex
&B
) {
260 return A
.toArrayIndex() - B
.toArrayIndex();
263 static StringRef
simpleTypeName(TypeIndex TI
);
266 support::ulittle32_t Index
;
269 // Used for pseudo-indexing an array of type records. An array of such records
270 // sorted by TypeIndex can allow log(N) lookups even though such a type record
271 // stream does not provide random access.
272 struct TypeIndexOffset
{
274 support::ulittle32_t Offset
;
277 void printTypeIndex(ScopedPrinter
&Printer
, StringRef FieldName
, TypeIndex TI
,
278 TypeCollection
&Types
);
281 template <> struct DenseMapInfo
<codeview::TypeIndex
> {
282 static inline codeview::TypeIndex
getEmptyKey() {
283 return codeview::TypeIndex
{DenseMapInfo
<uint32_t>::getEmptyKey()};
285 static inline codeview::TypeIndex
getTombstoneKey() {
286 return codeview::TypeIndex
{DenseMapInfo
<uint32_t>::getTombstoneKey()};
288 static unsigned getHashValue(const codeview::TypeIndex
&TI
) {
289 return DenseMapInfo
<uint32_t>::getHashValue(TI
.getIndex());
291 static bool isEqual(const codeview::TypeIndex
&LHS
,
292 const codeview::TypeIndex
&RHS
) {