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