1 //===- llvm/unittest/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
11 #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
12 #include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
13 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
14 #include "llvm/Support/Allocator.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
20 using namespace llvm::codeview
;
22 class TypeIndexIteratorTest
: public testing::Test
{
24 TypeIndexIteratorTest() {}
26 void SetUp() override
{
28 TTB
= std::make_unique
<AppendingTypeTableBuilder
>(Storage
);
29 CRB
= std::make_unique
<ContinuationRecordBuilder
>();
33 void TearDown() override
{
39 template <typename
... Indices
>
40 bool checkTypeReferences(uint32_t RecordIndex
, Indices
&&... TIs
) const {
41 EXPECT_EQ(sizeof...(Indices
), countRefs(RecordIndex
));
43 // Choose between type or symbol records. The checking code doesn't care
45 std::vector
<ArrayRef
<uint8_t>> CVRecords
;
46 if (Symbols
.empty()) {
47 CVRecords
= TTB
->records();
49 for (const CVSymbol
&S
: Symbols
)
50 CVRecords
.push_back(S
.data());
53 return checkTypeReferencesImpl(RecordIndex
, CVRecords
,
54 std::forward
<Indices
>(TIs
)...);
57 template <typename
... T
> void writeFieldList(T
&&... MemberRecords
) {
58 CRB
->begin(ContinuationRecordKind::FieldList
);
59 writeFieldListImpl(std::forward
<T
>(MemberRecords
)...);
60 auto Records
= CRB
->end(TTB
->nextTypeIndex());
61 ASSERT_EQ(1u, Records
.size());
62 TTB
->insertRecordBytes(Records
.front().RecordData
);
63 discoverAllTypeIndices();
66 template <typename
... T
> void writeTypeRecords(T
&&... Records
) {
67 writeTypeRecordsImpl(std::forward
<T
>(Records
)...);
68 ASSERT_EQ(sizeof...(T
), TTB
->records().size());
69 discoverAllTypeIndices();
72 template <typename
... T
> void writeSymbolRecords(T
&&... Records
) {
73 writeSymbolRecordsImpl(std::forward
<T
>(Records
)...);
74 ASSERT_EQ(sizeof...(T
), Symbols
.size());
75 discoverTypeIndicesInSymbols();
78 std::unique_ptr
<AppendingTypeTableBuilder
> TTB
;
81 uint32_t countRefs(uint32_t RecordIndex
) const {
82 auto &R
= Refs
[RecordIndex
];
90 bool checkOneTypeReference(uint32_t RecordIndex
, ArrayRef
<uint8_t> RecordData
,
92 RecordData
= RecordData
.drop_front(sizeof(RecordPrefix
));
93 auto &RefList
= Refs
[RecordIndex
];
94 for (auto &Ref
: RefList
) {
95 uint32_t Offset
= Ref
.Offset
;
96 ArrayRef
<uint8_t> Loc
= RecordData
.drop_front(Offset
);
97 ArrayRef
<TypeIndex
> Indices(
98 reinterpret_cast<const TypeIndex
*>(Loc
.data()), Ref
.Count
);
99 if (llvm::any_of(Indices
,
100 [TI
](const TypeIndex
&Other
) { return Other
== TI
; }))
106 template <typename
... Indices
>
107 bool checkTypeReferencesImpl(uint32_t RecordIndex
,
108 ArrayRef
<ArrayRef
<uint8_t>> CVRecords
) const {
112 template <typename
... Indices
>
113 bool checkTypeReferencesImpl(uint32_t RecordIndex
,
114 ArrayRef
<ArrayRef
<uint8_t>> CVRecords
,
115 TypeIndex TI
, Indices
&&... Rest
) const {
116 ArrayRef
<uint8_t> Record
= CVRecords
[RecordIndex
];
117 bool Success
= checkOneTypeReference(RecordIndex
, Record
, TI
);
118 EXPECT_TRUE(Success
);
119 return Success
& checkTypeReferencesImpl(RecordIndex
, CVRecords
,
120 std::forward
<Indices
>(Rest
)...);
123 void discoverAllTypeIndices() {
124 Refs
.resize(TTB
->records().size());
125 for (uint32_t I
= 0; I
< TTB
->records().size(); ++I
) {
126 ArrayRef
<uint8_t> Data
= TTB
->records()[I
];
127 discoverTypeIndices(Data
, Refs
[I
]);
131 void discoverTypeIndicesInSymbols() {
132 Refs
.resize(Symbols
.size());
133 for (uint32_t I
= 0; I
< Symbols
.size(); ++I
)
134 discoverTypeIndicesInSymbol(Symbols
[I
], Refs
[I
]);
137 // Helper function to write out a field list record with the given list
138 // of member records.
139 void writeFieldListImpl() {}
141 template <typename RecType
, typename
... Rest
>
142 void writeFieldListImpl(RecType
&&Record
, Rest
&&... Records
) {
143 CRB
->writeMemberType(Record
);
144 writeFieldListImpl(std::forward
<Rest
>(Records
)...);
147 // Helper function to write out a list of type records.
148 void writeTypeRecordsImpl() {}
150 template <typename RecType
, typename
... Rest
>
151 void writeTypeRecordsImpl(RecType
&&Record
, Rest
&&... Records
) {
152 TTB
->writeLeafType(Record
);
153 writeTypeRecordsImpl(std::forward
<Rest
>(Records
)...);
156 // Helper function to write out a list of symbol records.
157 void writeSymbolRecordsImpl() {}
159 template <typename RecType
, typename
... Rest
>
160 void writeSymbolRecordsImpl(RecType
&&Record
, Rest
&&... Records
) {
161 Symbols
.push_back(SymbolSerializer::writeOneSymbol(Record
, Storage
,
162 CodeViewContainer::Pdb
));
163 writeSymbolRecordsImpl(std::forward
<Rest
>(Records
)...);
166 std::vector
<SmallVector
<TiReference
, 4>> Refs
;
167 std::unique_ptr
<ContinuationRecordBuilder
> CRB
;
168 std::vector
<CVSymbol
> Symbols
;
169 BumpPtrAllocator Storage
;
173 static FuncIdRecord
FuncId(TypeIndex(1), TypeIndex(2), "FuncId");
174 static MemberFuncIdRecord
MemFuncId(TypeIndex(3), TypeIndex(4), "FuncId");
175 static StringIdRecord
StringId(TypeIndex(5), "TheString");
177 std::vector
<TypeIndex
> Ids
= {TypeIndex(6), TypeIndex(7), TypeIndex(8)};
178 StringListRecord Record
{TypeRecordKind::StringList
, Ids
};
181 std::vector
<TypeIndex
> Ids
= {TypeIndex(9), TypeIndex(10), TypeIndex(11)};
182 BuildInfoRecord Record
{Ids
};
184 static UdtSourceLineRecord
UdtSourceLine(TypeIndex(12), TypeIndex(13), 0);
185 static UdtModSourceLineRecord
UdtModSourceLine(TypeIndex(14), TypeIndex(15), 0,
187 static ModifierRecord
Modifier(TypeIndex(16), ModifierOptions::None
);
188 static ProcedureRecord
Procedure(TypeIndex(17), CallingConvention::PpcCall
,
189 FunctionOptions::None
, 0, TypeIndex(18));
190 static MemberFunctionRecord
MemberFunction(TypeIndex(19), TypeIndex(20),
192 CallingConvention::ThisCall
,
193 FunctionOptions::None
, 2,
196 std::vector
<TypeIndex
> Ids
= {TypeIndex(23), TypeIndex(24), TypeIndex(25)};
197 ArgListRecord Record
{TypeRecordKind::ArgList
, Ids
};
199 static ArrayRecord
Array(TypeIndex(26), TypeIndex(27), 10, "MyArray");
200 static ClassRecord
Class(TypeRecordKind::Class
, 3, ClassOptions::None
,
201 TypeIndex(28), TypeIndex(29), TypeIndex(30), 10,
202 "MyClass", "MyClassUniqueName");
203 static ClassRecord
Struct(TypeRecordKind::Struct
, 3, ClassOptions::None
,
204 TypeIndex(31), TypeIndex(32), TypeIndex(33), 10,
205 "MyClass", "MyClassUniqueName");
206 static UnionRecord
Union(1, ClassOptions::None
, TypeIndex(34), 10, "MyUnion",
207 "MyUnionUniqueName");
208 static EnumRecord
Enum(1, ClassOptions::None
, TypeIndex(35), "MyEnum",
209 "EnumUniqueName", TypeIndex(36));
210 static BitFieldRecord
BitField(TypeIndex(37), 1, 0);
211 static VFTableRecord
VFTable(TypeIndex(38), TypeIndex(39), 1, "VFT", {});
212 static VFTableShapeRecord
VTableShape({});
214 const TypeIndex T1
{40};
215 const TypeIndex T2
{41};
216 const TypeIndex T3
{42};
217 const TypeIndex T4
{43};
219 std::vector
<OneMethodRecord
> Methods
{
220 {T1
, MemberAccess::Public
, MethodKind::IntroducingVirtual
,
221 MethodOptions::None
, 0, "Method1"},
222 {T2
, MemberAccess::Public
, MethodKind::PureVirtual
, MethodOptions::None
,
224 {T3
, MemberAccess::Public
, MethodKind::PureIntroducingVirtual
,
225 MethodOptions::None
, 0, "Method1"},
226 {T4
, MemberAccess::Public
, MethodKind::Static
, MethodOptions::None
, 0,
229 MethodOverloadListRecord Record
{Methods
};
230 } MethodOverloadList
;
231 static PointerRecord
Pointer(TypeIndex(44), PointerKind::Near32
,
232 PointerMode::Pointer
, PointerOptions::Const
, 3);
233 static PointerRecord
MemberPointer(
234 TypeIndex(45), PointerKind::Near32
, PointerMode::PointerToDataMember
,
235 PointerOptions::Const
, 3,
236 MemberPointerInfo(TypeIndex(46),
237 PointerToMemberRepresentation::GeneralData
));
241 static BaseClassRecord
BaseClass(MemberAccess::Public
, TypeIndex(47), 0);
242 static EnumeratorRecord
Enumerator(MemberAccess::Public
,
243 APSInt(APInt(8, 3, false)), "Test");
244 DataMemberRecord
DataMember(MemberAccess::Public
, TypeIndex(48), 0, "Test");
245 OverloadedMethodRecord
OverloadedMethod(3, TypeIndex(49), "MethodList");
247 const TypeIndex T1
{50};
248 const TypeIndex T2
{51};
249 const TypeIndex T3
{52};
250 const TypeIndex T4
{53};
251 OneMethodRecord R1
{T1
,
252 MemberAccess::Public
,
253 MethodKind::IntroducingVirtual
,
257 OneMethodRecord R2
{T2
,
258 MemberAccess::Public
,
259 MethodKind::PureVirtual
,
263 OneMethodRecord R3
{T3
,
264 MemberAccess::Public
,
265 MethodKind::PureIntroducingVirtual
,
269 OneMethodRecord R4
{T4
,
270 MemberAccess::Protected
,
272 MethodOptions::CompilerGenerated
,
276 static NestedTypeRecord
NestedType(TypeIndex(54), "MyClass");
277 static StaticDataMemberRecord
StaticDataMember(MemberAccess::Public
,
278 TypeIndex(55), "Foo");
279 static VirtualBaseClassRecord
VirtualBaseClass(TypeRecordKind::VirtualBaseClass
,
280 MemberAccess::Public
,
281 TypeIndex(56), TypeIndex(57), 0,
283 static VFPtrRecord
VFPtr(TypeIndex(58));
284 static ListContinuationRecord
Continuation(TypeIndex(59));
287 TEST_F(TypeIndexIteratorTest
, FuncId
) {
288 using namespace leafs
;
289 writeTypeRecords(FuncId
);
290 checkTypeReferences(0, FuncId
.FunctionType
, FuncId
.ParentScope
);
293 TEST_F(TypeIndexIteratorTest
, MemFuncId
) {
294 using namespace leafs
;
295 writeTypeRecords(MemFuncId
);
296 checkTypeReferences(0, MemFuncId
.ClassType
, MemFuncId
.FunctionType
);
299 TEST_F(TypeIndexIteratorTest
, StringId
) {
300 using namespace leafs
;
301 writeTypeRecords(StringId
);
302 checkTypeReferences(0, StringId
.Id
);
305 TEST_F(TypeIndexIteratorTest
, SubstrList
) {
306 using namespace leafs
;
307 writeTypeRecords(StringList
.Record
);
308 checkTypeReferences(0, StringList
.Ids
[0], StringList
.Ids
[1],
312 TEST_F(TypeIndexIteratorTest
, BuildInfo
) {
313 using namespace leafs
;
314 writeTypeRecords(BuildInfo
.Record
);
315 checkTypeReferences(0, BuildInfo
.Ids
[0], BuildInfo
.Ids
[1], BuildInfo
.Ids
[2]);
318 TEST_F(TypeIndexIteratorTest
, UdtSrcLine
) {
319 using namespace leafs
;
320 writeTypeRecords(UdtSourceLine
);
321 checkTypeReferences(0, UdtSourceLine
.UDT
, UdtSourceLine
.SourceFile
);
324 TEST_F(TypeIndexIteratorTest
, UdtModSrcLine
) {
325 using namespace leafs
;
326 writeTypeRecords(UdtModSourceLine
);
327 checkTypeReferences(0, UdtModSourceLine
.UDT
, UdtModSourceLine
.SourceFile
);
330 TEST_F(TypeIndexIteratorTest
, Modifier
) {
331 using namespace leafs
;
332 writeTypeRecords(Modifier
);
333 checkTypeReferences(0, Modifier
.ModifiedType
);
336 TEST_F(TypeIndexIteratorTest
, Procedure
) {
337 using namespace leafs
;
338 writeTypeRecords(Procedure
);
339 checkTypeReferences(0, Procedure
.ReturnType
, Procedure
.ArgumentList
);
342 TEST_F(TypeIndexIteratorTest
, MemFunc
) {
343 using namespace leafs
;
344 writeTypeRecords(MemberFunction
);
345 checkTypeReferences(0, MemberFunction
.ReturnType
, MemberFunction
.ClassType
,
346 MemberFunction
.ThisType
, MemberFunction
.ArgumentList
);
349 TEST_F(TypeIndexIteratorTest
, ArgList
) {
350 using namespace leafs
;
351 writeTypeRecords(ArgList
.Record
);
352 checkTypeReferences(0, ArgList
.Ids
[0], ArgList
.Ids
[1], ArgList
.Ids
[2]);
355 TEST_F(TypeIndexIteratorTest
, Array
) {
356 using namespace leafs
;
357 writeTypeRecords(Array
);
358 checkTypeReferences(0, Array
.ElementType
, Array
.IndexType
);
361 TEST_F(TypeIndexIteratorTest
, Class
) {
362 using namespace leafs
;
363 writeTypeRecords(Class
);
364 checkTypeReferences(0, Class
.FieldList
, Class
.DerivationList
,
368 TEST_F(TypeIndexIteratorTest
, Struct
) {
369 using namespace leafs
;
370 writeTypeRecords(Struct
);
371 checkTypeReferences(0, Struct
.FieldList
, Struct
.DerivationList
,
375 TEST_F(TypeIndexIteratorTest
, Union
) {
376 using namespace leafs
;
377 writeTypeRecords(Union
);
378 checkTypeReferences(0, Union
.FieldList
);
381 TEST_F(TypeIndexIteratorTest
, Enum
) {
382 using namespace leafs
;
383 writeTypeRecords(Enum
);
384 checkTypeReferences(0, Enum
.FieldList
, Enum
.UnderlyingType
);
387 TEST_F(TypeIndexIteratorTest
, Bitfield
) {
388 using namespace leafs
;
389 writeTypeRecords(BitField
);
390 checkTypeReferences(0, BitField
.Type
);
393 TEST_F(TypeIndexIteratorTest
, VTable
) {
394 using namespace leafs
;
395 writeTypeRecords(VFTable
);
396 checkTypeReferences(0, VFTable
.CompleteClass
, VFTable
.OverriddenVFTable
);
399 TEST_F(TypeIndexIteratorTest
, VTShape
) {
400 using namespace leafs
;
401 writeTypeRecords(VTableShape
);
402 checkTypeReferences(0);
405 TEST_F(TypeIndexIteratorTest
, OverloadList
) {
406 using namespace leafs
;
407 writeTypeRecords(MethodOverloadList
.Record
);
408 checkTypeReferences(0, MethodOverloadList
.T1
, MethodOverloadList
.T2
,
409 MethodOverloadList
.T3
, MethodOverloadList
.T4
);
412 TEST_F(TypeIndexIteratorTest
, Pointer
) {
413 using namespace leafs
;
414 writeTypeRecords(Pointer
);
415 checkTypeReferences(0, Pointer
.ReferentType
);
418 TEST_F(TypeIndexIteratorTest
, MemberPointer
) {
419 using namespace leafs
;
420 writeTypeRecords(MemberPointer
);
421 checkTypeReferences(0, MemberPointer
.ReferentType
,
422 MemberPointer
.MemberInfo
->ContainingType
);
425 TEST_F(TypeIndexIteratorTest
, ManyTypes
) {
427 using namespace leafs
;
428 writeTypeRecords(FuncId
, MemFuncId
, StringId
, StringList
.Record
,
429 BuildInfo
.Record
, UdtSourceLine
, UdtModSourceLine
, Modifier
,
430 Procedure
, MemberFunction
, ArgList
.Record
, Array
, Class
,
431 Union
, Enum
, BitField
, VFTable
, VTableShape
,
432 MethodOverloadList
.Record
, Pointer
, MemberPointer
);
434 checkTypeReferences(0, FuncId
.FunctionType
, FuncId
.ParentScope
);
435 checkTypeReferences(1, MemFuncId
.ClassType
, MemFuncId
.FunctionType
);
436 checkTypeReferences(2, StringId
.Id
);
437 checkTypeReferences(3, StringList
.Ids
[0], StringList
.Ids
[1],
439 checkTypeReferences(4, BuildInfo
.Ids
[0], BuildInfo
.Ids
[1], BuildInfo
.Ids
[2]);
440 checkTypeReferences(5, UdtSourceLine
.UDT
, UdtSourceLine
.SourceFile
);
441 checkTypeReferences(6, UdtModSourceLine
.UDT
, UdtModSourceLine
.SourceFile
);
442 checkTypeReferences(7, Modifier
.ModifiedType
);
443 checkTypeReferences(8, Procedure
.ReturnType
, Procedure
.ArgumentList
);
444 checkTypeReferences(9, MemberFunction
.ReturnType
, MemberFunction
.ClassType
,
445 MemberFunction
.ThisType
, MemberFunction
.ArgumentList
);
446 checkTypeReferences(10, ArgList
.Ids
[0], ArgList
.Ids
[1], ArgList
.Ids
[2]);
447 checkTypeReferences(11, Array
.ElementType
, Array
.IndexType
);
448 checkTypeReferences(12, Class
.FieldList
, Class
.DerivationList
,
450 checkTypeReferences(13, Union
.FieldList
);
451 checkTypeReferences(14, Enum
.FieldList
, Enum
.UnderlyingType
);
452 checkTypeReferences(15, BitField
.Type
);
453 checkTypeReferences(16, VFTable
.CompleteClass
, VFTable
.OverriddenVFTable
);
454 checkTypeReferences(17);
455 checkTypeReferences(18, MethodOverloadList
.T1
, MethodOverloadList
.T2
,
456 MethodOverloadList
.T3
, MethodOverloadList
.T4
);
457 checkTypeReferences(19, Pointer
.ReferentType
);
458 checkTypeReferences(20, MemberPointer
.ReferentType
,
459 MemberPointer
.MemberInfo
->ContainingType
);
462 TEST_F(TypeIndexIteratorTest
, FieldListBaseClass
) {
463 using namespace members
;
464 writeFieldList(BaseClass
);
465 checkTypeReferences(0, BaseClass
.Type
);
468 TEST_F(TypeIndexIteratorTest
, FieldListEnumerator
) {
469 using namespace members
;
470 writeFieldList(Enumerator
);
471 checkTypeReferences(0);
474 TEST_F(TypeIndexIteratorTest
, FieldListMember
) {
475 using namespace members
;
476 writeFieldList(DataMember
);
477 checkTypeReferences(0, DataMember
.Type
);
480 TEST_F(TypeIndexIteratorTest
, FieldListMethod
) {
481 using namespace members
;
482 writeFieldList(OverloadedMethod
);
483 checkTypeReferences(0, OverloadedMethod
.MethodList
);
486 TEST_F(TypeIndexIteratorTest
, FieldListOneMethod
) {
487 using namespace members
;
488 writeFieldList(OneMethod
.R1
, OneMethod
.R2
, OneMethod
.R3
, OneMethod
.R4
);
489 checkTypeReferences(0, OneMethod
.T1
, OneMethod
.T2
, OneMethod
.T3
,
493 TEST_F(TypeIndexIteratorTest
, FieldListNestedType
) {
494 using namespace members
;
495 writeFieldList(NestedType
);
496 checkTypeReferences(0, NestedType
.Type
);
499 TEST_F(TypeIndexIteratorTest
, FieldListStaticMember
) {
500 using namespace members
;
501 writeFieldList(StaticDataMember
);
502 checkTypeReferences(0, StaticDataMember
.Type
);
505 TEST_F(TypeIndexIteratorTest
, FieldListVirtualBase
) {
506 using namespace members
;
507 writeFieldList(VirtualBaseClass
);
508 checkTypeReferences(0, VirtualBaseClass
.BaseType
, VirtualBaseClass
.VBPtrType
);
511 TEST_F(TypeIndexIteratorTest
, FieldListVFTable
) {
512 using namespace members
;
513 writeFieldList(VFPtr
);
514 checkTypeReferences(0, VFPtr
.Type
);
517 TEST_F(TypeIndexIteratorTest
, FieldListContinuation
) {
518 using namespace members
;
519 writeFieldList(Continuation
);
520 checkTypeReferences(0, Continuation
.ContinuationIndex
);
523 TEST_F(TypeIndexIteratorTest
, ManyMembers
) {
524 using namespace members
;
525 writeFieldList(BaseClass
, Enumerator
, DataMember
, OverloadedMethod
,
526 OneMethod
.R1
, OneMethod
.R2
, OneMethod
.R3
, OneMethod
.R4
,
527 NestedType
, StaticDataMember
, VirtualBaseClass
, VFPtr
,
531 0, BaseClass
.Type
, DataMember
.Type
, OverloadedMethod
.MethodList
,
532 OneMethod
.T1
, OneMethod
.T2
, OneMethod
.T3
, OneMethod
.T4
, NestedType
.Type
,
533 StaticDataMember
.Type
, VirtualBaseClass
.BaseType
,
534 VirtualBaseClass
.VBPtrType
, VFPtr
.Type
, Continuation
.ContinuationIndex
);
537 TEST_F(TypeIndexIteratorTest
, ProcSym
) {
538 ProcSym
GS(SymbolRecordKind::GlobalProcSym
);
539 GS
.FunctionType
= TypeIndex::Float32();
540 ProcSym
LS(SymbolRecordKind::ProcSym
);
541 LS
.FunctionType
= TypeIndex::Float64();
542 writeSymbolRecords(GS
, LS
);
543 checkTypeReferences(0, GS
.FunctionType
);
544 checkTypeReferences(1, LS
.FunctionType
);
547 TEST_F(TypeIndexIteratorTest
, DataSym
) {
548 DataSym
DS(SymbolRecordKind::GlobalData
);
549 DS
.Type
= TypeIndex::Float32();
550 writeSymbolRecords(DS
);
551 checkTypeReferences(0, DS
.Type
);
554 TEST_F(TypeIndexIteratorTest
, RegisterSym
) {
555 RegisterSym
Reg(SymbolRecordKind::RegisterSym
);
556 Reg
.Index
= TypeIndex::UInt32();
557 Reg
.Register
= RegisterId::EAX
;
559 writeSymbolRecords(Reg
);
560 checkTypeReferences(0, Reg
.Index
);
563 TEST_F(TypeIndexIteratorTest
, CallerSym
) {
564 CallerSym
Callees(SymbolRecordKind::CalleeSym
);
565 Callees
.Indices
.push_back(TypeIndex(1));
566 Callees
.Indices
.push_back(TypeIndex(2));
567 Callees
.Indices
.push_back(TypeIndex(3));
568 CallerSym
Callers(SymbolRecordKind::CallerSym
);
569 Callers
.Indices
.push_back(TypeIndex(4));
570 Callers
.Indices
.push_back(TypeIndex(5));
571 Callers
.Indices
.push_back(TypeIndex(6));
572 CallerSym
Inlinees(SymbolRecordKind::InlineesSym
);
573 Inlinees
.Indices
.push_back(TypeIndex(7));
574 Inlinees
.Indices
.push_back(TypeIndex(8));
575 Inlinees
.Indices
.push_back(TypeIndex(9));
576 writeSymbolRecords(Callees
, Callers
, Inlinees
);
577 checkTypeReferences(0, TypeIndex(1), TypeIndex(2), TypeIndex(3));
578 checkTypeReferences(1, TypeIndex(4), TypeIndex(5), TypeIndex(6));
579 checkTypeReferences(2, TypeIndex(7), TypeIndex(8), TypeIndex(9));
582 TEST_F(TypeIndexIteratorTest
, Precomp
) {
583 PrecompRecord
P(TypeRecordKind::Precomp
);
584 P
.StartTypeIndex
= TypeIndex::FirstNonSimpleIndex
;
586 P
.Signature
= 0x12345678;
587 P
.PrecompFilePath
= "C:/precomp.obj";
589 EndPrecompRecord
EP(TypeRecordKind::EndPrecomp
);
590 EP
.Signature
= P
.Signature
;
592 writeTypeRecords(P
, EP
);
593 checkTypeReferences(0);
596 // This is a test for getEncodedIntegerLength()
597 TEST_F(TypeIndexIteratorTest
, VariableSizeIntegers
) {
598 BaseClassRecord
BaseClass1(MemberAccess::Public
, TypeIndex(47), (uint64_t)-1);
599 BaseClassRecord
BaseClass2(MemberAccess::Public
, TypeIndex(48), 1);
600 writeFieldList(BaseClass1
, BaseClass2
);
601 checkTypeReferences(0, TypeIndex(47), TypeIndex(48));
604 TEST_F(TypeIndexIteratorTest
, UsingNamespace
) {
605 UsingNamespaceSym
UN(SymbolRecordKind::UsingNamespaceSym
);
607 writeSymbolRecords(UN
);
608 checkTypeReferences(0);