Coverage Report

Created: 2018-11-12 17:33

/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
//                     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
49.9k
  TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
105
22.1k
  explicit TypeIndex(uint32_t Index) : Index(Index) {}
106
  explicit TypeIndex(SimpleTypeKind Kind)
107
78.9k
      : Index(static_cast<uint32_t>(Kind)) {}
108
  TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode)
109
3.57k
      : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
110
111
441k
  uint32_t getIndex() const { return Index; }
112
46.4k
  void setIndex(uint32_t I) { Index = I; }
113
72.8k
  bool isSimple() const { return Index < FirstNonSimpleIndex; }
114
  bool isDecoratedItemId() const { return !!(Index & DecoratedItemIdMask); }
115
116
66.8k
  bool isNoneType() const { return *this == None(); }
117
118
132k
  uint32_t toArrayIndex() const {
119
132k
    assert(!isSimple());
120
132k
    return getIndex() - FirstNonSimpleIndex;
121
132k
  }
122
123
13.4k
  static TypeIndex fromArrayIndex(uint32_t Index) {
124
13.4k
    return TypeIndex(Index + FirstNonSimpleIndex);
125
13.4k
  }
126
127
39.2k
  SimpleTypeKind getSimpleKind() const {
128
39.2k
    assert(isSimple());
129
39.2k
    return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
130
39.2k
  }
131
132
3.64k
  SimpleTypeMode getSimpleMode() const {
133
3.64k
    assert(isSimple());
134
3.64k
    return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
135
3.64k
  }
136
137
  TypeIndex makeDirect() const { return TypeIndex{getSimpleKind()}; }
138
139
71.2k
  static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); }
140
593
  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
3.55k
  static TypeIndex NullptrT() {
149
3.55k
    // std::nullptr_t uses the pointer mode that doesn't indicate bit-width,
150
3.55k
    // presumably because std::nullptr_t is intended to be compatible with any
151
3.55k
    // pointer type.
152
3.55k
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer);
153
3.55k
  }
154
155
  static TypeIndex SignedCharacter() {
156
    return TypeIndex(SimpleTypeKind::SignedCharacter);
157
  }
158
  static TypeIndex UnsignedCharacter() {
159
    return TypeIndex(SimpleTypeKind::UnsignedCharacter);
160
  }
161
  static TypeIndex NarrowCharacter() {
162
    return TypeIndex(SimpleTypeKind::NarrowCharacter);
163
  }
164
  static TypeIndex WideCharacter() {
165
    return TypeIndex(SimpleTypeKind::WideCharacter);
166
  }
167
  static TypeIndex Int16Short() {
168
    return TypeIndex(SimpleTypeKind::Int16Short);
169
  }
170
  static TypeIndex UInt16Short() {
171
    return TypeIndex(SimpleTypeKind::UInt16Short);
172
  }
173
71
  static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); }
174
  static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); }
175
  static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); }
176
  static TypeIndex UInt32Long() {
177
    return TypeIndex(SimpleTypeKind::UInt32Long);
178
  }
179
  static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); }
180
  static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); }
181
  static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); }
182
  static TypeIndex UInt64Quad() {
183
    return TypeIndex(SimpleTypeKind::UInt64Quad);
184
  }
185
186
  static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
187
  static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
188
189
  TypeIndex &operator+=(unsigned N) {
190
    Index += N;
191
    return *this;
192
  }
193
194
36.2k
  TypeIndex &operator++() {
195
36.2k
    Index += 1;
196
36.2k
    return *this;
197
36.2k
  }
198
199
12.7k
  TypeIndex operator++(int) {
200
12.7k
    TypeIndex Copy = *this;
201
12.7k
    operator++();
202
12.7k
    return Copy;
203
12.7k
  }
204
205
  TypeIndex &operator-=(unsigned N) {
206
    assert(Index >= N);
207
    Index -= N;
208
    return *this;
209
  }
210
211
  TypeIndex &operator--() {
212
    Index -= 1;
213
    return *this;
214
  }
215
216
  TypeIndex operator--(int) {
217
    TypeIndex Copy = *this;
218
    operator--();
219
    return Copy;
220
  }
221
222
92.3k
  friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
223
92.3k
    return A.getIndex() == B.getIndex();
224
92.3k
  }
225
226
  friend inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
227
    return A.getIndex() != B.getIndex();
228
  }
229
230
  friend inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
231
    return A.getIndex() < B.getIndex();
232
  }
233
234
  friend inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
235
    return A.getIndex() <= B.getIndex();
236
  }
237
238
0
  friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
239
0
    return A.getIndex() > B.getIndex();
240
0
  }
241
242
0
  friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
243
0
    return A.getIndex() >= B.getIndex();
244
0
  }
245
246
  friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
247
    TypeIndex Result(A);
248
    Result += N;
249
    return Result;
250
  }
251
252
0
  friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
253
0
    assert(A.getIndex() >= N);
254
0
    TypeIndex Result(A);
255
0
    Result -= N;
256
0
    return Result;
257
0
  }
258
259
0
  friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
260
0
    assert(A >= B);
261
0
    return A.toArrayIndex() - B.toArrayIndex();
262
0
  }
263
264
  static StringRef simpleTypeName(TypeIndex TI);
265
266
private:
267
  support::ulittle32_t Index;
268
};
269
270
// Used for pseudo-indexing an array of type records.  An array of such records
271
// sorted by TypeIndex can allow log(N) lookups even though such a type record
272
// stream does not provide random access.
273
struct TypeIndexOffset {
274
  TypeIndex Type;
275
  support::ulittle32_t Offset;
276
};
277
278
void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
279
                    TypeCollection &Types);
280
}
281
282
template <> struct DenseMapInfo<codeview::TypeIndex> {
283
  static inline codeview::TypeIndex getEmptyKey() {
284
    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
285
  }
286
  static inline codeview::TypeIndex getTombstoneKey() {
287
    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
288
  }
289
  static unsigned getHashValue(const codeview::TypeIndex &TI) {
290
    return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
291
  }
292
  static bool isEqual(const codeview::TypeIndex &LHS,
293
                      const codeview::TypeIndex &RHS) {
294
    return LHS == RHS;
295
  }
296
};
297
298
} // namespace llvm
299
300
#endif