Line data Source code
1 : //===- TypeRecord.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_TYPERECORD_H
11 : #define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
12 :
13 : #include "llvm/ADT/APSInt.h"
14 : #include "llvm/ADT/ArrayRef.h"
15 : #include "llvm/ADT/Optional.h"
16 : #include "llvm/ADT/SmallVector.h"
17 : #include "llvm/ADT/StringRef.h"
18 : #include "llvm/ADT/iterator_range.h"
19 : #include "llvm/DebugInfo/CodeView/CVRecord.h"
20 : #include "llvm/DebugInfo/CodeView/CodeView.h"
21 : #include "llvm/DebugInfo/CodeView/GUID.h"
22 : #include "llvm/DebugInfo/CodeView/TypeIndex.h"
23 : #include "llvm/Support/BinaryStreamArray.h"
24 : #include "llvm/Support/Endian.h"
25 : #include <algorithm>
26 : #include <cstdint>
27 : #include <vector>
28 :
29 : namespace llvm {
30 : namespace codeview {
31 :
32 : using support::little32_t;
33 : using support::ulittle16_t;
34 : using support::ulittle32_t;
35 :
36 : using CVType = CVRecord<TypeLeafKind>;
37 : using RemappedType = RemappedRecord<TypeLeafKind>;
38 :
39 : struct CVMemberRecord {
40 : TypeLeafKind Kind;
41 : ArrayRef<uint8_t> Data;
42 : };
43 : using CVTypeArray = VarStreamArray<CVType>;
44 : using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
45 :
46 : /// Equvalent to CV_fldattr_t in cvinfo.h.
47 : struct MemberAttributes {
48 : uint16_t Attrs = 0;
49 :
50 : enum {
51 : MethodKindShift = 2,
52 : };
53 :
54 949 : MemberAttributes() = default;
55 :
56 : explicit MemberAttributes(MemberAccess Access)
57 5840 : : Attrs(static_cast<uint16_t>(Access)) {}
58 :
59 66 : MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
60 : Attrs = static_cast<uint16_t>(Access);
61 66 : Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
62 66 : Attrs |= static_cast<uint16_t>(Flags);
63 : }
64 :
65 : /// Get the access specifier. Valid for any kind of member.
66 0 : MemberAccess getAccess() const {
67 7743 : return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
68 : }
69 :
70 : /// Indicates if a method is defined with friend, virtual, static, etc.
71 0 : MethodKind getMethodKind() const {
72 1458 : return MethodKind(
73 1458 : (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
74 1458 : MethodKindShift);
75 : }
76 :
77 : /// Get the flags that are not included in access control or method
78 : /// properties.
79 0 : MethodOptions getFlags() const {
80 : return MethodOptions(
81 0 : unsigned(Attrs) &
82 0 : ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
83 : }
84 :
85 : /// Is this method virtual.
86 : bool isVirtual() const {
87 : auto MP = getMethodKind();
88 : return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
89 : MP != MethodKind::Static;
90 : }
91 :
92 : /// Does this member introduce a new virtual method.
93 : bool isIntroducedVirtual() const {
94 : auto MP = getMethodKind();
95 : return MP == MethodKind::IntroducingVirtual ||
96 : MP == MethodKind::PureIntroducingVirtual;
97 : }
98 : };
99 :
100 : // Does not correspond to any tag, this is the tail of an LF_POINTER record
101 : // if it represents a member pointer.
102 : class MemberPointerInfo {
103 : public:
104 : MemberPointerInfo() = default;
105 :
106 : MemberPointerInfo(TypeIndex ContainingType,
107 : PointerToMemberRepresentation Representation)
108 16 : : ContainingType(ContainingType), Representation(Representation) {}
109 :
110 31 : TypeIndex getContainingType() const { return ContainingType; }
111 0 : PointerToMemberRepresentation getRepresentation() const {
112 0 : return Representation;
113 : }
114 :
115 : TypeIndex ContainingType;
116 : PointerToMemberRepresentation Representation;
117 : };
118 :
119 : class TypeRecord {
120 : protected:
121 : TypeRecord() = default;
122 13726 : explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
123 :
124 : public:
125 0 : TypeRecordKind getKind() const { return Kind; }
126 :
127 : TypeRecordKind Kind;
128 : };
129 :
130 : // LF_MODIFIER
131 : class ModifierRecord : public TypeRecord {
132 : public:
133 : ModifierRecord() = default;
134 264 : explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
135 : ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
136 26 : : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
137 26 : Modifiers(Modifiers) {}
138 :
139 154 : TypeIndex getModifiedType() const { return ModifiedType; }
140 0 : ModifierOptions getModifiers() const { return Modifiers; }
141 :
142 : TypeIndex ModifiedType;
143 : ModifierOptions Modifiers;
144 : };
145 :
146 : // LF_PROCEDURE
147 : class ProcedureRecord : public TypeRecord {
148 : public:
149 : ProcedureRecord() = default;
150 562 : explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
151 : ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
152 : FunctionOptions Options, uint16_t ParameterCount,
153 : TypeIndex ArgumentList)
154 168 : : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
155 : CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
156 168 : ArgumentList(ArgumentList) {}
157 :
158 451 : TypeIndex getReturnType() const { return ReturnType; }
159 0 : CallingConvention getCallConv() const { return CallConv; }
160 0 : FunctionOptions getOptions() const { return Options; }
161 0 : uint16_t getParameterCount() const { return ParameterCount; }
162 416 : TypeIndex getArgumentList() const { return ArgumentList; }
163 :
164 : TypeIndex ReturnType;
165 : CallingConvention CallConv;
166 : FunctionOptions Options;
167 : uint16_t ParameterCount;
168 : TypeIndex ArgumentList;
169 : };
170 :
171 : // LF_MFUNCTION
172 : class MemberFunctionRecord : public TypeRecord {
173 : public:
174 : MemberFunctionRecord() = default;
175 1759 : explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
176 :
177 : MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
178 : TypeIndex ThisType, CallingConvention CallConv,
179 : FunctionOptions Options, uint16_t ParameterCount,
180 : TypeIndex ArgumentList, int32_t ThisPointerAdjustment)
181 93 : : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
182 : ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
183 : Options(Options), ParameterCount(ParameterCount),
184 : ArgumentList(ArgumentList),
185 93 : ThisPointerAdjustment(ThisPointerAdjustment) {}
186 :
187 920 : TypeIndex getReturnType() const { return ReturnType; }
188 836 : TypeIndex getClassType() const { return ClassType; }
189 419 : TypeIndex getThisType() const { return ThisType; }
190 0 : CallingConvention getCallConv() const { return CallConv; }
191 0 : FunctionOptions getOptions() const { return Options; }
192 0 : uint16_t getParameterCount() const { return ParameterCount; }
193 836 : TypeIndex getArgumentList() const { return ArgumentList; }
194 0 : int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
195 :
196 : TypeIndex ReturnType;
197 : TypeIndex ClassType;
198 : TypeIndex ThisType;
199 : CallingConvention CallConv;
200 : FunctionOptions Options;
201 : uint16_t ParameterCount;
202 : TypeIndex ArgumentList;
203 : int32_t ThisPointerAdjustment;
204 : };
205 :
206 : // LF_LABEL
207 : class LabelRecord : public TypeRecord {
208 : public:
209 : LabelRecord() = default;
210 1 : explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
211 :
212 : LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
213 :
214 : LabelType Mode;
215 : };
216 :
217 : // LF_MFUNC_ID
218 : class MemberFuncIdRecord : public TypeRecord {
219 : public:
220 : MemberFuncIdRecord() = default;
221 129 : explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
222 : MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
223 : StringRef Name)
224 42 : : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
225 42 : FunctionType(FunctionType), Name(Name) {}
226 :
227 65 : TypeIndex getClassType() const { return ClassType; }
228 65 : TypeIndex getFunctionType() const { return FunctionType; }
229 0 : StringRef getName() const { return Name; }
230 :
231 : TypeIndex ClassType;
232 : TypeIndex FunctionType;
233 : StringRef Name;
234 : };
235 :
236 : // LF_ARGLIST
237 383 : class ArgListRecord : public TypeRecord {
238 : public:
239 : ArgListRecord() = default;
240 1061 : explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
241 :
242 : ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
243 261 : : TypeRecord(Kind), ArgIndices(Indices) {}
244 :
245 : ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
246 :
247 : std::vector<TypeIndex> ArgIndices;
248 : };
249 :
250 : // LF_SUBSTR_LIST
251 : class StringListRecord : public TypeRecord {
252 : public:
253 : StringListRecord() = default;
254 87 : explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
255 :
256 : StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
257 : : TypeRecord(Kind), StringIndices(Indices) {}
258 :
259 : ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
260 :
261 : std::vector<TypeIndex> StringIndices;
262 : };
263 :
264 : // LF_POINTER
265 73 : class PointerRecord : public TypeRecord {
266 : public:
267 : static const uint32_t PointerKindShift = 0;
268 : static const uint32_t PointerKindMask = 0x1F;
269 :
270 : static const uint32_t PointerModeShift = 5;
271 : static const uint32_t PointerModeMask = 0x07;
272 :
273 : static const uint32_t PointerOptionMask = 0xFF;
274 :
275 : static const uint32_t PointerSizeShift = 13;
276 : static const uint32_t PointerSizeMask = 0xFF;
277 :
278 : PointerRecord() = default;
279 1597 : explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
280 :
281 : PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
282 : : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
283 : Attrs(Attrs) {}
284 :
285 : PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
286 : PointerOptions PO, uint8_t Size)
287 143 : : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
288 286 : Attrs(calcAttrs(PK, PM, PO, Size)) {}
289 :
290 : PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
291 : PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI)
292 16 : : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
293 32 : Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
294 :
295 841 : TypeIndex getReferentType() const { return ReferentType; }
296 :
297 0 : PointerKind getPointerKind() const {
298 653 : return static_cast<PointerKind>((Attrs >> PointerKindShift) &
299 653 : PointerKindMask);
300 : }
301 :
302 0 : PointerMode getMode() const {
303 3947 : return static_cast<PointerMode>((Attrs >> PointerModeShift) &
304 3106 : PointerModeMask);
305 : }
306 :
307 0 : PointerOptions getOptions() const {
308 0 : return static_cast<PointerOptions>(Attrs);
309 : }
310 :
311 0 : uint8_t getSize() const {
312 448 : return (Attrs >> PointerSizeShift) & PointerSizeMask;
313 : }
314 :
315 38 : MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
316 :
317 : bool isPointerToMember() const {
318 2517 : return getMode() == PointerMode::PointerToDataMember ||
319 : getMode() == PointerMode::PointerToMemberFunction;
320 : }
321 :
322 419 : bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
323 826 : bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
324 :
325 0 : bool isVolatile() const {
326 826 : return !!(Attrs & uint32_t(PointerOptions::Volatile));
327 : }
328 :
329 0 : bool isUnaligned() const {
330 826 : return !!(Attrs & uint32_t(PointerOptions::Unaligned));
331 : }
332 :
333 0 : bool isRestrict() const {
334 826 : return !!(Attrs & uint32_t(PointerOptions::Restrict));
335 : }
336 :
337 : TypeIndex ReferentType;
338 : uint32_t Attrs;
339 : Optional<MemberPointerInfo> MemberInfo;
340 :
341 : void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
342 : uint8_t Size) {
343 7 : Attrs = calcAttrs(PK, PM, PO, Size);
344 : }
345 :
346 : private:
347 : static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
348 : uint8_t Size) {
349 : uint32_t A = 0;
350 155 : A |= static_cast<uint32_t>(PK);
351 150 : A |= static_cast<uint32_t>(PO);
352 154 : A |= (static_cast<uint32_t>(PM) << PointerModeShift);
353 159 : A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
354 : return A;
355 : }
356 : };
357 :
358 : // LF_NESTTYPE
359 : class NestedTypeRecord : public TypeRecord {
360 : public:
361 : NestedTypeRecord() = default;
362 297 : explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
363 : NestedTypeRecord(TypeIndex Type, StringRef Name)
364 12 : : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
365 :
366 71 : TypeIndex getNestedType() const { return Type; }
367 0 : StringRef getName() const { return Name; }
368 :
369 : TypeIndex Type;
370 : StringRef Name;
371 : };
372 :
373 : // LF_FIELDLIST
374 : class FieldListRecord : public TypeRecord {
375 : public:
376 : FieldListRecord() = default;
377 1004 : explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
378 : explicit FieldListRecord(ArrayRef<uint8_t> Data)
379 : : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
380 :
381 : ArrayRef<uint8_t> Data;
382 : };
383 :
384 : // LF_ARRAY
385 : class ArrayRecord : public TypeRecord {
386 : public:
387 : ArrayRecord() = default;
388 163 : explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
389 : ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
390 : StringRef Name)
391 19 : : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
392 19 : IndexType(IndexType), Size(Size), Name(Name) {}
393 :
394 39 : TypeIndex getElementType() const { return ElementType; }
395 37 : TypeIndex getIndexType() const { return IndexType; }
396 0 : uint64_t getSize() const { return Size; }
397 0 : StringRef getName() const { return Name; }
398 :
399 : TypeIndex ElementType;
400 : TypeIndex IndexType;
401 : uint64_t Size;
402 : StringRef Name;
403 : };
404 :
405 : class TagRecord : public TypeRecord {
406 : protected:
407 : TagRecord() = default;
408 1139 : explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
409 : TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
410 : TypeIndex FieldList, StringRef Name, StringRef UniqueName)
411 220 : : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
412 220 : FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
413 :
414 : public:
415 : static const int HfaKindShift = 11;
416 : static const int HfaKindMask = 0x1800;
417 : static const int WinRTKindShift = 14;
418 : static const int WinRTKindMask = 0xC000;
419 :
420 0 : bool hasUniqueName() const {
421 3514 : return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
422 : }
423 :
424 : bool isNested() const {
425 : return (Options & ClassOptions::Nested) != ClassOptions::None;
426 : }
427 :
428 : bool isForwardRef() const {
429 : return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
430 : }
431 :
432 0 : uint16_t getMemberCount() const { return MemberCount; }
433 0 : ClassOptions getOptions() const { return Options; }
434 714 : TypeIndex getFieldList() const { return FieldList; }
435 0 : StringRef getName() const { return Name; }
436 0 : StringRef getUniqueName() const { return UniqueName; }
437 :
438 : uint16_t MemberCount;
439 : ClassOptions Options;
440 : TypeIndex FieldList;
441 : StringRef Name;
442 : StringRef UniqueName;
443 : };
444 :
445 : // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
446 : class ClassRecord : public TagRecord {
447 : public:
448 : ClassRecord() = default;
449 2451 : explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
450 : ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
451 : TypeIndex FieldList, TypeIndex DerivationList,
452 : TypeIndex VTableShape, uint64_t Size, StringRef Name,
453 : StringRef UniqueName)
454 197 : : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
455 197 : DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
456 :
457 : HfaKind getHfa() const {
458 : uint16_t Value = static_cast<uint16_t>(Options);
459 : Value = (Value & HfaKindMask) >> HfaKindShift;
460 : return static_cast<HfaKind>(Value);
461 : }
462 :
463 : WindowsRTClassKind getWinRTKind() const {
464 : uint16_t Value = static_cast<uint16_t>(Options);
465 : Value = (Value & WinRTKindMask) >> WinRTKindShift;
466 : return static_cast<WindowsRTClassKind>(Value);
467 : }
468 :
469 628 : TypeIndex getDerivationList() const { return DerivationList; }
470 628 : TypeIndex getVTableShape() const { return VTableShape; }
471 0 : uint64_t getSize() const { return Size; }
472 :
473 : TypeIndex DerivationList;
474 : TypeIndex VTableShape;
475 : uint64_t Size;
476 : };
477 :
478 : // LF_UNION
479 : struct UnionRecord : public TagRecord {
480 : UnionRecord() = default;
481 43 : explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
482 : UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
483 : uint64_t Size, StringRef Name, StringRef UniqueName)
484 15 : : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
485 : UniqueName),
486 15 : Size(Size) {}
487 :
488 : HfaKind getHfa() const {
489 : uint16_t Value = static_cast<uint16_t>(Options);
490 : Value = (Value & HfaKindMask) >> HfaKindShift;
491 : return static_cast<HfaKind>(Value);
492 : }
493 :
494 0 : uint64_t getSize() const { return Size; }
495 :
496 : uint64_t Size;
497 : };
498 :
499 : // LF_ENUM
500 : class EnumRecord : public TagRecord {
501 : public:
502 : EnumRecord() = default;
503 124 : explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
504 : EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
505 : StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
506 8 : : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
507 : UniqueName),
508 8 : UnderlyingType(UnderlyingType) {}
509 :
510 449 : TypeIndex getUnderlyingType() const { return UnderlyingType; }
511 :
512 : TypeIndex UnderlyingType;
513 : };
514 :
515 : // LF_BITFIELD
516 : class BitFieldRecord : public TypeRecord {
517 : public:
518 : BitFieldRecord() = default;
519 22 : explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
520 : BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
521 8 : : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
522 8 : BitOffset(BitOffset) {}
523 :
524 7 : TypeIndex getType() const { return Type; }
525 0 : uint8_t getBitOffset() const { return BitOffset; }
526 0 : uint8_t getBitSize() const { return BitSize; }
527 :
528 : TypeIndex Type;
529 : uint8_t BitSize;
530 : uint8_t BitOffset;
531 : };
532 :
533 : // LF_VTSHAPE
534 9 : class VFTableShapeRecord : public TypeRecord {
535 : public:
536 : VFTableShapeRecord() = default;
537 45 : explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
538 : explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
539 9 : : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
540 : explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
541 : : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
542 :
543 : ArrayRef<VFTableSlotKind> getSlots() const {
544 53 : if (!SlotsRef.empty())
545 9 : return SlotsRef;
546 : return Slots;
547 : }
548 :
549 36 : uint32_t getEntryCount() const { return getSlots().size(); }
550 :
551 : ArrayRef<VFTableSlotKind> SlotsRef;
552 : std::vector<VFTableSlotKind> Slots;
553 : };
554 :
555 : // LF_TYPESERVER2
556 : class TypeServer2Record : public TypeRecord {
557 : public:
558 : TypeServer2Record() = default;
559 11 : explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
560 : TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
561 : : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
562 : assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
563 : ::memcpy(Guid.Guid, GuidStr.data(), 16);
564 : }
565 :
566 9 : const GUID &getGuid() const { return Guid; }
567 0 : uint32_t getAge() const { return Age; }
568 0 : StringRef getName() const { return Name; }
569 :
570 : GUID Guid;
571 : uint32_t Age;
572 : StringRef Name;
573 : };
574 :
575 : // LF_STRING_ID
576 : class StringIdRecord : public TypeRecord {
577 : public:
578 : StringIdRecord() = default;
579 1299 : explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
580 : StringIdRecord(TypeIndex Id, StringRef String)
581 372 : : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
582 :
583 526 : TypeIndex getId() const { return Id; }
584 0 : StringRef getString() const { return String; }
585 :
586 : TypeIndex Id;
587 : StringRef String;
588 : };
589 :
590 : // LF_FUNC_ID
591 : class FuncIdRecord : public TypeRecord {
592 : public:
593 : FuncIdRecord() = default;
594 561 : explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
595 : FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
596 210 : : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
597 210 : FunctionType(FunctionType), Name(Name) {}
598 :
599 277 : TypeIndex getParentScope() const { return ParentScope; }
600 277 : TypeIndex getFunctionType() const { return FunctionType; }
601 0 : StringRef getName() const { return Name; }
602 :
603 : TypeIndex ParentScope;
604 : TypeIndex FunctionType;
605 : StringRef Name;
606 : };
607 :
608 : // LF_UDT_SRC_LINE
609 : class UdtSourceLineRecord : public TypeRecord {
610 : public:
611 : UdtSourceLineRecord() = default;
612 914 : explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
613 : UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
614 110 : : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
615 110 : SourceFile(SourceFile), LineNumber(LineNumber) {}
616 :
617 458 : TypeIndex getUDT() const { return UDT; }
618 385 : TypeIndex getSourceFile() const { return SourceFile; }
619 0 : uint32_t getLineNumber() const { return LineNumber; }
620 :
621 : TypeIndex UDT;
622 : TypeIndex SourceFile;
623 : uint32_t LineNumber;
624 : };
625 :
626 : // LF_UDT_MOD_SRC_LINE
627 : class UdtModSourceLineRecord : public TypeRecord {
628 : public:
629 : UdtModSourceLineRecord() = default;
630 36 : explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
631 : UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
632 : uint32_t LineNumber, uint16_t Module)
633 : : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
634 : SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
635 :
636 14 : TypeIndex getUDT() const { return UDT; }
637 0 : TypeIndex getSourceFile() const { return SourceFile; }
638 0 : uint32_t getLineNumber() const { return LineNumber; }
639 0 : uint16_t getModule() const { return Module; }
640 :
641 : TypeIndex UDT;
642 : TypeIndex SourceFile;
643 : uint32_t LineNumber;
644 : uint16_t Module;
645 : };
646 :
647 : // LF_BUILDINFO
648 : class BuildInfoRecord : public TypeRecord {
649 : public:
650 : BuildInfoRecord() = default;
651 303 : explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
652 : BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
653 130 : : TypeRecord(TypeRecordKind::BuildInfo),
654 : ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
655 :
656 : ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
657 :
658 : /// Indices of known build info arguments.
659 : enum BuildInfoArg {
660 : CurrentDirectory, ///< Absolute CWD path
661 : BuildTool, ///< Absolute compiler path
662 : SourceFile, ///< Path to main source file, relative or absolute
663 : TypeServerPDB, ///< Absolute path of type server PDB (/Fd)
664 : CommandLine, ///< Full canonical command line (maybe -cc1)
665 : MaxArgs
666 : };
667 :
668 : SmallVector<TypeIndex, MaxArgs> ArgIndices;
669 : };
670 :
671 : // LF_VFTABLE
672 : class VFTableRecord : public TypeRecord {
673 : public:
674 : VFTableRecord() = default;
675 15 : explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
676 49 : VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
677 : uint32_t VFPtrOffset, StringRef Name,
678 : ArrayRef<StringRef> Methods)
679 49 : : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
680 49 : OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
681 49 : MethodNames.push_back(Name);
682 49 : MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
683 49 : }
684 :
685 7 : TypeIndex getCompleteClass() const { return CompleteClass; }
686 7 : TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
687 0 : uint32_t getVFPtrOffset() const { return VFPtrOffset; }
688 11 : StringRef getName() const { return makeArrayRef(MethodNames).front(); }
689 :
690 : ArrayRef<StringRef> getMethodNames() const {
691 : return makeArrayRef(MethodNames).drop_front();
692 : }
693 :
694 : TypeIndex CompleteClass;
695 : TypeIndex OverriddenVFTable;
696 : uint32_t VFPtrOffset;
697 : std::vector<StringRef> MethodNames;
698 : };
699 :
700 : // LF_ONEMETHOD
701 : class OneMethodRecord : public TypeRecord {
702 : public:
703 : OneMethodRecord() = default;
704 649 : explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
705 : OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
706 : StringRef Name)
707 : : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
708 : VFTableOffset(VFTableOffset), Name(Name) {}
709 : OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
710 : MethodOptions Options, int32_t VFTableOffset, StringRef Name)
711 66 : : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
712 66 : Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
713 :
714 401 : TypeIndex getType() const { return Type; }
715 189 : MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
716 212 : MethodOptions getOptions() const { return Attrs.getFlags(); }
717 : MemberAccess getAccess() const { return Attrs.getAccess(); }
718 0 : int32_t getVFTableOffset() const { return VFTableOffset; }
719 0 : StringRef getName() const { return Name; }
720 :
721 : bool isIntroducingVirtual() const {
722 401 : return getMethodKind() == MethodKind::IntroducingVirtual ||
723 : getMethodKind() == MethodKind::PureIntroducingVirtual;
724 : }
725 :
726 : TypeIndex Type;
727 : MemberAttributes Attrs;
728 : int32_t VFTableOffset;
729 : StringRef Name;
730 : };
731 :
732 : // LF_METHODLIST
733 : class MethodOverloadListRecord : public TypeRecord {
734 : public:
735 : MethodOverloadListRecord() = default;
736 403 : explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
737 : MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
738 1 : : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
739 :
740 : ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
741 :
742 : std::vector<OneMethodRecord> Methods;
743 : };
744 :
745 : /// For method overload sets. LF_METHOD
746 : class OverloadedMethodRecord : public TypeRecord {
747 : public:
748 : OverloadedMethodRecord() = default;
749 390 : explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
750 : OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
751 : StringRef Name)
752 1 : : TypeRecord(TypeRecordKind::OverloadedMethod),
753 1 : NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
754 :
755 0 : uint16_t getNumOverloads() const { return NumOverloads; }
756 87 : TypeIndex getMethodList() const { return MethodList; }
757 0 : StringRef getName() const { return Name; }
758 :
759 : uint16_t NumOverloads;
760 : TypeIndex MethodList;
761 : StringRef Name;
762 : };
763 :
764 : // LF_MEMBER
765 : class DataMemberRecord : public TypeRecord {
766 : public:
767 : DataMemberRecord() = default;
768 1933 : explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
769 : DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
770 : StringRef Name)
771 : : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
772 : FieldOffset(Offset), Name(Name) {}
773 : DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
774 : StringRef Name)
775 104 : : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
776 104 : FieldOffset(Offset), Name(Name) {}
777 :
778 505 : MemberAccess getAccess() const { return Attrs.getAccess(); }
779 505 : TypeIndex getType() const { return Type; }
780 0 : uint64_t getFieldOffset() const { return FieldOffset; }
781 0 : StringRef getName() const { return Name; }
782 :
783 : MemberAttributes Attrs;
784 : TypeIndex Type;
785 : uint64_t FieldOffset;
786 : StringRef Name;
787 : };
788 :
789 : // LF_STMEMBER
790 : class StaticDataMemberRecord : public TypeRecord {
791 : public:
792 : StaticDataMemberRecord() = default;
793 196 : explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
794 : StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
795 : : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
796 : Name(Name) {}
797 : StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
798 4 : : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
799 4 : Name(Name) {}
800 :
801 43 : MemberAccess getAccess() const { return Attrs.getAccess(); }
802 43 : TypeIndex getType() const { return Type; }
803 0 : StringRef getName() const { return Name; }
804 :
805 : MemberAttributes Attrs;
806 : TypeIndex Type;
807 : StringRef Name;
808 : };
809 :
810 : // LF_ENUMERATE
811 505 : class EnumeratorRecord : public TypeRecord {
812 : public:
813 : EnumeratorRecord() = default;
814 7763 : explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
815 : EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
816 : : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
817 : Value(std::move(Value)), Name(Name) {}
818 : EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
819 5708 : : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
820 5708 : Value(std::move(Value)), Name(Name) {}
821 :
822 6102 : MemberAccess getAccess() const { return Attrs.getAccess(); }
823 : APSInt getValue() const { return Value; }
824 0 : StringRef getName() const { return Name; }
825 :
826 : MemberAttributes Attrs;
827 : APSInt Value;
828 : StringRef Name;
829 : };
830 :
831 : // LF_VFUNCTAB
832 : class VFPtrRecord : public TypeRecord {
833 : public:
834 : VFPtrRecord() = default;
835 4 : explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
836 : VFPtrRecord(TypeIndex Type)
837 13 : : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
838 :
839 16 : TypeIndex getType() const { return Type; }
840 :
841 : TypeIndex Type;
842 : };
843 :
844 : // LF_BCLASS, LF_BINTERFACE
845 : class BaseClassRecord : public TypeRecord {
846 : public:
847 : BaseClassRecord() = default;
848 33 : explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
849 : BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
850 : : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
851 : Offset(Offset) {}
852 : BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
853 15 : : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
854 15 : Offset(Offset) {}
855 :
856 21 : MemberAccess getAccess() const { return Attrs.getAccess(); }
857 21 : TypeIndex getBaseType() const { return Type; }
858 0 : uint64_t getBaseOffset() const { return Offset; }
859 :
860 : MemberAttributes Attrs;
861 : TypeIndex Type;
862 : uint64_t Offset;
863 : };
864 :
865 : // LF_VBCLASS, LF_IVBCLASS
866 : class VirtualBaseClassRecord : public TypeRecord {
867 : public:
868 : VirtualBaseClassRecord() = default;
869 25 : explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
870 : VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
871 : TypeIndex BaseType, TypeIndex VBPtrType,
872 : uint64_t Offset, uint64_t Index)
873 : : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
874 : VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
875 : VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
876 : TypeIndex BaseType, TypeIndex VBPtrType,
877 : uint64_t Offset, uint64_t Index)
878 9 : : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
879 9 : VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
880 :
881 15 : MemberAccess getAccess() const { return Attrs.getAccess(); }
882 15 : TypeIndex getBaseType() const { return BaseType; }
883 15 : TypeIndex getVBPtrType() const { return VBPtrType; }
884 0 : uint64_t getVBPtrOffset() const { return VBPtrOffset; }
885 0 : uint64_t getVTableIndex() const { return VTableIndex; }
886 :
887 : MemberAttributes Attrs;
888 : TypeIndex BaseType;
889 : TypeIndex VBPtrType;
890 : uint64_t VBPtrOffset;
891 : uint64_t VTableIndex;
892 : };
893 :
894 : /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
895 : /// together. The first will end in an LF_INDEX record that points to the next.
896 : class ListContinuationRecord : public TypeRecord {
897 : public:
898 : ListContinuationRecord() = default;
899 0 : explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
900 : ListContinuationRecord(TypeIndex ContinuationIndex)
901 : : TypeRecord(TypeRecordKind::ListContinuation),
902 : ContinuationIndex(ContinuationIndex) {}
903 :
904 4 : TypeIndex getContinuationIndex() const { return ContinuationIndex; }
905 :
906 : TypeIndex ContinuationIndex;
907 : };
908 :
909 : // LF_PRECOMP
910 : class PrecompRecord : public TypeRecord {
911 : public:
912 : PrecompRecord() = default;
913 5 : explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
914 :
915 0 : uint32_t getStartTypeIndex() const { return StartTypeIndex; }
916 0 : uint32_t getTypesCount() const { return TypesCount; }
917 0 : uint32_t getSignature() const { return Signature; }
918 0 : StringRef getPrecompFilePath() const { return PrecompFilePath; }
919 :
920 : uint32_t StartTypeIndex;
921 : uint32_t TypesCount;
922 : uint32_t Signature;
923 : StringRef PrecompFilePath;
924 : };
925 :
926 : // LF_ENDPRECOMP
927 : class EndPrecompRecord : public TypeRecord {
928 : public:
929 : EndPrecompRecord() = default;
930 5 : explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
931 :
932 0 : uint32_t getSignature() const { return Signature; }
933 :
934 : uint32_t Signature;
935 : };
936 :
937 : } // end namespace codeview
938 : } // end namespace llvm
939 :
940 : #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
|