Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
Line
Count
Source (jump to first uncovered line)
1
//===- TypeIndex.h ----------------------------------------------*- C++ -*-===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
10
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
11
12
#include "llvm/ADT/DenseMapInfo.h"
13
#include "llvm/Support/Endian.h"
14
#include <cassert>
15
#include <cinttypes>
16
#include <functional>
17
18
namespace llvm {
19
20
class ScopedPrinter;
21
22
namespace codeview {
23
24
class TypeCollection;
25
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
31
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
38
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
57
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
65
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
73
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
79
};
80
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
90
};
91
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.
95
class TypeIndex {
96
public:
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;
101
102
public:
103
65.5k
  TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
104
26.6k
  explicit TypeIndex(uint32_t Index) : Index(Index) {}
105
  explicit TypeIndex(SimpleTypeKind Kind)
106
102k
      : Index(static_cast<uint32_t>(Kind)) {}
107
  TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode)
108
4.51k
      : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
109
110
526k
  uint32_t getIndex() const { return Index; }
111
59.8k
  void setIndex(uint32_t I) { Index = I; }
112
98.7k
  bool isSimple() const { return Index < FirstNonSimpleIndex; }
113
  bool isDecoratedItemId() const { return !!(Index & DecoratedItemIdMask); }
114
115
86.2k
  bool isNoneType() const { return *this == None(); }
116
117
163k
  uint32_t toArrayIndex() const {
118
163k
    assert(!isSimple());
119
163k
    return getIndex() - FirstNonSimpleIndex;
120
163k
  }
121
122
17.8k
  static TypeIndex fromArrayIndex(uint32_t Index) {
123
17.8k
    return TypeIndex(Index + FirstNonSimpleIndex);
124
17.8k
  }
125
126
49.7k
  SimpleTypeKind getSimpleKind() const {
127
49.7k
    assert(isSimple());
128
49.7k
    return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
129
49.7k
  }
130
131
4.59k
  SimpleTypeMode getSimpleMode() const {
132
4.59k
    assert(isSimple());
133
4.59k
    return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
134
4.59k
  }
135
136
  TypeIndex makeDirect() const { return TypeIndex{getSimpleKind()}; }
137
138
92.6k
  static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); }
139
909
  static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); }
140
0
  static TypeIndex VoidPointer32() {
141
0
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32);
142
0
  }
143
0
  static TypeIndex VoidPointer64() {
144
0
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64);
145
0
  }
146
147
4.49k
  static TypeIndex NullptrT() {
148
4.49k
    // std::nullptr_t uses the pointer mode that doesn't indicate bit-width,
149
4.49k
    // presumably because std::nullptr_t is intended to be compatible with any
150
4.49k
    // pointer type.
151
4.49k
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer);
152
4.49k
  }
153
154
0
  static TypeIndex SignedCharacter() {
155
0
    return TypeIndex(SimpleTypeKind::SignedCharacter);
156
0
  }
157
0
  static TypeIndex UnsignedCharacter() {
158
0
    return TypeIndex(SimpleTypeKind::UnsignedCharacter);
159
0
  }
160
0
  static TypeIndex NarrowCharacter() {
161
0
    return TypeIndex(SimpleTypeKind::NarrowCharacter);
162
0
  }
163
0
  static TypeIndex WideCharacter() {
164
0
    return TypeIndex(SimpleTypeKind::WideCharacter);
165
0
  }
166
0
  static TypeIndex Int16Short() {
167
0
    return TypeIndex(SimpleTypeKind::Int16Short);
168
0
  }
169
0
  static TypeIndex UInt16Short() {
170
0
    return TypeIndex(SimpleTypeKind::UInt16Short);
171
0
  }
172
75
  static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); }
173
  static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); }
174
0
  static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); }
175
0
  static TypeIndex UInt32Long() {
176
0
    return TypeIndex(SimpleTypeKind::UInt32Long);
177
0
  }
178
0
  static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); }
179
0
  static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); }
180
0
  static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); }
181
0
  static TypeIndex UInt64Quad() {
182
0
    return TypeIndex(SimpleTypeKind::UInt64Quad);
183
0
  }
184
185
  static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
186
  static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
187
188
  TypeIndex &operator+=(unsigned N) {
189
    Index += N;
190
    return *this;
191
  }
192
193
33.3k
  TypeIndex &operator++() {
194
33.3k
    Index += 1;
195
33.3k
    return *this;
196
33.3k
  }
197
198
4.26k
  TypeIndex operator++(int) {
199
4.26k
    TypeIndex Copy = *this;
200
4.26k
    operator++();
201
4.26k
    return Copy;
202
4.26k
  }
203
204
0
  TypeIndex &operator-=(unsigned N) {
205
0
    assert(Index >= N);
206
0
    Index -= N;
207
0
    return *this;
208
0
  }
209
210
0
  TypeIndex &operator--() {
211
0
    Index -= 1;
212
0
    return *this;
213
0
  }
214
215
0
  TypeIndex operator--(int) {
216
0
    TypeIndex Copy = *this;
217
0
    operator--();
218
0
    return Copy;
219
0
  }
220
221
115k
  friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
222
115k
    return A.getIndex() == B.getIndex();
223
115k
  }
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 bool operator<=(const TypeIndex &A, const TypeIndex &B) {
234
    return A.getIndex() <= B.getIndex();
235
  }
236
237
0
  friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
238
0
    return A.getIndex() > B.getIndex();
239
0
  }
240
241
0
  friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
242
0
    return A.getIndex() >= B.getIndex();
243
0
  }
244
245
  friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
246
    TypeIndex Result(A);
247
    Result += N;
248
    return Result;
249
  }
250
251
0
  friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
252
0
    assert(A.getIndex() >= N);
253
0
    TypeIndex Result(A);
254
0
    Result -= N;
255
0
    return Result;
256
0
  }
257
258
0
  friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
259
0
    assert(A >= B);
260
0
    return A.toArrayIndex() - B.toArrayIndex();
261
0
  }
262
263
  static StringRef simpleTypeName(TypeIndex TI);
264
265
private:
266
  support::ulittle32_t Index;
267
};
268
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 {
273
  TypeIndex Type;
274
  support::ulittle32_t Offset;
275
};
276
277
void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
278
                    TypeCollection &Types);
279
}
280
281
template <> struct DenseMapInfo<codeview::TypeIndex> {
282
  static inline codeview::TypeIndex getEmptyKey() {
283
    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
284
  }
285
  static inline codeview::TypeIndex getTombstoneKey() {
286
    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
287
  }
288
  static unsigned getHashValue(const codeview::TypeIndex &TI) {
289
    return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
290
  }
291
  static bool isEqual(const codeview::TypeIndex &LHS,
292
                      const codeview::TypeIndex &RHS) {
293
    return LHS == RHS;
294
  }
295
};
296
297
} // namespace llvm
298
299
#endif