llvm.org GIT mirror llvm / 9b6c494
[PDB] Add native reading support for UDT / class types. This allows the native reader to find records of class/struct/ union type and dump them. This behavior is tested by using the diadump subcommand against golden output produced by actual DIA SDK on the same PDB file, and again using pretty -native to confirm that we actually dump the classes. We don't find class members or anything like that yet, for now it's just the class itself. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342779 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 11 months ago
19 changed file(s) with 1088 addition(s) and 143 deletion(s). Raw diff Collapse all Expand all
922922
923923 uint32_t Signature;
924924 };
925
925926 } // end namespace codeview
926927 } // end namespace llvm
927928
0 //===- TypeRecordHelpers.h --------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDHELPERS_H
10 #define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDHELPERS_H
11
12 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
13
14 namespace llvm {
15 namespace codeview {
16 /// Given an arbitrary codeview type, determine if it is an LF_STRUCTURE,
17 /// LF_CLASS, LF_INTERFACE, LF_UNION, or LF_ENUM with the forward ref class
18 /// option.
19 bool isUdtForwardRef(CVType CVT);
20
21 /// Given a CVType which is assumed to be an LF_MODIFIER, return the
22 /// TypeIndex of the type that the LF_MODIFIER modifies.
23 TypeIndex getModifiedType(const CVType &CVT);
24 }
25 }
26
27 #endif
3434 virtual uint32_t getChildCount() const override { return 0; }
3535 virtual std::unique_ptr
3636 getChildAtIndex(uint32_t Index) const override {
37 assert(false);
3837 return nullptr;
3938 }
4039 virtual std::unique_ptr getNext() override {
41 assert(false);
4240 return nullptr;
4341 }
4442 virtual void reset() override {}
2525 public:
2626 NativeEnumTypes(NativeSession &Session,
2727 codeview::LazyRandomTypeCollection &TypeCollection,
28 codeview::TypeLeafKind Kind);
28 std::vector Kinds);
2929
3030 uint32_t getChildCount() const override;
3131 std::unique_ptr getChildAtIndex(uint32_t Index) const override;
3333 void reset() override;
3434
3535 private:
36 NativeEnumTypes(NativeSession &Session,
37 const std::vector &Matches,
38 codeview::TypeLeafKind Kind);
39
4036 std::vector Matches;
4137 uint32_t Index;
4238 NativeSession &Session;
99 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H
1010 #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H
1111
12 #include "llvm/ADT/Optional.h"
1213 #include "llvm/DebugInfo/CodeView/CodeView.h"
1314 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
1415 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
2526 codeview::EnumRecord Record);
2627
2728 NativeTypeEnum(NativeSession &Session, SymIndexId Id,
28 codeview::TypeIndex ModifierTI,
29 codeview::ModifierRecord Modifier,
30 codeview::EnumRecord EnumRecord);
29 NativeTypeEnum &UnmodifiedType,
30 codeview::ModifierRecord Modifier);
3131 ~NativeTypeEnum() override;
3232
3333 void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
5959 bool isInterfaceUdt() const override;
6060
6161 const NativeTypeBuiltin &getUnderlyingBuiltinType() const;
62 const codeview::EnumRecord &getEnumRecord() const { return *Record; }
6263
6364 protected:
6465 codeview::TypeIndex Index;
65 codeview::EnumRecord Record;
66 Optional Record;
67 NativeTypeEnum *UnmodifiedType = nullptr;
6668 Optional Modifiers;
6769 };
6870
0 //===- NativeTypeUDT.h - info about class/struct type ------------*- C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H
10 #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H
11
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/DebugInfo/CodeView/CodeView.h"
14 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
15 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
16 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
17
18 namespace llvm {
19 namespace pdb {
20
21 class NativeTypeUDT : public NativeRawSymbol {
22 public:
23 NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI,
24 codeview::ClassRecord Class);
25
26 NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI,
27 codeview::UnionRecord Union);
28
29 NativeTypeUDT(NativeSession &Session, SymIndexId Id,
30 NativeTypeUDT &UnmodifiedType,
31 codeview::ModifierRecord Modifier);
32
33 ~NativeTypeUDT() override;
34
35 void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
36 PdbSymbolIdField RecurseIdFields) const override;
37
38 std::string getName() const override;
39 SymIndexId getLexicalParentId() const override;
40 SymIndexId getUnmodifiedTypeId() const override;
41 SymIndexId getVirtualTableShapeId() const override;
42 uint64_t getLength() const override;
43 PDB_UdtType getUdtKind() const override;
44 bool hasConstructor() const override;
45 bool isConstType() const override;
46 bool hasAssignmentOperator() const override;
47 bool hasCastOperator() const override;
48 bool hasNestedTypes() const override;
49 bool hasOverloadedOperator() const override;
50 bool isInterfaceUdt() const override;
51 bool isIntrinsic() const override;
52 bool isNested() const override;
53 bool isPacked() const override;
54 bool isRefUdt() const override;
55 bool isScoped() const override;
56 bool isValueUdt() const override;
57 bool isUnalignedType() const override;
58 bool isVolatileType() const override;
59
60 protected:
61 codeview::TypeIndex Index;
62
63 Optional Class;
64 Optional Union;
65 NativeTypeUDT *UnmodifiedType = nullptr;
66 codeview::TagRecord *Tag = nullptr;
67 Optional Modifiers;
68 };
69
70 } // namespace pdb
71 } // namespace llvm
72
73 #endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H
7676 std::unique_ptr
7777 createTypeEnumerator(codeview::TypeLeafKind Kind);
7878
79 std::unique_ptr
80 createTypeEnumerator(std::vector Kinds);
81
7982 SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
8083
8184 template
3333 TypeIndex.cpp
3434 TypeIndexDiscovery.cpp
3535 TypeHashing.cpp
36 TypeRecordHelpers.cpp
3637 TypeRecordMapping.cpp
3738 TypeStreamMerger.cpp
3839 TypeTableCollection.cpp
0 //===- TypeRecordHelpers.cpp ------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
10
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
13 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
14
15 using namespace llvm;
16 using namespace llvm::codeview;
17
18 template static ClassOptions getUdtOptions(CVType CVT) {
19 RecordT Record;
20 if (auto EC = TypeDeserializer::deserializeAs(CVT, Record)) {
21 consumeError(std::move(EC));
22 return ClassOptions::None;
23 }
24 return Record.getOptions();
25 }
26
27 bool llvm::codeview::isUdtForwardRef(CVType CVT) {
28 ClassOptions UdtOptions = ClassOptions::None;
29 switch (CVT.kind()) {
30 case LF_STRUCTURE:
31 case LF_CLASS:
32 case LF_INTERFACE:
33 UdtOptions = getUdtOptions(std::move(CVT));
34 break;
35 case LF_ENUM:
36 UdtOptions = getUdtOptions(std::move(CVT));
37 break;
38 case LF_UNION:
39 UdtOptions = getUdtOptions(std::move(CVT));
40 break;
41 default:
42 return false;
43 }
44 return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None;
45 }
46
47 TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) {
48 assert(CVT.kind() == LF_MODIFIER);
49 SmallVector Refs;
50 discoverTypeIndices(CVT, Refs);
51 return Refs.front();
52 }
5454 Native/NativeTypeBuiltin.cpp
5555 Native/NativeTypeEnum.cpp
5656 Native/NativeTypePointer.cpp
57 Native/NativeTypeUDT.cpp
5758 Native/NamedStreamMap.cpp
5859 Native/NativeSession.cpp
5960 Native/PDBFile.cpp
99 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
1010
1111 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
12 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
1213 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
1314 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
1415 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
2122
2223 NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
2324 LazyRandomTypeCollection &Types,
24 TypeLeafKind Kind)
25 std::vector Kinds)
2526 : Matches(), Index(0), Session(PDBSession) {
2627 Optional TI = Types.getFirst();
2728 while (TI) {
2829 CVType CVT = Types.getType(*TI);
2930 TypeLeafKind K = CVT.kind();
30 if (K == Kind)
31 Matches.push_back(*TI);
32 else if (K == TypeLeafKind::LF_MODIFIER) {
33 ModifierRecord MR;
34 if (auto EC = TypeDeserializer::deserializeAs(CVT, MR)) {
35 consumeError(std::move(EC));
36 } else if (!MR.ModifiedType.isSimple()) {
37 CVType UnmodifiedCVT = Types.getType(MR.ModifiedType);
38 if (UnmodifiedCVT.kind() == Kind)
31 if (llvm::is_contained(Kinds, K)) {
32 // Don't add forward refs, we'll find those later while enumerating.
33 if (!isUdtForwardRef(CVT))
34 Matches.push_back(*TI);
35 } else if (K == TypeLeafKind::LF_MODIFIER) {
36 TypeIndex ModifiedTI = getModifiedType(CVT);
37 if (!ModifiedTI.isSimple()) {
38 CVType UnmodifiedCVT = Types.getType(ModifiedTI);
39 // LF_MODIFIERs point to forward refs, but don't worry about that
40 // here. We're pushing the TypeIndex of the LF_MODIFIER itself,
41 // so we'll worry about resolving forward refs later.
42 if (llvm::is_contained(Kinds, UnmodifiedCVT.kind()))
3943 Matches.push_back(*TI);
4044 }
4145 }
4246 TI = Types.getNext(*TI);
4347 }
4448 }
45
46 NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
47 const std::vector &Matches,
48 TypeLeafKind Kind)
49 : Matches(Matches), Index(0), Session(PDBSession) {}
5049
5150 uint32_t NativeEnumTypes::getChildCount() const {
5251 return static_cast(Matches.size());
4444 return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ENUM);
4545 case PDB_SymType::PointerType:
4646 return Session.getSymbolCache().createTypeEnumerator(codeview::LF_POINTER);
47 case PDB_SymType::UDT:
48 return Session.getSymbolCache().createTypeEnumerator(
49 {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION,
50 codeview::LF_INTERFACE});
4751 default:
4852 break;
4953 }
3030
3131 std::unique_ptr
3232 NativeRawSymbol::findChildren(PDB_SymType Type) const {
33 return nullptr;
33 return llvm::make_unique>();
3434 }
3535
3636 std::unique_ptr
3737 NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
3838 PDB_NameSearchFlags Flags) const {
39 return nullptr;
39 return llvm::make_unique>();
4040 }
4141
4242 std::unique_ptr
4343 NativeRawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
4444 PDB_NameSearchFlags Flags, uint32_t Section, uint32_t Offset) const {
45 return nullptr;
45 return llvm::make_unique>();
4646 }
4747
4848 std::unique_ptr
4949 NativeRawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
5050 PDB_NameSearchFlags Flags, uint64_t VA) const {
51 return nullptr;
51 return llvm::make_unique>();
5252 }
5353
5454 std::unique_ptr
5555 NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
5656 PDB_NameSearchFlags Flags, uint32_t RVA) const {
57 return nullptr;
57 return llvm::make_unique>();
5858 }
5959
6060 std::unique_ptr
6161 NativeRawSymbol::findInlineFramesByAddr(uint32_t Section,
6262 uint32_t Offset) const {
63 return nullptr;
63 return llvm::make_unique>();
6464 }
6565
6666 std::unique_ptr
6767 NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
68 return nullptr;
68 return llvm::make_unique>();
6969 }
7070
7171 std::unique_ptr
7272 NativeRawSymbol::findInlineFramesByVA(uint64_t VA) const {
73 return nullptr;
73 return llvm::make_unique>();
7474 }
7575
7676 std::unique_ptr
7777 NativeRawSymbol::findInlineeLines() const {
78 return nullptr;
78 return llvm::make_unique>();
7979 }
8080
8181 std::unique_ptr
8282 NativeRawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
8383 uint32_t Length) const {
84 return nullptr;
84 return llvm::make_unique>();
8585 }
8686
8787 std::unique_ptr
8888 NativeRawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
89 return nullptr;
89 return llvm::make_unique>();
9090 }
9191
9292 std::unique_ptr
9393 NativeRawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
94 return nullptr;
94 return llvm::make_unique>();
9595 }
9696
9797 void NativeRawSymbol::getDataBytes(SmallVector &bytes) const {
3939 class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
4040 public:
4141 NativeEnumEnumEnumerators(NativeSession &Session,
42 const NativeTypeEnum &ClassParent,
43 const codeview::EnumRecord &CVEnum);
42 const NativeTypeEnum &ClassParent);
4443
4544 uint32_t getChildCount() const override;
4645 std::unique_ptr getChildAtIndex(uint32_t Index) const override;
5554
5655 NativeSession &Session;
5756 const NativeTypeEnum &ClassParent;
58 const codeview::EnumRecord &CVEnum;
5957 std::vector Enumerators;
6058 Optional ContinuationIndex;
6159 uint32_t Index = 0;
6361 } // namespace
6462
6563 NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
66 NativeSession &Session, const NativeTypeEnum &ClassParent,
67 const codeview::EnumRecord &CVEnum)
68 : Session(Session), ClassParent(ClassParent), CVEnum(CVEnum) {
64 NativeSession &Session, const NativeTypeEnum &ClassParent)
65 : Session(Session), ClassParent(ClassParent) {
6966 TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
7067 LazyRandomTypeCollection &Types = Tpi.typeCollection();
7168
72 ContinuationIndex = CVEnum.FieldList;
69 ContinuationIndex = ClassParent.getEnumRecord().FieldList;
7370 while (ContinuationIndex) {
7471 CVType FieldList = Types.getType(*ContinuationIndex);
7572 assert(FieldList.kind() == LF_FIELDLIST);
9996 if (Index >= getChildCount())
10097 return nullptr;
10198
102 SymIndexId Id =
103 Session.getSymbolCache()
104 .getOrCreateFieldListMember(
105 CVEnum.FieldList, Index, ClassParent, Enumerators[Index]);
99 SymIndexId Id = Session.getSymbolCache()
100 .getOrCreateFieldListMember(
101 ClassParent.getEnumRecord().FieldList, Index,
102 ClassParent, Enumerators[Index]);
106103 return Session.getSymbolCache().getSymbolById(Id);
107104 }
108105
121118 Record(std::move(Record)) {}
122119
123120 NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
124 codeview::TypeIndex ModifierTI,
125 codeview::ModifierRecord Modifier,
126 codeview::EnumRecord EnumRecord)
127 : NativeRawSymbol(Session, PDB_SymType::Enum, Id), Index(ModifierTI),
128 Record(std::move(EnumRecord)), Modifiers(std::move(Modifier)) {}
121 NativeTypeEnum &UnmodifiedType,
122 codeview::ModifierRecord Modifier)
123 : NativeRawSymbol(Session, PDB_SymType::Enum, Id),
124 UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
129125
130126 NativeTypeEnum::~NativeTypeEnum() {}
131127
172168 const NativeTypeEnum *ClassParent = nullptr;
173169 if (!Modifiers)
174170 ClassParent = this;
175 else {
176 NativeRawSymbol &NRS =
177 Session.getSymbolCache().getNativeSymbolById(getUnmodifiedTypeId());
178 assert(NRS.getSymTag() == PDB_SymType::Enum);
179 ClassParent = static_cast(&NRS);
180 }
181 return llvm::make_unique(Session, *ClassParent,
182 Record);
171 else
172 ClassParent = UnmodifiedType;
173 return llvm::make_unique(Session, *ClassParent);
183174 }
184175
185176 PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
186177
187178 PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
188 Session.getSymbolCache().findSymbolByTypeIndex(Record.getUnderlyingType());
189
190 codeview::TypeIndex Underlying = Record.getUnderlyingType();
179 if (UnmodifiedType)
180 return UnmodifiedType->getBuiltinType();
181
182 Session.getSymbolCache().findSymbolByTypeIndex(Record->getUnderlyingType());
183
184 codeview::TypeIndex Underlying = Record->getUnderlyingType();
191185
192186 // This indicates a corrupt record.
193187 if (!Underlying.isSimple() ||
254248 }
255249
256250 SymIndexId NativeTypeEnum::getUnmodifiedTypeId() const {
257 if (!Modifiers)
258 return 0;
259
260 return Session.getSymbolCache().findSymbolByTypeIndex(
261 Modifiers->ModifiedType);
251 return UnmodifiedType ? UnmodifiedType->getSymIndexId() : 0;
262252 }
263253
264254 bool NativeTypeEnum::hasConstructor() const {
265 return bool(Record.getOptions() &
255 if (UnmodifiedType)
256 return UnmodifiedType->hasConstructor();
257
258 return bool(Record->getOptions() &
266259 codeview::ClassOptions::HasConstructorOrDestructor);
267260 }
268261
269262 bool NativeTypeEnum::hasAssignmentOperator() const {
270 return bool(Record.getOptions() &
263 if (UnmodifiedType)
264 return UnmodifiedType->hasAssignmentOperator();
265
266 return bool(Record->getOptions() &
271267 codeview::ClassOptions::HasOverloadedAssignmentOperator);
272268 }
273269
274270 bool NativeTypeEnum::hasNestedTypes() const {
275 return bool(Record.getOptions() &
271 if (UnmodifiedType)
272 return UnmodifiedType->hasNestedTypes();
273
274 return bool(Record->getOptions() &
276275 codeview::ClassOptions::ContainsNestedClass);
277276 }
278277
279278 bool NativeTypeEnum::isIntrinsic() const {
280 return bool(Record.getOptions() & codeview::ClassOptions::Intrinsic);
279 if (UnmodifiedType)
280 return UnmodifiedType->isIntrinsic();
281
282 return bool(Record->getOptions() & codeview::ClassOptions::Intrinsic);
281283 }
282284
283285 bool NativeTypeEnum::hasCastOperator() const {
284 return bool(Record.getOptions() &
286 if (UnmodifiedType)
287 return UnmodifiedType->hasCastOperator();
288
289 return bool(Record->getOptions() &
285290 codeview::ClassOptions::HasConversionOperator);
286291 }
287292
288293 uint64_t NativeTypeEnum::getLength() const {
294 if (UnmodifiedType)
295 return UnmodifiedType->getLength();
296
289297 const auto Id = Session.getSymbolCache().findSymbolByTypeIndex(
290 Record.getUnderlyingType());
298 Record->getUnderlyingType());
291299 const auto UnderlyingType =
292300 Session.getConcreteSymbolById(Id);
293301 return UnderlyingType ? UnderlyingType->getLength() : 0;
294302 }
295303
296 std::string NativeTypeEnum::getName() const { return Record.getName(); }
304 std::string NativeTypeEnum::getName() const {
305 if (UnmodifiedType)
306 return UnmodifiedType->getName();
307
308 return Record->getName();
309 }
297310
298311 bool NativeTypeEnum::isNested() const {
299 return bool(Record.getOptions() & codeview::ClassOptions::Nested);
312 if (UnmodifiedType)
313 return UnmodifiedType->isNested();
314
315 return bool(Record->getOptions() & codeview::ClassOptions::Nested);
300316 }
301317
302318 bool NativeTypeEnum::hasOverloadedOperator() const {
303 return bool(Record.getOptions() &
319 if (UnmodifiedType)
320 return UnmodifiedType->hasOverloadedOperator();
321
322 return bool(Record->getOptions() &
304323 codeview::ClassOptions::HasOverloadedOperator);
305324 }
306325
307326 bool NativeTypeEnum::isPacked() const {
308 return bool(Record.getOptions() & codeview::ClassOptions::Packed);
327 if (UnmodifiedType)
328 return UnmodifiedType->isPacked();
329
330 return bool(Record->getOptions() & codeview::ClassOptions::Packed);
309331 }
310332
311333 bool NativeTypeEnum::isScoped() const {
312 return bool(Record.getOptions() & codeview::ClassOptions::Scoped);
334 if (UnmodifiedType)
335 return UnmodifiedType->isScoped();
336
337 return bool(Record->getOptions() & codeview::ClassOptions::Scoped);
313338 }
314339
315340 SymIndexId NativeTypeEnum::getTypeId() const {
341 if (UnmodifiedType)
342 return UnmodifiedType->getTypeId();
343
316344 return Session.getSymbolCache().findSymbolByTypeIndex(
317 Record.getUnderlyingType());
345 Record->getUnderlyingType());
318346 }
319347
320348 bool NativeTypeEnum::isRefUdt() const { return false; }
345373 }
346374
347375 const NativeTypeBuiltin &NativeTypeEnum::getUnderlyingBuiltinType() const {
376 if (UnmodifiedType)
377 return UnmodifiedType->getUnderlyingBuiltinType();
378
348379 return Session.getSymbolCache().getNativeSymbolById(
349380 getTypeId());
350381 }
0 //===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
10
11 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
12
13 #include
14
15 using namespace llvm;
16 using namespace llvm::codeview;
17 using namespace llvm::pdb;
18
19 NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
20 codeview::TypeIndex TI, codeview::ClassRecord CR)
21 : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
22 Class(std::move(CR)), Tag(Class.getPointer()) {}
23
24 NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
25 codeview::TypeIndex TI, codeview::UnionRecord UR)
26 : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
27 Union(std::move(UR)), Tag(Union.getPointer()) {}
28
29 NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
30 NativeTypeUDT &UnmodifiedType,
31 codeview::ModifierRecord Modifier)
32 : NativeRawSymbol(Session, PDB_SymType::UDT, Id),
33 UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
34
35 NativeTypeUDT::~NativeTypeUDT() {}
36
37 void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
38 PdbSymbolIdField ShowIdFields,
39 PdbSymbolIdField RecurseIdFields) const {
40
41 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
42
43 dumpSymbolField(OS, "name", getName(), Indent);
44 dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
45 PdbSymbolIdField::LexicalParent, ShowIdFields,
46 RecurseIdFields);
47 if (Modifiers.hasValue())
48 dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
49 Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
50 RecurseIdFields);
51 if (getUdtKind() != PDB_UdtType::Union)
52 dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(),
53 Indent);
54 dumpSymbolField(OS, "length", getLength(), Indent);
55 dumpSymbolField(OS, "udtKind", getUdtKind(), Indent);
56 dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
57 dumpSymbolField(OS, "constType", isConstType(), Indent);
58 dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
59 dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
60 dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
61 dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
62 dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
63 dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
64 dumpSymbolField(OS, "nested", isNested(), Indent);
65 dumpSymbolField(OS, "packed", isPacked(), Indent);
66 dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
67 dumpSymbolField(OS, "scoped", isScoped(), Indent);
68 dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
69 dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
70 dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
71 }
72
73 std::string NativeTypeUDT::getName() const {
74 if (UnmodifiedType)
75 return UnmodifiedType->getName();
76
77 return Tag->getName();
78 }
79
80 SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
81
82 SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
83 if (UnmodifiedType)
84 return UnmodifiedType->getSymIndexId();
85
86 return 0;
87 }
88
89 SymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
90 if (UnmodifiedType)
91 return UnmodifiedType->getVirtualTableShapeId();
92
93 if (Class)
94 return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape);
95
96 return 0;
97 }
98
99 uint64_t NativeTypeUDT::getLength() const {
100 if (UnmodifiedType)
101 return UnmodifiedType->getLength();
102
103 if (Class)
104 return Class->getSize();
105
106 return Union->getSize();
107 }
108
109 PDB_UdtType NativeTypeUDT::getUdtKind() const {
110 if (UnmodifiedType)
111 return UnmodifiedType->getUdtKind();
112
113 switch (Tag->Kind) {
114 case TypeRecordKind::Class:
115 return PDB_UdtType::Class;
116 case TypeRecordKind::Union:
117 return PDB_UdtType::Union;
118 case TypeRecordKind::Struct:
119 return PDB_UdtType::Struct;
120 case TypeRecordKind::Interface:
121 return PDB_UdtType::Interface;
122 default:
123 llvm_unreachable("Unexected udt kind");
124 }
125 }
126
127 bool NativeTypeUDT::hasConstructor() const {
128 if (UnmodifiedType)
129 return UnmodifiedType->hasConstructor();
130
131 return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
132 ClassOptions::None;
133 }
134
135 bool NativeTypeUDT::isConstType() const {
136 if (!Modifiers)
137 return false;
138 return (Modifiers->Modifiers & ModifierOptions::Const) !=
139 ModifierOptions::None;
140 }
141
142 bool NativeTypeUDT::hasAssignmentOperator() const {
143 if (UnmodifiedType)
144 return UnmodifiedType->hasAssignmentOperator();
145
146 return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
147 ClassOptions::None;
148 }
149
150 bool NativeTypeUDT::hasCastOperator() const {
151 if (UnmodifiedType)
152 return UnmodifiedType->hasCastOperator();
153
154 return (Tag->Options & ClassOptions::HasConversionOperator) !=
155 ClassOptions::None;
156 }
157
158 bool NativeTypeUDT::hasNestedTypes() const {
159 if (UnmodifiedType)
160 return UnmodifiedType->hasNestedTypes();
161
162 return (Tag->Options & ClassOptions::ContainsNestedClass) !=
163 ClassOptions::None;
164 }
165
166 bool NativeTypeUDT::hasOverloadedOperator() const {
167 if (UnmodifiedType)
168 return UnmodifiedType->hasOverloadedOperator();
169
170 return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
171 ClassOptions::None;
172 }
173
174 bool NativeTypeUDT::isInterfaceUdt() const { return false; }
175
176 bool NativeTypeUDT::isIntrinsic() const {
177 if (UnmodifiedType)
178 return UnmodifiedType->isIntrinsic();
179
180 return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
181 }
182
183 bool NativeTypeUDT::isNested() const {
184 if (UnmodifiedType)
185 return UnmodifiedType->isNested();
186
187 return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
188 }
189
190 bool NativeTypeUDT::isPacked() const {
191 if (UnmodifiedType)
192 return UnmodifiedType->isPacked();
193
194 return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
195 }
196
197 bool NativeTypeUDT::isRefUdt() const { return false; }
198
199 bool NativeTypeUDT::isScoped() const {
200 if (UnmodifiedType)
201 return UnmodifiedType->isScoped();
202
203 return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
204 }
205
206 bool NativeTypeUDT::isValueUdt() const { return false; }
207
208 bool NativeTypeUDT::isUnalignedType() const {
209 if (!Modifiers)
210 return false;
211 return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
212 ModifierOptions::None;
213 }
214
215 bool NativeTypeUDT::isVolatileType() const {
216 if (!Modifiers)
217 return false;
218 return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
219 ModifierOptions::None;
220 }
0 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
11
22 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
3 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
34 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
45 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
56 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
89 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
910 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
1011 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
12 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
1113 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1214 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
1315 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
4951
5052 if (Dbi)
5153 Compilands.resize(Dbi->modules().getModuleCount());
54
55 auto &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
56 Tpi.buildHashMap();
5257 }
5358
5459 std::unique_ptr
55 SymbolCache::createTypeEnumerator(codeview::TypeLeafKind Kind) {
60 SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
61 return createTypeEnumerator(std::vector{Kind});
62 }
63
64 std::unique_ptr
65 SymbolCache::createTypeEnumerator(std::vector Kinds) {
5666 auto Tpi = Session.getPDBFile().getPDBTpiStream();
5767 if (!Tpi) {
5868 consumeError(Tpi.takeError());
6070 }
6171 auto &Types = Tpi->typeCollection();
6272 return std::unique_ptr(
63 new NativeEnumTypes(Session, Types, Kind));
73 new NativeEnumTypes(Session, Types, std::move(Kinds)));
6474 }
6575
6676 SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
97107 if (Record.ModifiedType.isSimple())
98108 return createSimpleType(Record.ModifiedType, Record.Modifiers);
99109
100 auto Tpi = Session.getPDBFile().getPDBTpiStream();
101 if (!Tpi) {
102 consumeError(Tpi.takeError());
103 return 0;
104 }
105 codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
106
107 codeview::CVType UnmodifiedType = Types.getType(Record.ModifiedType);
108
109 switch (UnmodifiedType.kind()) {
110 case LF_ENUM: {
111 EnumRecord ER;
112 if (auto EC =
113 TypeDeserializer::deserializeAs(UnmodifiedType, ER)) {
114 consumeError(std::move(EC));
115 return 0;
116 }
117 return createSymbol(Record.ModifiedType, std::move(Record),
118 std::move(ER));
119 }
120 case LF_STRUCTURE:
121 case LF_UNION:
122 case LF_CLASS:
123 // FIXME: Handle these
124 break;
110 // Make sure we create and cache a record for the unmodified type.
111 SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
112 NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
113
114 switch (UnmodifiedNRS.getSymTag()) {
115 case PDB_SymType::Enum:
116 return createSymbol(
117 static_cast(UnmodifiedNRS), std::move(Record));
118 case PDB_SymType::UDT:
119 return createSymbol(
120 static_cast(UnmodifiedNRS), std::move(Record));
125121 default:
126122 // No other types can be modified. (LF_POINTER, for example, records
127123 // its modifiers a different way.
128124 assert(false && "Invalid LF_MODIFIER record");
129125 break;
130126 }
131 return createSymbolPlaceholder();
127 return 0;
132128 }
133129
134130 SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
149145 }
150146 codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
151147 codeview::CVType CVT = Types.getType(Index);
152 // TODO(amccarth): Make this handle all types.
148
149 if (isUdtForwardRef(CVT)) {
150 Expected EFD = Tpi->findFullDeclForForwardRef(Index);
151
152 if (!EFD)
153 consumeError(EFD.takeError());
154 else if (*EFD != Index) {
155 assert(!isUdtForwardRef(Types.getType(*EFD)));
156 SymIndexId Result = findSymbolByTypeIndex(*EFD);
157 // Record a mapping from ForwardRef -> SymIndex of complete type so that
158 // we'll take the fast path next time.
159 TypeIndexToSymbolId[Index] = Result;
160 return Result;
161 }
162 }
163
164 // At this point if we still have a forward ref udt it means the full decl was
165 // not in the PDB. We just have to deal with it and use the forward ref.
153166 SymIndexId Id = 0;
154
155167 switch (CVT.kind()) {
156168 case codeview::LF_ENUM:
157169 Id = createSymbolForType(Index, std::move(CVT));
170 break;
171 case codeview::LF_CLASS:
172 case codeview::LF_STRUCTURE:
173 case codeview::LF_INTERFACE:
174 Id = createSymbolForType(Index, std::move(CVT));
175 break;
176 case codeview::LF_UNION:
177 Id = createSymbolForType(Index, std::move(CVT));
158178 break;
159179 case codeview::LF_POINTER:
160180 Id = createSymbolForType(Index,
1010
1111 #include "llvm/ADT/iterator_range.h"
1212 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
13 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
14 #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
1513 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
14 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
1615 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1716 #include "llvm/DebugInfo/PDB/Native/Hash.h"
1817 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
160159
161160 bool TpiStream::supportsTypeLookup() const { return !HashMap.empty(); }
162161
163 template static ClassOptions getUdtOptions(CVType CVT) {
164 RecordT Record;
165 if (auto EC = TypeDeserializer::deserializeAs(CVT, Record)) {
166 consumeError(std::move(EC));
167 return ClassOptions::None;
168 }
169 return Record.getOptions();
170 }
171
172 static bool isUdtForwardRef(CVType CVT) {
173 ClassOptions UdtOptions = ClassOptions::None;
174 switch (CVT.kind()) {
175 case LF_STRUCTURE:
176 case LF_CLASS:
177 case LF_INTERFACE:
178 UdtOptions = getUdtOptions(std::move(CVT));
179 break;
180 case LF_ENUM:
181 UdtOptions = getUdtOptions(std::move(CVT));
182 break;
183 case LF_UNION:
184 UdtOptions = getUdtOptions(std::move(CVT));
185 break;
186 default:
187 return false;
188 }
189 return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None;
190 }
191
192162 Expected
193163 TpiStream::findFullDeclForForwardRef(TypeIndex ForwardRefTI) const {
194164 CVType F = Types->getType(ForwardRefTI);
0 ; RUN: llvm-pdbutil pretty -native -classes %p/../Inputs/every-class.pdb \
1 ; RUN: | FileCheck -check-prefix=PRETTY %s
2
3 ; RUN: llvm-pdbutil diadump -native -udts %p/../Inputs/every-class.pdb \
4 ; RUN: | FileCheck -check-prefix=DUMP %s
5
6
7 PRETTY: struct main::__l2:: [sizeof = 1]
8 PRETTY: struct main::__l2::Scoped [sizeof = 1]
9 PRETTY: struct __vc_attributes::event_sourceAttribute [sizeof = 12]
10 PRETTY: struct __vc_attributes::helper_attributes::v1_alttypeAttribute [sizeof = 4]
11 PRETTY: struct __vc_attributes::helper_attributes::usageAttribute [sizeof = 4]
12 PRETTY: struct __vc_attributes::threadingAttribute [sizeof = 4]
13 PRETTY: struct __vc_attributes::aggregatableAttribute [sizeof = 4]
14 PRETTY: struct __vc_attributes::event_receiverAttribute [sizeof = 8]
15 PRETTY: struct __vc_attributes::moduleAttribute [sizeof = 96]
16 PRETTY: struct Nested [sizeof = 1]
17 PRETTY: struct Nested::F [sizeof = 1]
18 PRETTY: struct Constructor [sizeof = 1]
19 PRETTY: class Class [sizeof = 1]
20 PRETTY: union Union [sizeof = 1]
21 PRETTY: struct Operator [sizeof = 1]
22 PRETTY: struct Cast [sizeof = 1]
23 PRETTY: struct Nothing [sizeof = 1]
24 PRETTY: struct Assignment [sizeof = 1]
25 PRETTY: const struct Nothing
26 PRETTY: volatile struct Nothing
27 PRETTY: const volatile struct Nothing
28 PRETTY: unaligned struct Nothing
29
30 ; DUMP: {
31 ; DUMP-NEXT: symIndexId: 2
32 ; DUMP-NEXT: symTag: UDT
33 ; DUMP-NEXT: name: main::__l2::
34 ; DUMP-NEXT: virtualTableShapeId: 3
35 ; DUMP-NEXT: length: 1
36 ; DUMP-NEXT: udtKind: struct
37 ; DUMP-NEXT: constructor: 0
38 ; DUMP-NEXT: constType: 0
39 ; DUMP-NEXT: hasAssignmentOperator: 0
40 ; DUMP-NEXT: hasCastOperator: 0
41 ; DUMP-NEXT: hasNestedTypes: 0
42 ; DUMP-NEXT: overloadedOperator: 0
43 ; DUMP-NEXT: isInterfaceUdt: 0
44 ; DUMP-NEXT: intrinsic: 0
45 ; DUMP-NEXT: nested: 0
46 ; DUMP-NEXT: packed: 0
47 ; DUMP-NEXT: isRefUdt: 0
48 ; DUMP-NEXT: scoped: 1
49 ; DUMP-NEXT: unalignedType: 0
50 ; DUMP-NEXT: isValueUdt: 0
51 ; DUMP-NEXT: volatileType: 0
52 ; DUMP-NEXT: }
53 ; DUMP-NEXT: {
54 ; DUMP-NEXT: symIndexId: 4
55 ; DUMP-NEXT: symTag: UDT
56 ; DUMP-NEXT: name: main::__l2::Scoped
57 ; DUMP-NEXT: virtualTableShapeId: 3
58 ; DUMP-NEXT: length: 1
59 ; DUMP-NEXT: udtKind: struct
60 ; DUMP-NEXT: constructor: 0
61 ; DUMP-NEXT: constType: 0
62 ; DUMP-NEXT: hasAssignmentOperator: 0
63 ; DUMP-NEXT: hasCastOperator: 0
64 ; DUMP-NEXT: hasNestedTypes: 0
65 ; DUMP-NEXT: overloadedOperator: 0
66 ; DUMP-NEXT: isInterfaceUdt: 0
67 ; DUMP-NEXT: intrinsic: 0
68 ; DUMP-NEXT: nested: 0
69 ; DUMP-NEXT: packed: 0
70 ; DUMP-NEXT: isRefUdt: 0
71 ; DUMP-NEXT: scoped: 1
72 ; DUMP-NEXT: unalignedType: 0
73 ; DUMP-NEXT: isValueUdt: 0
74 ; DUMP-NEXT: volatileType: 0
75 ; DUMP-NEXT: }
76 ; DUMP-NEXT: {
77 ; DUMP-NEXT: symIndexId: 5
78 ; DUMP-NEXT: symTag: UDT
79 ; DUMP-NEXT: name: __vc_attributes::event_sourceAttribute
80 ; DUMP-NEXT: virtualTableShapeId: 3
81 ; DUMP-NEXT: length: 12
82 ; DUMP-NEXT: udtKind: struct
83 ; DUMP-NEXT: constructor: 1
84 ; DUMP-NEXT: constType: 0
85 ; DUMP-NEXT: hasAssignmentOperator: 0
86 ; DUMP-NEXT: hasCastOperator: 0
87 ; DUMP-NEXT: hasNestedTypes: 1
88 ; DUMP-NEXT: overloadedOperator: 0
89 ; DUMP-NEXT: isInterfaceUdt: 0
90 ; DUMP-NEXT: intrinsic: 0
91 ; DUMP-NEXT: nested: 0
92 ; DUMP-NEXT: packed: 0
93 ; DUMP-NEXT: isRefUdt: 0
94 ; DUMP-NEXT: scoped: 0
95 ; DUMP-NEXT: unalignedType: 0
96 ; DUMP-NEXT: isValueUdt: 0
97 ; DUMP-NEXT: volatileType: 0
98 ; DUMP-NEXT: }
99 ; DUMP-NEXT: {
100 ; DUMP-NEXT: symIndexId: 6
101 ; DUMP-NEXT: symTag: UDT
102 ; DUMP-NEXT: name: __vc_attributes::helper_attributes::v1_alttypeAttribute
103 ; DUMP-NEXT: virtualTableShapeId: 3
104 ; DUMP-NEXT: length: 4
105 ; DUMP-NEXT: udtKind: struct
106 ; DUMP-NEXT: constructor: 1
107 ; DUMP-NEXT: constType: 0
108 ; DUMP-NEXT: hasAssignmentOperator: 0
109 ; DUMP-NEXT: hasCastOperator: 0
110 ; DUMP-NEXT: hasNestedTypes: 1
111 ; DUMP-NEXT: overloadedOperator: 0
112 ; DUMP-NEXT: isInterfaceUdt: 0
113 ; DUMP-NEXT: intrinsic: 0
114 ; DUMP-NEXT: nested: 0
115 ; DUMP-NEXT: packed: 0
116 ; DUMP-NEXT: isRefUdt: 0
117 ; DUMP-NEXT: scoped: 0
118 ; DUMP-NEXT: unalignedType: 0
119 ; DUMP-NEXT: isValueUdt: 0
120 ; DUMP-NEXT: volatileType: 0
121 ; DUMP-NEXT: }
122 ; DUMP-NEXT: {
123 ; DUMP-NEXT: symIndexId: 7
124 ; DUMP-NEXT: symTag: UDT
125 ; DUMP-NEXT: name: __vc_attributes::helper_attributes::usageAttribute
126 ; DUMP-NEXT: virtualTableShapeId: 3
127 ; DUMP-NEXT: length: 4
128 ; DUMP-NEXT: udtKind: struct
129 ; DUMP-NEXT: constructor: 1
130 ; DUMP-NEXT: constType: 0
131 ; DUMP-NEXT: hasAssignmentOperator: 0
132 ; DUMP-NEXT: hasCastOperator: 0
133 ; DUMP-NEXT: hasNestedTypes: 1
134 ; DUMP-NEXT: overloadedOperator: 0
135 ; DUMP-NEXT: isInterfaceUdt: 0
136 ; DUMP-NEXT: intrinsic: 0
137 ; DUMP-NEXT: nested: 0
138 ; DUMP-NEXT: packed: 0
139 ; DUMP-NEXT: isRefUdt: 0
140 ; DUMP-NEXT: scoped: 0
141 ; DUMP-NEXT: unalignedType: 0
142 ; DUMP-NEXT: isValueUdt: 0
143 ; DUMP-NEXT: volatileType: 0
144 ; DUMP-NEXT: }
145 ; DUMP-NEXT: {
146 ; DUMP-NEXT: symIndexId: 8
147 ; DUMP-NEXT: symTag: UDT
148 ; DUMP-NEXT: name: __vc_attributes::threadingAttribute
149 ; DUMP-NEXT: virtualTableShapeId: 3
150 ; DUMP-NEXT: length: 4
151 ; DUMP-NEXT: udtKind: struct
152 ; DUMP-NEXT: constructor: 1
153 ; DUMP-NEXT: constType: 0
154 ; DUMP-NEXT: hasAssignmentOperator: 0
155 ; DUMP-NEXT: hasCastOperator: 0
156 ; DUMP-NEXT: hasNestedTypes: 1
157 ; DUMP-NEXT: overloadedOperator: 0
158 ; DUMP-NEXT: isInterfaceUdt: 0
159 ; DUMP-NEXT: intrinsic: 0
160 ; DUMP-NEXT: nested: 0
161 ; DUMP-NEXT: packed: 0
162 ; DUMP-NEXT: isRefUdt: 0
163 ; DUMP-NEXT: scoped: 0
164 ; DUMP-NEXT: unalignedType: 0
165 ; DUMP-NEXT: isValueUdt: 0
166 ; DUMP-NEXT: volatileType: 0
167 ; DUMP-NEXT: }
168 ; DUMP-NEXT: {
169 ; DUMP-NEXT: symIndexId: 9
170 ; DUMP-NEXT: symTag: UDT
171 ; DUMP-NEXT: name: __vc_attributes::aggregatableAttribute
172 ; DUMP-NEXT: virtualTableShapeId: 3
173 ; DUMP-NEXT: length: 4
174 ; DUMP-NEXT: udtKind: struct
175 ; DUMP-NEXT: constructor: 1
176 ; DUMP-NEXT: constType: 0
177 ; DUMP-NEXT: hasAssignmentOperator: 0
178 ; DUMP-NEXT: hasCastOperator: 0
179 ; DUMP-NEXT: hasNestedTypes: 1
180 ; DUMP-NEXT: overloadedOperator: 0
181 ; DUMP-NEXT: isInterfaceUdt: 0
182 ; DUMP-NEXT: intrinsic: 0
183 ; DUMP-NEXT: nested: 0
184 ; DUMP-NEXT: packed: 0
185 ; DUMP-NEXT: isRefUdt: 0
186 ; DUMP-NEXT: scoped: 0
187 ; DUMP-NEXT: unalignedType: 0
188 ; DUMP-NEXT: isValueUdt: 0
189 ; DUMP-NEXT: volatileType: 0
190 ; DUMP-NEXT: }
191 ; DUMP-NEXT: {
192 ; DUMP-NEXT: symIndexId: 10
193 ; DUMP-NEXT: symTag: UDT
194 ; DUMP-NEXT: name: __vc_attributes::event_receiverAttribute
195 ; DUMP-NEXT: virtualTableShapeId: 3
196 ; DUMP-NEXT: length: 8
197 ; DUMP-NEXT: udtKind: struct
198 ; DUMP-NEXT: constructor: 1
199 ; DUMP-NEXT: constType: 0
200 ; DUMP-NEXT: hasAssignmentOperator: 0
201 ; DUMP-NEXT: hasCastOperator: 0
202 ; DUMP-NEXT: hasNestedTypes: 1
203 ; DUMP-NEXT: overloadedOperator: 0
204 ; DUMP-NEXT: isInterfaceUdt: 0
205 ; DUMP-NEXT: intrinsic: 0
206 ; DUMP-NEXT: nested: 0
207 ; DUMP-NEXT: packed: 0
208 ; DUMP-NEXT: isRefUdt: 0
209 ; DUMP-NEXT: scoped: 0
210 ; DUMP-NEXT: unalignedType: 0
211 ; DUMP-NEXT: isValueUdt: 0
212 ; DUMP-NEXT: volatileType: 0
213 ; DUMP-NEXT: }
214 ; DUMP-NEXT: {
215 ; DUMP-NEXT: symIndexId: 11
216 ; DUMP-NEXT: symTag: UDT
217 ; DUMP-NEXT: name: __vc_attributes::moduleAttribute
218 ; DUMP-NEXT: virtualTableShapeId: 3
219 ; DUMP-NEXT: length: 96
220 ; DUMP-NEXT: udtKind: struct
221 ; DUMP-NEXT: constructor: 1
222 ; DUMP-NEXT: constType: 0
223 ; DUMP-NEXT: hasAssignmentOperator: 0
224 ; DUMP-NEXT: hasCastOperator: 0
225 ; DUMP-NEXT: hasNestedTypes: 1
226 ; DUMP-NEXT: overloadedOperator: 0
227 ; DUMP-NEXT: isInterfaceUdt: 0
228 ; DUMP-NEXT: intrinsic: 0
229 ; DUMP-NEXT: nested: 0
230 ; DUMP-NEXT: packed: 0
231 ; DUMP-NEXT: isRefUdt: 0
232 ; DUMP-NEXT: scoped: 0
233 ; DUMP-NEXT: unalignedType: 0
234 ; DUMP-NEXT: isValueUdt: 0
235 ; DUMP-NEXT: volatileType: 0
236 ; DUMP-NEXT: }
237 ; DUMP-NEXT: {
238 ; DUMP-NEXT: symIndexId: 12
239 ; DUMP-NEXT: symTag: UDT
240 ; DUMP-NEXT: name: Nested
241 ; DUMP-NEXT: virtualTableShapeId: 3
242 ; DUMP-NEXT: length: 1
243 ; DUMP-NEXT: udtKind: struct
244 ; DUMP-NEXT: constructor: 0
245 ; DUMP-NEXT: constType: 0
246 ; DUMP-NEXT: hasAssignmentOperator: 0
247 ; DUMP-NEXT: hasCastOperator: 0
248 ; DUMP-NEXT: hasNestedTypes: 1
249 ; DUMP-NEXT: overloadedOperator: 0
250 ; DUMP-NEXT: isInterfaceUdt: 0
251 ; DUMP-NEXT: intrinsic: 0
252 ; DUMP-NEXT: nested: 0
253 ; DUMP-NEXT: packed: 0
254 ; DUMP-NEXT: isRefUdt: 0
255 ; DUMP-NEXT: scoped: 0
256 ; DUMP-NEXT: unalignedType: 0
257 ; DUMP-NEXT: isValueUdt: 0
258 ; DUMP-NEXT: volatileType: 0
259 ; DUMP-NEXT: }
260 ; DUMP-NEXT: {
261 ; DUMP-NEXT: symIndexId: 13
262 ; DUMP-NEXT: symTag: UDT
263 ; DUMP-NEXT: name: Nested::F
264 ; DUMP-NEXT: virtualTableShapeId: 3
265 ; DUMP-NEXT: length: 1
266 ; DUMP-NEXT: udtKind: struct
267 ; DUMP-NEXT: constructor: 0
268 ; DUMP-NEXT: constType: 0
269 ; DUMP-NEXT: hasAssignmentOperator: 0
270 ; DUMP-NEXT: hasCastOperator: 0
271 ; DUMP-NEXT: hasNestedTypes: 0
272 ; DUMP-NEXT: overloadedOperator: 0
273 ; DUMP-NEXT: isInterfaceUdt: 0
274 ; DUMP-NEXT: intrinsic: 0
275 ; DUMP-NEXT: nested: 1
276 ; DUMP-NEXT: packed: 0
277 ; DUMP-NEXT: isRefUdt: 0
278 ; DUMP-NEXT: scoped: 0
279 ; DUMP-NEXT: unalignedType: 0
280 ; DUMP-NEXT: isValueUdt: 0
281 ; DUMP-NEXT: volatileType: 0
282 ; DUMP-NEXT: }
283 ; DUMP-NEXT: {
284 ; DUMP-NEXT: symIndexId: 14
285 ; DUMP-NEXT: symTag: UDT
286 ; DUMP-NEXT: name: Constructor
287 ; DUMP-NEXT: virtualTableShapeId: 3
288 ; DUMP-NEXT: length: 1
289 ; DUMP-NEXT: udtKind: struct
290 ; DUMP-NEXT: constructor: 1
291 ; DUMP-NEXT: constType: 0
292 ; DUMP-NEXT: hasAssignmentOperator: 0
293 ; DUMP-NEXT: hasCastOperator: 0
294 ; DUMP-NEXT: hasNestedTypes: 0
295 ; DUMP-NEXT: overloadedOperator: 0
296 ; DUMP-NEXT: isInterfaceUdt: 0
297 ; DUMP-NEXT: intrinsic: 0
298 ; DUMP-NEXT: nested: 0
299 ; DUMP-NEXT: packed: 0
300 ; DUMP-NEXT: isRefUdt: 0
301 ; DUMP-NEXT: scoped: 0
302 ; DUMP-NEXT: unalignedType: 0
303 ; DUMP-NEXT: isValueUdt: 0
304 ; DUMP-NEXT: volatileType: 0
305 ; DUMP-NEXT: }
306 ; DUMP-NEXT: {
307 ; DUMP-NEXT: symIndexId: 15
308 ; DUMP-NEXT: symTag: UDT
309 ; DUMP-NEXT: name: Class
310 ; DUMP-NEXT: virtualTableShapeId: 3
311 ; DUMP-NEXT: length: 1
312 ; DUMP-NEXT: udtKind: class
313 ; DUMP-NEXT: constructor: 0
314 ; DUMP-NEXT: constType: 0
315 ; DUMP-NEXT: hasAssignmentOperator: 0
316 ; DUMP-NEXT: hasCastOperator: 0
317 ; DUMP-NEXT: hasNestedTypes: 0
318 ; DUMP-NEXT: overloadedOperator: 0
319 ; DUMP-NEXT: isInterfaceUdt: 0
320 ; DUMP-NEXT: intrinsic: 0
321 ; DUMP-NEXT: nested: 0
322 ; DUMP-NEXT: packed: 0
323 ; DUMP-NEXT: isRefUdt: 0
324 ; DUMP-NEXT: scoped: 0
325 ; DUMP-NEXT: unalignedType: 0
326 ; DUMP-NEXT: isValueUdt: 0
327 ; DUMP-NEXT: volatileType: 0
328 ; DUMP-NEXT: }
329 ; DUMP-NEXT: {
330 ; DUMP-NEXT: symIndexId: 16
331 ; DUMP-NEXT: symTag: UDT
332 ; DUMP-NEXT: name: Union
333 ; DUMP-NEXT: length: 1
334 ; DUMP-NEXT: udtKind: union
335 ; DUMP-NEXT: constructor: 0
336 ; DUMP-NEXT: constType: 0
337 ; DUMP-NEXT: hasAssignmentOperator: 0
338 ; DUMP-NEXT: hasCastOperator: 0
339 ; DUMP-NEXT: hasNestedTypes: 0
340 ; DUMP-NEXT: overloadedOperator: 0
341 ; DUMP-NEXT: isInterfaceUdt: 0
342 ; DUMP-NEXT: intrinsic: 0
343 ; DUMP-NEXT: nested: 0
344 ; DUMP-NEXT: packed: 0
345 ; DUMP-NEXT: isRefUdt: 0
346 ; DUMP-NEXT: scoped: 0
347 ; DUMP-NEXT: unalignedType: 0
348 ; DUMP-NEXT: isValueUdt: 0
349 ; DUMP-NEXT: volatileType: 0
350 ; DUMP-NEXT: }
351 ; DUMP-NEXT: {
352 ; DUMP-NEXT: symIndexId: 17
353 ; DUMP-NEXT: symTag: UDT
354 ; DUMP-NEXT: name: Operator
355 ; DUMP-NEXT: virtualTableShapeId: 3
356 ; DUMP-NEXT: length: 1
357 ; DUMP-NEXT: udtKind: struct
358 ; DUMP-NEXT: constructor: 0
359 ; DUMP-NEXT: constType: 0
360 ; DUMP-NEXT: hasAssignmentOperator: 0
361 ; DUMP-NEXT: hasCastOperator: 0
362 ; DUMP-NEXT: hasNestedTypes: 0
363 ; DUMP-NEXT: overloadedOperator: 1
364 ; DUMP-NEXT: isInterfaceUdt: 0
365 ; DUMP-NEXT: intrinsic: 0
366 ; DUMP-NEXT: nested: 0
367 ; DUMP-NEXT: packed: 0
368 ; DUMP-NEXT: isRefUdt: 0
369 ; DUMP-NEXT: scoped: 0
370 ; DUMP-NEXT: unalignedType: 0
371 ; DUMP-NEXT: isValueUdt: 0
372 ; DUMP-NEXT: volatileType: 0
373 ; DUMP-NEXT: }
374 ; DUMP-NEXT: {
375 ; DUMP-NEXT: symIndexId: 18
376 ; DUMP-NEXT: symTag: UDT
377 ; DUMP-NEXT: name: Cast
378 ; DUMP-NEXT: virtualTableShapeId: 3
379 ; DUMP-NEXT: length: 1
380 ; DUMP-NEXT: udtKind: struct
381 ; DUMP-NEXT: constructor: 0
382 ; DUMP-NEXT: constType: 0
383 ; DUMP-NEXT: hasAssignmentOperator: 0
384 ; DUMP-NEXT: hasCastOperator: 1
385 ; DUMP-NEXT: hasNestedTypes: 0
386 ; DUMP-NEXT: overloadedOperator: 1
387 ; DUMP-NEXT: isInterfaceUdt: 0
388 ; DUMP-NEXT: intrinsic: 0
389 ; DUMP-NEXT: nested: 0
390 ; DUMP-NEXT: packed: 0
391 ; DUMP-NEXT: isRefUdt: 0
392 ; DUMP-NEXT: scoped: 0
393 ; DUMP-NEXT: unalignedType: 0
394 ; DUMP-NEXT: isValueUdt: 0
395 ; DUMP-NEXT: volatileType: 0
396 ; DUMP-NEXT: }
397 ; DUMP-NEXT: {
398 ; DUMP-NEXT: symIndexId: 19
399 ; DUMP-NEXT: symTag: UDT
400 ; DUMP-NEXT: name: Nothing
401 ; DUMP-NEXT: virtualTableShapeId: 3
402 ; DUMP-NEXT: length: 1
403 ; DUMP-NEXT: udtKind: struct
404 ; DUMP-NEXT: constructor: 0
405 ; DUMP-NEXT: constType: 0
406 ; DUMP-NEXT: hasAssignmentOperator: 0
407 ; DUMP-NEXT: hasCastOperator: 0
408 ; DUMP-NEXT: hasNestedTypes: 0
409 ; DUMP-NEXT: overloadedOperator: 0
410 ; DUMP-NEXT: isInterfaceUdt: 0
411 ; DUMP-NEXT: intrinsic: 0
412 ; DUMP-NEXT: nested: 0
413 ; DUMP-NEXT: packed: 0
414 ; DUMP-NEXT: isRefUdt: 0
415 ; DUMP-NEXT: scoped: 0
416 ; DUMP-NEXT: unalignedType: 0
417 ; DUMP-NEXT: isValueUdt: 0
418 ; DUMP-NEXT: volatileType: 0
419 ; DUMP-NEXT: }
420 ; DUMP-NEXT: {
421 ; DUMP-NEXT: symIndexId: 20
422 ; DUMP-NEXT: symTag: UDT
423 ; DUMP-NEXT: name: Assignment
424 ; DUMP-NEXT: virtualTableShapeId: 3
425 ; DUMP-NEXT: length: 1
426 ; DUMP-NEXT: udtKind: struct
427 ; DUMP-NEXT: constructor: 0
428 ; DUMP-NEXT: constType: 0
429 ; DUMP-NEXT: hasAssignmentOperator: 1
430 ; DUMP-NEXT: hasCastOperator: 0
431 ; DUMP-NEXT: hasNestedTypes: 0
432 ; DUMP-NEXT: overloadedOperator: 1
433 ; DUMP-NEXT: isInterfaceUdt: 0
434 ; DUMP-NEXT: intrinsic: 0
435 ; DUMP-NEXT: nested: 0
436 ; DUMP-NEXT: packed: 0
437 ; DUMP-NEXT: isRefUdt: 0
438 ; DUMP-NEXT: scoped: 0
439 ; DUMP-NEXT: unalignedType: 0
440 ; DUMP-NEXT: isValueUdt: 0
441 ; DUMP-NEXT: volatileType: 0
442 ; DUMP-NEXT: }
443 ; DUMP-NEXT: {
444 ; DUMP-NEXT: symIndexId: 21
445 ; DUMP-NEXT: symTag: UDT
446 ; DUMP-NEXT: name: Nothing
447 ; DUMP-NEXT: unmodifiedTypeId: 19
448 ; DUMP-NEXT: virtualTableShapeId: 3
449 ; DUMP-NEXT: length: 1
450 ; DUMP-NEXT: udtKind: struct
451 ; DUMP-NEXT: constructor: 0
452 ; DUMP-NEXT: constType: 1
453 ; DUMP-NEXT: hasAssignmentOperator: 0
454 ; DUMP-NEXT: hasCastOperator: 0
455 ; DUMP-NEXT: hasNestedTypes: 0
456 ; DUMP-NEXT: overloadedOperator: 0
457 ; DUMP-NEXT: isInterfaceUdt: 0
458 ; DUMP-NEXT: intrinsic: 0
459 ; DUMP-NEXT: nested: 0
460 ; DUMP-NEXT: packed: 0
461 ; DUMP-NEXT: isRefUdt: 0
462 ; DUMP-NEXT: scoped: 0
463 ; DUMP-NEXT: unalignedType: 0
464 ; DUMP-NEXT: isValueUdt: 0
465 ; DUMP-NEXT: volatileType: 0
466 ; DUMP-NEXT: }
467 ; DUMP-NEXT: {
468 ; DUMP-NEXT: symIndexId: 22
469 ; DUMP-NEXT: symTag: UDT
470 ; DUMP-NEXT: name: Nothing
471 ; DUMP-NEXT: unmodifiedTypeId: 19
472 ; DUMP-NEXT: virtualTableShapeId: 3
473 ; DUMP-NEXT: length: 1
474 ; DUMP-NEXT: udtKind: struct
475 ; DUMP-NEXT: constructor: 0
476 ; DUMP-NEXT: constType: 0
477 ; DUMP-NEXT: hasAssignmentOperator: 0
478 ; DUMP-NEXT: hasCastOperator: 0
479 ; DUMP-NEXT: hasNestedTypes: 0
480 ; DUMP-NEXT: overloadedOperator: 0
481 ; DUMP-NEXT: isInterfaceUdt: 0
482 ; DUMP-NEXT: intrinsic: 0
483 ; DUMP-NEXT: nested: 0
484 ; DUMP-NEXT: packed: 0
485 ; DUMP-NEXT: isRefUdt: 0
486 ; DUMP-NEXT: scoped: 0
487 ; DUMP-NEXT: unalignedType: 0
488 ; DUMP-NEXT: isValueUdt: 0
489 ; DUMP-NEXT: volatileType: 1
490 ; DUMP-NEXT: }
491 ; DUMP-NEXT: {
492 ; DUMP-NEXT: symIndexId: 23
493 ; DUMP-NEXT: symTag: UDT
494 ; DUMP-NEXT: name: Nothing
495 ; DUMP-NEXT: unmodifiedTypeId: 19
496 ; DUMP-NEXT: virtualTableShapeId: 3
497 ; DUMP-NEXT: length: 1
498 ; DUMP-NEXT: udtKind: struct
499 ; DUMP-NEXT: constructor: 0
500 ; DUMP-NEXT: constType: 1
501 ; DUMP-NEXT: hasAssignmentOperator: 0
502 ; DUMP-NEXT: hasCastOperator: 0
503 ; DUMP-NEXT: hasNestedTypes: 0
504 ; DUMP-NEXT: overloadedOperator: 0
505 ; DUMP-NEXT: isInterfaceUdt: 0
506 ; DUMP-NEXT: intrinsic: 0
507 ; DUMP-NEXT: nested: 0
508 ; DUMP-NEXT: packed: 0
509 ; DUMP-NEXT: isRefUdt: 0
510 ; DUMP-NEXT: scoped: 0
511 ; DUMP-NEXT: unalignedType: 0
512 ; DUMP-NEXT: isValueUdt: 0
513 ; DUMP-NEXT: volatileType: 1
514 ; DUMP-NEXT: }
515 ; DUMP-NEXT: {
516 ; DUMP-NEXT: symIndexId: 24
517 ; DUMP-NEXT: symTag: UDT
518 ; DUMP-NEXT: name: Nothing
519 ; DUMP-NEXT: unmodifiedTypeId: 19
520 ; DUMP-NEXT: virtualTableShapeId: 3
521 ; DUMP-NEXT: length: 1
522 ; DUMP-NEXT: udtKind: struct
523 ; DUMP-NEXT: constructor: 0
524 ; DUMP-NEXT: constType: 0
525 ; DUMP-NEXT: hasAssignmentOperator: 0
526 ; DUMP-NEXT: hasCastOperator: 0
527 ; DUMP-NEXT: hasNestedTypes: 0
528 ; DUMP-NEXT: overloadedOperator: 0
529 ; DUMP-NEXT: isInterfaceUdt: 0
530 ; DUMP-NEXT: intrinsic: 0
531 ; DUMP-NEXT: nested: 0
532 ; DUMP-NEXT: packed: 0
533 ; DUMP-NEXT: isRefUdt: 0
534 ; DUMP-NEXT: scoped: 0
535 ; DUMP-NEXT: unalignedType: 1
536 ; DUMP-NEXT: isValueUdt: 0
537 ; DUMP-NEXT: volatileType: 0
538 ; DUMP-NEXT: }
985985 SymTypes.push_back(PDB_SymType::Enum);
986986 if (opts::diadump::Pointers)
987987 SymTypes.push_back(PDB_SymType::PointerType);
988 if (opts::diadump::UDTs)
989 SymTypes.push_back(PDB_SymType::UDT);
988990
989991 PdbSymbolIdField Ids = opts::diadump::NoSymIndexIds ? PdbSymbolIdField::None
990992 : PdbSymbolIdField::All;
10101012 outs() << "\n}\n";
10111013 }
10121014 }
1015 auto Child = Session->getSymbolById(3);
1016 Child->defaultDump(outs(), 2, PdbSymbolIdField::All, PdbSymbolIdField::None);
10131017 }
10141018
10151019 static void dumpPretty(StringRef Path) {