1 //===- llvm/unittest/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
12 #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
13 #include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
14 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
15 #include "llvm/Support/Allocator.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
21 using namespace llvm::codeview
;
23 class TypeIndexIteratorTest
: public testing::Test
{
25 TypeIndexIteratorTest() {}
27 void SetUp() override
{
29 TTB
= make_unique
<AppendingTypeTableBuilder
>(Storage
);
30 CRB
= make_unique
<ContinuationRecordBuilder
>();
34 void TearDown() override
{
40 template <typename
... Indices
>
41 bool checkTypeReferences(uint32_t RecordIndex
, Indices
&&... TIs
) const {
42 EXPECT_EQ(sizeof...(Indices
), countRefs(RecordIndex
));
44 // Choose between type or symbol records. The checking code doesn't care
46 std::vector
<ArrayRef
<uint8_t>> CVRecords
;
47 if (Symbols
.empty()) {
48 CVRecords
= TTB
->records();
50 for (const CVSymbol
&S
: Symbols
)
51 CVRecords
.push_back(S
.data());
54 return checkTypeReferencesImpl(RecordIndex
, CVRecords
,
55 std::forward
<Indices
>(TIs
)...);
58 template <typename
... T
> void writeFieldList(T
&&... MemberRecords
) {
59 CRB
->begin(ContinuationRecordKind::FieldList
);
60 writeFieldListImpl(std::forward
<T
>(MemberRecords
)...);
61 auto Records
= CRB
->end(TTB
->nextTypeIndex());
62 ASSERT_EQ(1u, Records
.size());
63 TTB
->insertRecordBytes(Records
.front().RecordData
);
64 discoverAllTypeIndices();
67 template <typename
... T
> void writeTypeRecords(T
&&... Records
) {
68 writeTypeRecordsImpl(std::forward
<T
>(Records
)...);
69 ASSERT_EQ(sizeof...(T
), TTB
->records().size());
70 discoverAllTypeIndices();
73 template <typename
... T
> void writeSymbolRecords(T
&&... Records
) {
74 writeSymbolRecordsImpl(std::forward
<T
>(Records
)...);
75 ASSERT_EQ(sizeof...(T
), Symbols
.size());
76 discoverTypeIndicesInSymbols();
79 std::unique_ptr
<AppendingTypeTableBuilder
> TTB
;
82 uint32_t countRefs(uint32_t RecordIndex
) const {
83 auto &R
= Refs
[RecordIndex
];
91 bool checkOneTypeReference(uint32_t RecordIndex
, ArrayRef
<uint8_t> RecordData
,
93 RecordData
= RecordData
.drop_front(sizeof(RecordPrefix
));
94 auto &RefList
= Refs
[RecordIndex
];
95 for (auto &Ref
: RefList
) {
96 uint32_t Offset
= Ref
.Offset
;
97 ArrayRef
<uint8_t> Loc
= RecordData
.drop_front(Offset
);
98 ArrayRef
<TypeIndex
> Indices(
99 reinterpret_cast<const TypeIndex
*>(Loc
.data()), Ref
.Count
);
100 if (llvm::any_of(Indices
,
101 [TI
](const TypeIndex
&Other
) { return Other
== TI
; }))
107 template <typename
... Indices
>
108 bool checkTypeReferencesImpl(uint32_t RecordIndex
,
109 ArrayRef
<ArrayRef
<uint8_t>> CVRecords
) const {
113 template <typename
... Indices
>
114 bool checkTypeReferencesImpl(uint32_t RecordIndex
,
115 ArrayRef
<ArrayRef
<uint8_t>> CVRecords
,
116 TypeIndex TI
, Indices
&&... Rest
) const {
117 ArrayRef
<uint8_t> Record
= CVRecords
[RecordIndex
];
118 bool Success
= checkOneTypeReference(RecordIndex
, Record
, TI
);
119 EXPECT_TRUE(Success
);
120 return Success
& checkTypeReferencesImpl(RecordIndex
, CVRecords
,
121 std::forward
<Indices
>(Rest
)...);
124 void discoverAllTypeIndices() {
125 Refs
.resize(TTB
->records().size());
126 for (uint32_t I
= 0; I
< TTB
->records().size(); ++I
) {
127 ArrayRef
<uint8_t> Data
= TTB
->records()[I
];
128 discoverTypeIndices(Data
, Refs
[I
]);
132 void discoverTypeIndicesInSymbols() {
133 Refs
.resize(Symbols
.size());
134 for (uint32_t I
= 0; I
< Symbols
.size(); ++I
)
135 discoverTypeIndicesInSymbol(Symbols
[I
], Refs
[I
]);
138 // Helper function to write out a field list record with the given list
139 // of member records.
140 void writeFieldListImpl() {}
142 template <typename RecType
, typename
... Rest
>
143 void writeFieldListImpl(RecType
&&Record
, Rest
&&... Records
) {
144 CRB
->writeMemberType(Record
);
145 writeFieldListImpl(std::forward
<Rest
>(Records
)...);
148 // Helper function to write out a list of type records.
149 void writeTypeRecordsImpl() {}
151 template <typename RecType
, typename
... Rest
>
152 void writeTypeRecordsImpl(RecType
&&Record
, Rest
&&... Records
) {
153 TTB
->writeLeafType(Record
);
154 writeTypeRecordsImpl(std::forward
<Rest
>(Records
)...);
157 // Helper function to write out a list of symbol records.
158 void writeSymbolRecordsImpl() {}
160 template <typename RecType
, typename
... Rest
>
161 void writeSymbolRecordsImpl(RecType
&&Record
, Rest
&&... Records
) {
162 Symbols
.push_back(SymbolSerializer::writeOneSymbol(Record
, Storage
,
163 CodeViewContainer::Pdb
));
164 writeSymbolRecordsImpl(std::forward
<Rest
>(Records
)...);
167 std::vector
<SmallVector
<TiReference
, 4>> Refs
;
168 std::unique_ptr
<ContinuationRecordBuilder
> CRB
;
169 std::vector
<CVSymbol
> Symbols
;
170 BumpPtrAllocator Storage
;
174 static FuncIdRecord
FuncId(TypeIndex(1), TypeIndex(2), "FuncId");
175 static MemberFuncIdRecord
MemFuncId(TypeIndex(3), TypeIndex(4), "FuncId");
176 static StringIdRecord
StringId(TypeIndex(5), "TheString");
178 std::vector
<TypeIndex
> Ids
= {TypeIndex(6), TypeIndex(7), TypeIndex(8)};
179 StringListRecord Record
{TypeRecordKind::StringList
, Ids
};
182 std::vector
<TypeIndex
> Ids
= {TypeIndex(9), TypeIndex(10), TypeIndex(11)};
183 BuildInfoRecord Record
{Ids
};
185 static UdtSourceLineRecord
UdtSourceLine(TypeIndex(12), TypeIndex(13), 0);
186 static UdtModSourceLineRecord
UdtModSourceLine(TypeIndex(14), TypeIndex(15), 0,
188 static ModifierRecord
Modifier(TypeIndex(16), ModifierOptions::None
);
189 static ProcedureRecord
Procedure(TypeIndex(17), CallingConvention::PpcCall
,
190 FunctionOptions::None
, 0, TypeIndex(18));
191 static MemberFunctionRecord
MemberFunction(TypeIndex(19), TypeIndex(20),
193 CallingConvention::ThisCall
,
194 FunctionOptions::None
, 2,
197 std::vector
<TypeIndex
> Ids
= {TypeIndex(23), TypeIndex(24), TypeIndex(25)};
198 ArgListRecord Record
{TypeRecordKind::ArgList
, Ids
};
200 static ArrayRecord
Array(TypeIndex(26), TypeIndex(27), 10, "MyArray");
201 static ClassRecord
Class(TypeRecordKind::Class
, 3, ClassOptions::None
,
202 TypeIndex(28), TypeIndex(29), TypeIndex(30), 10,
203 "MyClass", "MyClassUniqueName");
204 static ClassRecord
Struct(TypeRecordKind::Struct
, 3, ClassOptions::None
,
205 TypeIndex(31), TypeIndex(32), TypeIndex(33), 10,
206 "MyClass", "MyClassUniqueName");
207 static UnionRecord
Union(1, ClassOptions::None
, TypeIndex(34), 10, "MyUnion",
208 "MyUnionUniqueName");
209 static EnumRecord
Enum(1, ClassOptions::None
, TypeIndex(35), "MyEnum",
210 "EnumUniqueName", TypeIndex(36));
211 static BitFieldRecord
BitField(TypeIndex(37), 1, 0);
212 static VFTableRecord
VFTable(TypeIndex(38), TypeIndex(39), 1, "VFT", {});
213 static VFTableShapeRecord
VTableShape({});
215 const TypeIndex T1
{40};
216 const TypeIndex T2
{41};
217 const TypeIndex T3
{42};
218 const TypeIndex T4
{43};
220 std::vector
<OneMethodRecord
> Methods
{
221 {T1
, MemberAccess::Public
, MethodKind::IntroducingVirtual
,
222 MethodOptions::None
, 0, "Method1"},
223 {T2
, MemberAccess::Public
, MethodKind::PureVirtual
, MethodOptions::None
,
225 {T3
, MemberAccess::Public
, MethodKind::PureIntroducingVirtual
,
226 MethodOptions::None
, 0, "Method1"},
227 {T4
, MemberAccess::Public
, MethodKind::Static
, MethodOptions::None
, 0,
230 MethodOverloadListRecord Record
{Methods
};
231 } MethodOverloadList
;
232 static PointerRecord
Pointer(TypeIndex(44), PointerKind::Near32
,
233 PointerMode::Pointer
, PointerOptions::Const
, 3);
234 static PointerRecord
MemberPointer(
235 TypeIndex(45), PointerKind::Near32
, PointerMode::PointerToDataMember
,
236 PointerOptions::Const
, 3,
237 MemberPointerInfo(TypeIndex(46),
238 PointerToMemberRepresentation::GeneralData
));
242 static BaseClassRecord
BaseClass(MemberAccess::Public
, TypeIndex(47), 0);
243 static EnumeratorRecord
Enumerator(MemberAccess::Public
,
244 APSInt(APInt(8, 3, false)), "Test");
245 DataMemberRecord
DataMember(MemberAccess::Public
, TypeIndex(48), 0, "Test");
246 OverloadedMethodRecord
OverloadedMethod(3, TypeIndex(49), "MethodList");
248 const TypeIndex T1
{50};
249 const TypeIndex T2
{51};
250 const TypeIndex T3
{52};
251 const TypeIndex T4
{53};
252 OneMethodRecord R1
{T1
,
253 MemberAccess::Public
,
254 MethodKind::IntroducingVirtual
,
258 OneMethodRecord R2
{T2
,
259 MemberAccess::Public
,
260 MethodKind::PureVirtual
,
264 OneMethodRecord R3
{T3
,
265 MemberAccess::Public
,
266 MethodKind::PureIntroducingVirtual
,
270 OneMethodRecord R4
{T4
,
271 MemberAccess::Protected
,
273 MethodOptions::CompilerGenerated
,
277 static NestedTypeRecord
NestedType(TypeIndex(54), "MyClass");
278 static StaticDataMemberRecord
StaticDataMember(MemberAccess::Public
,
279 TypeIndex(55), "Foo");
280 static VirtualBaseClassRecord
VirtualBaseClass(TypeRecordKind::VirtualBaseClass
,
281 MemberAccess::Public
,
282 TypeIndex(56), TypeIndex(57), 0,
284 static VFPtrRecord
VFPtr(TypeIndex(58));
285 static ListContinuationRecord
Continuation(TypeIndex(59));
288 TEST_F(TypeIndexIteratorTest
, FuncId
) {
289 using namespace leafs
;
290 writeTypeRecords(FuncId
);
291 checkTypeReferences(0, FuncId
.FunctionType
, FuncId
.ParentScope
);
294 TEST_F(TypeIndexIteratorTest
, MemFuncId
) {
295 using namespace leafs
;
296 writeTypeRecords(MemFuncId
);
297 checkTypeReferences(0, MemFuncId
.ClassType
, MemFuncId
.FunctionType
);
300 TEST_F(TypeIndexIteratorTest
, StringId
) {
301 using namespace leafs
;
302 writeTypeRecords(StringId
);
303 checkTypeReferences(0, StringId
.Id
);
306 TEST_F(TypeIndexIteratorTest
, SubstrList
) {
307 using namespace leafs
;
308 writeTypeRecords(StringList
.Record
);
309 checkTypeReferences(0, StringList
.Ids
[0], StringList
.Ids
[1],
313 TEST_F(TypeIndexIteratorTest
, BuildInfo
) {
314 using namespace leafs
;
315 writeTypeRecords(BuildInfo
.Record
);
316 checkTypeReferences(0, BuildInfo
.Ids
[0], BuildInfo
.Ids
[1], BuildInfo
.Ids
[2]);
319 TEST_F(TypeIndexIteratorTest
, UdtSrcLine
) {
320 using namespace leafs
;
321 writeTypeRecords(UdtSourceLine
);
322 checkTypeReferences(0, UdtSourceLine
.UDT
, UdtSourceLine
.SourceFile
);
325 TEST_F(TypeIndexIteratorTest
, UdtModSrcLine
) {
326 using namespace leafs
;
327 writeTypeRecords(UdtModSourceLine
);
328 checkTypeReferences(0, UdtModSourceLine
.UDT
, UdtModSourceLine
.SourceFile
);
331 TEST_F(TypeIndexIteratorTest
, Modifier
) {
332 using namespace leafs
;
333 writeTypeRecords(Modifier
);
334 checkTypeReferences(0, Modifier
.ModifiedType
);
337 TEST_F(TypeIndexIteratorTest
, Procedure
) {
338 using namespace leafs
;
339 writeTypeRecords(Procedure
);
340 checkTypeReferences(0, Procedure
.ReturnType
, Procedure
.ArgumentList
);
343 TEST_F(TypeIndexIteratorTest
, MemFunc
) {
344 using namespace leafs
;
345 writeTypeRecords(MemberFunction
);
346 checkTypeReferences(0, MemberFunction
.ReturnType
, MemberFunction
.ClassType
,
347 MemberFunction
.ThisType
, MemberFunction
.ArgumentList
);
350 TEST_F(TypeIndexIteratorTest
, ArgList
) {
351 using namespace leafs
;
352 writeTypeRecords(ArgList
.Record
);
353 checkTypeReferences(0, ArgList
.Ids
[0], ArgList
.Ids
[1], ArgList
.Ids
[2]);
356 TEST_F(TypeIndexIteratorTest
, Array
) {
357 using namespace leafs
;
358 writeTypeRecords(Array
);
359 checkTypeReferences(0, Array
.ElementType
, Array
.IndexType
);
362 TEST_F(TypeIndexIteratorTest
, Class
) {
363 using namespace leafs
;
364 writeTypeRecords(Class
);
365 checkTypeReferences(0, Class
.FieldList
, Class
.DerivationList
,
369 TEST_F(TypeIndexIteratorTest
, Struct
) {
370 using namespace leafs
;
371 writeTypeRecords(Struct
);
372 checkTypeReferences(0, Struct
.FieldList
, Struct
.DerivationList
,
376 TEST_F(TypeIndexIteratorTest
, Union
) {
377 using namespace leafs
;
378 writeTypeRecords(Union
);
379 checkTypeReferences(0, Union
.FieldList
);
382 TEST_F(TypeIndexIteratorTest
, Enum
) {
383 using namespace leafs
;
384 writeTypeRecords(Enum
);
385 checkTypeReferences(0, Enum
.FieldList
, Enum
.UnderlyingType
);
388 TEST_F(TypeIndexIteratorTest
, Bitfield
) {
389 using namespace leafs
;
390 writeTypeRecords(BitField
);
391 checkTypeReferences(0, BitField
.Type
);
394 TEST_F(TypeIndexIteratorTest
, VTable
) {
395 using namespace leafs
;
396 writeTypeRecords(VFTable
);
397 checkTypeReferences(0, VFTable
.CompleteClass
, VFTable
.OverriddenVFTable
);
400 TEST_F(TypeIndexIteratorTest
, VTShape
) {
401 using namespace leafs
;
402 writeTypeRecords(VTableShape
);
403 checkTypeReferences(0);
406 TEST_F(TypeIndexIteratorTest
, OverloadList
) {
407 using namespace leafs
;
408 writeTypeRecords(MethodOverloadList
.Record
);
409 checkTypeReferences(0, MethodOverloadList
.T1
, MethodOverloadList
.T2
,
410 MethodOverloadList
.T3
, MethodOverloadList
.T4
);
413 TEST_F(TypeIndexIteratorTest
, Pointer
) {
414 using namespace leafs
;
415 writeTypeRecords(Pointer
);
416 checkTypeReferences(0, Pointer
.ReferentType
);
419 TEST_F(TypeIndexIteratorTest
, MemberPointer
) {
420 using namespace leafs
;
421 writeTypeRecords(MemberPointer
);
422 checkTypeReferences(0, MemberPointer
.ReferentType
,
423 MemberPointer
.MemberInfo
->ContainingType
);
426 TEST_F(TypeIndexIteratorTest
, ManyTypes
) {
428 using namespace leafs
;
429 writeTypeRecords(FuncId
, MemFuncId
, StringId
, StringList
.Record
,
430 BuildInfo
.Record
, UdtSourceLine
, UdtModSourceLine
, Modifier
,
431 Procedure
, MemberFunction
, ArgList
.Record
, Array
, Class
,
432 Union
, Enum
, BitField
, VFTable
, VTableShape
,
433 MethodOverloadList
.Record
, Pointer
, MemberPointer
);
435 checkTypeReferences(0, FuncId
.FunctionType
, FuncId
.ParentScope
);
436 checkTypeReferences(1, MemFuncId
.ClassType
, MemFuncId
.FunctionType
);
437 checkTypeReferences(2, StringId
.Id
);
438 checkTypeReferences(3, StringList
.Ids
[0], StringList
.Ids
[1],
440 checkTypeReferences(4, BuildInfo
.Ids
[0], BuildInfo
.Ids
[1], BuildInfo
.Ids
[2]);
441 checkTypeReferences(5, UdtSourceLine
.UDT
, UdtSourceLine
.SourceFile
);
442 checkTypeReferences(6, UdtModSourceLine
.UDT
, UdtModSourceLine
.SourceFile
);
443 checkTypeReferences(7, Modifier
.ModifiedType
);
444 checkTypeReferences(8, Procedure
.ReturnType
, Procedure
.ArgumentList
);
445 checkTypeReferences(9, MemberFunction
.ReturnType
, MemberFunction
.ClassType
,
446 MemberFunction
.ThisType
, MemberFunction
.ArgumentList
);
447 checkTypeReferences(10, ArgList
.Ids
[0], ArgList
.Ids
[1], ArgList
.Ids
[2]);
448 checkTypeReferences(11, Array
.ElementType
, Array
.IndexType
);
449 checkTypeReferences(12, Class
.FieldList
, Class
.DerivationList
,
451 checkTypeReferences(13, Union
.FieldList
);
452 checkTypeReferences(14, Enum
.FieldList
, Enum
.UnderlyingType
);
453 checkTypeReferences(15, BitField
.Type
);
454 checkTypeReferences(16, VFTable
.CompleteClass
, VFTable
.OverriddenVFTable
);
455 checkTypeReferences(17);
456 checkTypeReferences(18, MethodOverloadList
.T1
, MethodOverloadList
.T2
,
457 MethodOverloadList
.T3
, MethodOverloadList
.T4
);
458 checkTypeReferences(19, Pointer
.ReferentType
);
459 checkTypeReferences(20, MemberPointer
.ReferentType
,
460 MemberPointer
.MemberInfo
->ContainingType
);
463 TEST_F(TypeIndexIteratorTest
, FieldListBaseClass
) {
464 using namespace members
;
465 writeFieldList(BaseClass
);
466 checkTypeReferences(0, BaseClass
.Type
);
469 TEST_F(TypeIndexIteratorTest
, FieldListEnumerator
) {
470 using namespace members
;
471 writeFieldList(Enumerator
);
472 checkTypeReferences(0);
475 TEST_F(TypeIndexIteratorTest
, FieldListMember
) {
476 using namespace members
;
477 writeFieldList(DataMember
);
478 checkTypeReferences(0, DataMember
.Type
);
481 TEST_F(TypeIndexIteratorTest
, FieldListMethod
) {
482 using namespace members
;
483 writeFieldList(OverloadedMethod
);
484 checkTypeReferences(0, OverloadedMethod
.MethodList
);
487 TEST_F(TypeIndexIteratorTest
, FieldListOneMethod
) {
488 using namespace members
;
489 writeFieldList(OneMethod
.R1
, OneMethod
.R2
, OneMethod
.R3
, OneMethod
.R4
);
490 checkTypeReferences(0, OneMethod
.T1
, OneMethod
.T2
, OneMethod
.T3
,
494 TEST_F(TypeIndexIteratorTest
, FieldListNestedType
) {
495 using namespace members
;
496 writeFieldList(NestedType
);
497 checkTypeReferences(0, NestedType
.Type
);
500 TEST_F(TypeIndexIteratorTest
, FieldListStaticMember
) {
501 using namespace members
;
502 writeFieldList(StaticDataMember
);
503 checkTypeReferences(0, StaticDataMember
.Type
);
506 TEST_F(TypeIndexIteratorTest
, FieldListVirtualBase
) {
507 using namespace members
;
508 writeFieldList(VirtualBaseClass
);
509 checkTypeReferences(0, VirtualBaseClass
.BaseType
, VirtualBaseClass
.VBPtrType
);
512 TEST_F(TypeIndexIteratorTest
, FieldListVFTable
) {
513 using namespace members
;
514 writeFieldList(VFPtr
);
515 checkTypeReferences(0, VFPtr
.Type
);
518 TEST_F(TypeIndexIteratorTest
, FieldListContinuation
) {
519 using namespace members
;
520 writeFieldList(Continuation
);
521 checkTypeReferences(0, Continuation
.ContinuationIndex
);
524 TEST_F(TypeIndexIteratorTest
, ManyMembers
) {
525 using namespace members
;
526 writeFieldList(BaseClass
, Enumerator
, DataMember
, OverloadedMethod
,
527 OneMethod
.R1
, OneMethod
.R2
, OneMethod
.R3
, OneMethod
.R4
,
528 NestedType
, StaticDataMember
, VirtualBaseClass
, VFPtr
,
532 0, BaseClass
.Type
, DataMember
.Type
, OverloadedMethod
.MethodList
,
533 OneMethod
.T1
, OneMethod
.T2
, OneMethod
.T3
, OneMethod
.T4
, NestedType
.Type
,
534 StaticDataMember
.Type
, VirtualBaseClass
.BaseType
,
535 VirtualBaseClass
.VBPtrType
, VFPtr
.Type
, Continuation
.ContinuationIndex
);
538 TEST_F(TypeIndexIteratorTest
, ProcSym
) {
539 ProcSym
GS(SymbolRecordKind::GlobalProcSym
);
540 GS
.FunctionType
= TypeIndex::Float32();
541 ProcSym
LS(SymbolRecordKind::ProcSym
);
542 LS
.FunctionType
= TypeIndex::Float64();
543 writeSymbolRecords(GS
, LS
);
544 checkTypeReferences(0, GS
.FunctionType
);
545 checkTypeReferences(1, LS
.FunctionType
);
548 TEST_F(TypeIndexIteratorTest
, DataSym
) {
549 DataSym
DS(SymbolRecordKind::GlobalData
);
550 DS
.Type
= TypeIndex::Float32();
551 writeSymbolRecords(DS
);
552 checkTypeReferences(0, DS
.Type
);
555 TEST_F(TypeIndexIteratorTest
, RegisterSym
) {
556 RegisterSym
Reg(SymbolRecordKind::RegisterSym
);
557 Reg
.Index
= TypeIndex::UInt32();
558 Reg
.Register
= RegisterId::EAX
;
560 writeSymbolRecords(Reg
);
561 checkTypeReferences(0, Reg
.Index
);
564 TEST_F(TypeIndexIteratorTest
, CallerSym
) {
565 CallerSym
Callees(SymbolRecordKind::CalleeSym
);
566 Callees
.Indices
.push_back(TypeIndex(1));
567 Callees
.Indices
.push_back(TypeIndex(2));
568 Callees
.Indices
.push_back(TypeIndex(3));
569 CallerSym
Callers(SymbolRecordKind::CallerSym
);
570 Callers
.Indices
.push_back(TypeIndex(4));
571 Callers
.Indices
.push_back(TypeIndex(5));
572 Callers
.Indices
.push_back(TypeIndex(6));
573 CallerSym
Inlinees(SymbolRecordKind::InlineesSym
);
574 Inlinees
.Indices
.push_back(TypeIndex(7));
575 Inlinees
.Indices
.push_back(TypeIndex(8));
576 Inlinees
.Indices
.push_back(TypeIndex(9));
577 writeSymbolRecords(Callees
, Callers
, Inlinees
);
578 checkTypeReferences(0, TypeIndex(1), TypeIndex(2), TypeIndex(3));
579 checkTypeReferences(1, TypeIndex(4), TypeIndex(5), TypeIndex(6));
580 checkTypeReferences(2, TypeIndex(7), TypeIndex(8), TypeIndex(9));
583 TEST_F(TypeIndexIteratorTest
, Precomp
) {
584 PrecompRecord
P(TypeRecordKind::Precomp
);
585 P
.StartTypeIndex
= TypeIndex::FirstNonSimpleIndex
;
587 P
.Signature
= 0x12345678;
588 P
.PrecompFilePath
= "C:/precomp.obj";
590 EndPrecompRecord
EP(TypeRecordKind::EndPrecomp
);
591 EP
.Signature
= P
.Signature
;
593 writeTypeRecords(P
, EP
);
594 checkTypeReferences(0);
597 // This is a test for getEncodedIntegerLength()
598 TEST_F(TypeIndexIteratorTest
, VariableSizeIntegers
) {
599 BaseClassRecord
BaseClass1(MemberAccess::Public
, TypeIndex(47), (uint64_t)-1);
600 BaseClassRecord
BaseClass2(MemberAccess::Public
, TypeIndex(48), 1);
601 writeFieldList(BaseClass1
, BaseClass2
);
602 checkTypeReferences(0, TypeIndex(47), TypeIndex(48));
605 TEST_F(TypeIndexIteratorTest
, UsingNamespace
) {
606 UsingNamespaceSym
UN(SymbolRecordKind::UsingNamespaceSym
);
608 writeSymbolRecords(UN
);
609 checkTypeReferences(0);