diff options
| author | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2018-04-10 00:09:15 +0000 |
|---|---|---|
| committer | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2018-04-10 00:09:15 +0000 |
| commit | 3241cec5779f96fa48455b9a25000550499b01d4 (patch) | |
| tree | 324ea62dff707cafa924299e7d48144b7791bff9 /llvm/unittests/DebugInfo | |
| parent | dfa932b04942d2b53342ecddd9e1f6def9643a74 (diff) | |
| download | bcm5719-llvm-3241cec5779f96fa48455b9a25000550499b01d4.tar.gz bcm5719-llvm-3241cec5779f96fa48455b9a25000550499b01d4.zip | |
Fix line endings (CR/LF -> LF) introduced by rL329613
reviewer: zturner
llvm-svn: 329646
Diffstat (limited to 'llvm/unittests/DebugInfo')
| -rw-r--r-- | llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp | 1190 |
1 files changed, 595 insertions, 595 deletions
diff --git a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp index 64ee3e213db..14d358dd152 100644 --- a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp +++ b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp @@ -1,595 +1,595 @@ -//===- llvm/unittest/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
-
-#include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
-#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
-#include "llvm/Support/Allocator.h"
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-class TypeIndexIteratorTest : public testing::Test {
-public:
- TypeIndexIteratorTest() {}
-
- void SetUp() override {
- Refs.clear();
- TTB = make_unique<AppendingTypeTableBuilder>(Storage);
- CRB = make_unique<ContinuationRecordBuilder>();
- Symbols.clear();
- }
-
- void TearDown() override {
- CRB.reset();
- TTB.reset();
- }
-
-protected:
- template <typename... Indices>
- bool checkTypeReferences(uint32_t RecordIndex, Indices &&... TIs) const {
- EXPECT_EQ(sizeof...(Indices), countRefs(RecordIndex));
-
- // Choose between type or symbol records. The checking code doesn't care
- // which we have.
- std::vector<ArrayRef<uint8_t>> CVRecords;
- if (Symbols.empty()) {
- CVRecords = TTB->records();
- } else {
- for (const CVSymbol &S : Symbols)
- CVRecords.push_back(S.data());
- }
-
- return checkTypeReferencesImpl(RecordIndex, CVRecords,
- std::forward<Indices>(TIs)...);
- }
-
- template <typename... T> void writeFieldList(T &&... MemberRecords) {
- CRB->begin(ContinuationRecordKind::FieldList);
- writeFieldListImpl(std::forward<T>(MemberRecords)...);
- auto Records = CRB->end(TTB->nextTypeIndex());
- ASSERT_EQ(1u, Records.size());
- TTB->insertRecordBytes(Records.front().RecordData);
- discoverAllTypeIndices();
- }
-
- template <typename... T> void writeTypeRecords(T &&... Records) {
- writeTypeRecordsImpl(std::forward<T>(Records)...);
- ASSERT_EQ(sizeof...(T), TTB->records().size());
- discoverAllTypeIndices();
- }
-
- template <typename... T> void writeSymbolRecords(T &&... Records) {
- writeSymbolRecordsImpl(std::forward<T>(Records)...);
- ASSERT_EQ(sizeof...(T), Symbols.size());
- discoverTypeIndicesInSymbols();
- }
-
- std::unique_ptr<AppendingTypeTableBuilder> TTB;
-
-private:
- uint32_t countRefs(uint32_t RecordIndex) const {
- auto &R = Refs[RecordIndex];
- uint32_t Count = 0;
- for (auto &Ref : R) {
- Count += Ref.Count;
- }
- return Count;
- }
-
- bool checkOneTypeReference(uint32_t RecordIndex, ArrayRef<uint8_t> RecordData,
- TypeIndex TI) const {
- RecordData = RecordData.drop_front(sizeof(RecordPrefix));
- auto &RefList = Refs[RecordIndex];
- for (auto &Ref : RefList) {
- uint32_t Offset = Ref.Offset;
- ArrayRef<uint8_t> Loc = RecordData.drop_front(Offset);
- ArrayRef<TypeIndex> Indices(
- reinterpret_cast<const TypeIndex *>(Loc.data()), Ref.Count);
- if (llvm::any_of(Indices,
- [TI](const TypeIndex &Other) { return Other == TI; }))
- return true;
- }
- return false;
- }
-
- template <typename... Indices>
- bool checkTypeReferencesImpl(uint32_t RecordIndex,
- ArrayRef<ArrayRef<uint8_t>> CVRecords) const {
- return true;
- }
-
- template <typename... Indices>
- bool checkTypeReferencesImpl(uint32_t RecordIndex,
- ArrayRef<ArrayRef<uint8_t>> CVRecords,
- TypeIndex TI, Indices &&... Rest) const {
- ArrayRef<uint8_t> Record = CVRecords[RecordIndex];
- bool Success = checkOneTypeReference(RecordIndex, Record, TI);
- EXPECT_TRUE(Success);
- return Success & checkTypeReferencesImpl(RecordIndex, CVRecords,
- std::forward<Indices>(Rest)...);
- }
-
- void discoverAllTypeIndices() {
- Refs.resize(TTB->records().size());
- for (uint32_t I = 0; I < TTB->records().size(); ++I) {
- ArrayRef<uint8_t> Data = TTB->records()[I];
- discoverTypeIndices(Data, Refs[I]);
- }
- }
-
- void discoverTypeIndicesInSymbols() {
- Refs.resize(Symbols.size());
- for (uint32_t I = 0; I < Symbols.size(); ++I)
- discoverTypeIndicesInSymbol(Symbols[I], Refs[I]);
- }
-
- // Helper function to write out a field list record with the given list
- // of member records.
- void writeFieldListImpl() {}
-
- template <typename RecType, typename... Rest>
- void writeFieldListImpl(RecType &&Record, Rest &&... Records) {
- CRB->writeMemberType(Record);
- writeFieldListImpl(std::forward<Rest>(Records)...);
- }
-
- // Helper function to write out a list of type records.
- void writeTypeRecordsImpl() {}
-
- template <typename RecType, typename... Rest>
- void writeTypeRecordsImpl(RecType &&Record, Rest &&... Records) {
- TTB->writeLeafType(Record);
- writeTypeRecordsImpl(std::forward<Rest>(Records)...);
- }
-
- // Helper function to write out a list of symbol records.
- void writeSymbolRecordsImpl() {}
-
- template <typename RecType, typename... Rest>
- void writeSymbolRecordsImpl(RecType &&Record, Rest &&... Records) {
- Symbols.push_back(SymbolSerializer::writeOneSymbol(Record, Storage,
- CodeViewContainer::Pdb));
- writeSymbolRecordsImpl(std::forward<Rest>(Records)...);
- }
-
- std::vector<SmallVector<TiReference, 4>> Refs;
- std::unique_ptr<ContinuationRecordBuilder> CRB;
- std::vector<CVSymbol> Symbols;
- BumpPtrAllocator Storage;
-};
-
-namespace leafs {
-static FuncIdRecord FuncId(TypeIndex(1), TypeIndex(2), "FuncId");
-static MemberFuncIdRecord MemFuncId(TypeIndex(3), TypeIndex(4), "FuncId");
-static StringIdRecord StringId(TypeIndex(5), "TheString");
-static struct {
- std::vector<TypeIndex> Ids = {TypeIndex(6), TypeIndex(7), TypeIndex(8)};
- StringListRecord Record{TypeRecordKind::StringList, Ids};
-} StringList;
-static struct {
- std::vector<TypeIndex> Ids = {TypeIndex(9), TypeIndex(10), TypeIndex(11)};
- BuildInfoRecord Record{Ids};
-} BuildInfo;
-static UdtSourceLineRecord UdtSourceLine(TypeIndex(12), TypeIndex(13), 0);
-static UdtModSourceLineRecord UdtModSourceLine(TypeIndex(14), TypeIndex(15), 0,
- 0);
-static ModifierRecord Modifier(TypeIndex(16), ModifierOptions::None);
-static ProcedureRecord Procedure(TypeIndex(17), CallingConvention::PpcCall,
- FunctionOptions::None, 0, TypeIndex(18));
-static MemberFunctionRecord MemberFunction(TypeIndex(19), TypeIndex(20),
- TypeIndex(21),
- CallingConvention::ThisCall,
- FunctionOptions::None, 2,
- TypeIndex(22), 0);
-static struct {
- std::vector<TypeIndex> Ids = {TypeIndex(23), TypeIndex(24), TypeIndex(25)};
- ArgListRecord Record{TypeRecordKind::ArgList, Ids};
-} ArgList;
-static ArrayRecord Array(TypeIndex(26), TypeIndex(27), 10, "MyArray");
-static ClassRecord Class(TypeRecordKind::Class, 3, ClassOptions::None,
- TypeIndex(28), TypeIndex(29), TypeIndex(30), 10,
- "MyClass", "MyClassUniqueName");
-static ClassRecord Struct(TypeRecordKind::Struct, 3, ClassOptions::None,
- TypeIndex(31), TypeIndex(32), TypeIndex(33), 10,
- "MyClass", "MyClassUniqueName");
-static UnionRecord Union(1, ClassOptions::None, TypeIndex(34), 10, "MyUnion",
- "MyUnionUniqueName");
-static EnumRecord Enum(1, ClassOptions::None, TypeIndex(35), "MyEnum",
- "EnumUniqueName", TypeIndex(36));
-static BitFieldRecord BitField(TypeIndex(37), 1, 0);
-static VFTableRecord VFTable(TypeIndex(38), TypeIndex(39), 1, "VFT", {});
-static VFTableShapeRecord VTableShape({});
-static struct {
- const TypeIndex T1{40};
- const TypeIndex T2{41};
- const TypeIndex T3{42};
- const TypeIndex T4{43};
-
- std::vector<OneMethodRecord> Methods{
- {T1, MemberAccess::Public, MethodKind::IntroducingVirtual,
- MethodOptions::None, 0, "Method1"},
- {T2, MemberAccess::Public, MethodKind::PureVirtual, MethodOptions::None,
- 0, "Method1"},
- {T3, MemberAccess::Public, MethodKind::PureIntroducingVirtual,
- MethodOptions::None, 0, "Method1"},
- {T4, MemberAccess::Public, MethodKind::Static, MethodOptions::None, 0,
- "Method1"}};
-
- MethodOverloadListRecord Record{Methods};
-} MethodOverloadList;
-static PointerRecord Pointer(TypeIndex(44), PointerKind::Near32,
- PointerMode::Pointer, PointerOptions::Const, 3);
-static PointerRecord MemberPointer(
- TypeIndex(45), PointerKind::Near32, PointerMode::PointerToDataMember,
- PointerOptions::Const, 3,
- MemberPointerInfo(TypeIndex(46),
- PointerToMemberRepresentation::GeneralData));
-}
-
-namespace members {
-static BaseClassRecord BaseClass(MemberAccess::Public, TypeIndex(47), 0);
-static EnumeratorRecord Enumerator(MemberAccess::Public,
- APSInt(APInt(8, 3, false)), "Test");
-DataMemberRecord DataMember(MemberAccess::Public, TypeIndex(48), 0, "Test");
-OverloadedMethodRecord OverloadedMethod(3, TypeIndex(49), "MethodList");
-static struct {
- const TypeIndex T1{50};
- const TypeIndex T2{51};
- const TypeIndex T3{52};
- const TypeIndex T4{53};
- OneMethodRecord R1{T1,
- MemberAccess::Public,
- MethodKind::IntroducingVirtual,
- MethodOptions::None,
- 0,
- "M1"};
- OneMethodRecord R2{T2,
- MemberAccess::Public,
- MethodKind::PureVirtual,
- MethodOptions::None,
- 0,
- "M2"};
- OneMethodRecord R3{T3,
- MemberAccess::Public,
- MethodKind::PureIntroducingVirtual,
- MethodOptions::None,
- 0,
- "M3"};
- OneMethodRecord R4{T4,
- MemberAccess::Protected,
- MethodKind::Vanilla,
- MethodOptions::CompilerGenerated,
- 0,
- "M4"};
-} OneMethod;
-static NestedTypeRecord NestedType(TypeIndex(54), "MyClass");
-static StaticDataMemberRecord StaticDataMember(MemberAccess::Public,
- TypeIndex(55), "Foo");
-static VirtualBaseClassRecord VirtualBaseClass(TypeRecordKind::VirtualBaseClass,
- MemberAccess::Public,
- TypeIndex(56), TypeIndex(57), 0,
- 0);
-static VFPtrRecord VFPtr(TypeIndex(58));
-static ListContinuationRecord Continuation(TypeIndex(59));
-}
-
-TEST_F(TypeIndexIteratorTest, FuncId) {
- using namespace leafs;
- writeTypeRecords(FuncId);
- checkTypeReferences(0, FuncId.FunctionType, FuncId.ParentScope);
-}
-
-TEST_F(TypeIndexIteratorTest, MemFuncId) {
- using namespace leafs;
- writeTypeRecords(MemFuncId);
- checkTypeReferences(0, MemFuncId.ClassType, MemFuncId.FunctionType);
-}
-
-TEST_F(TypeIndexIteratorTest, StringId) {
- using namespace leafs;
- writeTypeRecords(StringId);
- checkTypeReferences(0, StringId.Id);
-}
-
-TEST_F(TypeIndexIteratorTest, SubstrList) {
- using namespace leafs;
- writeTypeRecords(StringList.Record);
- checkTypeReferences(0, StringList.Ids[0], StringList.Ids[1],
- StringList.Ids[2]);
-}
-
-TEST_F(TypeIndexIteratorTest, BuildInfo) {
- using namespace leafs;
- writeTypeRecords(BuildInfo.Record);
- checkTypeReferences(0, BuildInfo.Ids[0], BuildInfo.Ids[1], BuildInfo.Ids[2]);
-}
-
-TEST_F(TypeIndexIteratorTest, UdtSrcLine) {
- using namespace leafs;
- writeTypeRecords(UdtSourceLine);
- checkTypeReferences(0, UdtSourceLine.UDT, UdtSourceLine.SourceFile);
-}
-
-TEST_F(TypeIndexIteratorTest, UdtModSrcLine) {
- using namespace leafs;
- writeTypeRecords(UdtModSourceLine);
- checkTypeReferences(0, UdtModSourceLine.UDT, UdtModSourceLine.SourceFile);
-}
-
-TEST_F(TypeIndexIteratorTest, Modifier) {
- using namespace leafs;
- writeTypeRecords(Modifier);
- checkTypeReferences(0, Modifier.ModifiedType);
-}
-
-TEST_F(TypeIndexIteratorTest, Procedure) {
- using namespace leafs;
- writeTypeRecords(Procedure);
- checkTypeReferences(0, Procedure.ReturnType, Procedure.ArgumentList);
-}
-
-TEST_F(TypeIndexIteratorTest, MemFunc) {
- using namespace leafs;
- writeTypeRecords(MemberFunction);
- checkTypeReferences(0, MemberFunction.ReturnType, MemberFunction.ClassType,
- MemberFunction.ThisType, MemberFunction.ArgumentList);
-}
-
-TEST_F(TypeIndexIteratorTest, ArgList) {
- using namespace leafs;
- writeTypeRecords(ArgList.Record);
- checkTypeReferences(0, ArgList.Ids[0], ArgList.Ids[1], ArgList.Ids[2]);
-}
-
-TEST_F(TypeIndexIteratorTest, Array) {
- using namespace leafs;
- writeTypeRecords(Array);
- checkTypeReferences(0, Array.ElementType, Array.IndexType);
-}
-
-TEST_F(TypeIndexIteratorTest, Class) {
- using namespace leafs;
- writeTypeRecords(Class);
- checkTypeReferences(0, Class.FieldList, Class.DerivationList,
- Class.VTableShape);
-}
-
-TEST_F(TypeIndexIteratorTest, Struct) {
- using namespace leafs;
- writeTypeRecords(Struct);
- checkTypeReferences(0, Struct.FieldList, Struct.DerivationList,
- Struct.VTableShape);
-}
-
-TEST_F(TypeIndexIteratorTest, Union) {
- using namespace leafs;
- writeTypeRecords(Union);
- checkTypeReferences(0, Union.FieldList);
-}
-
-TEST_F(TypeIndexIteratorTest, Enum) {
- using namespace leafs;
- writeTypeRecords(Enum);
- checkTypeReferences(0, Enum.FieldList, Enum.UnderlyingType);
-}
-
-TEST_F(TypeIndexIteratorTest, Bitfield) {
- using namespace leafs;
- writeTypeRecords(BitField);
- checkTypeReferences(0, BitField.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, VTable) {
- using namespace leafs;
- writeTypeRecords(VFTable);
- checkTypeReferences(0, VFTable.CompleteClass, VFTable.OverriddenVFTable);
-}
-
-TEST_F(TypeIndexIteratorTest, VTShape) {
- using namespace leafs;
- writeTypeRecords(VTableShape);
- checkTypeReferences(0);
-}
-
-TEST_F(TypeIndexIteratorTest, OverloadList) {
- using namespace leafs;
- writeTypeRecords(MethodOverloadList.Record);
- checkTypeReferences(0, MethodOverloadList.T1, MethodOverloadList.T2,
- MethodOverloadList.T3, MethodOverloadList.T4);
-}
-
-TEST_F(TypeIndexIteratorTest, Pointer) {
- using namespace leafs;
- writeTypeRecords(Pointer);
- checkTypeReferences(0, Pointer.ReferentType);
-}
-
-TEST_F(TypeIndexIteratorTest, MemberPointer) {
- using namespace leafs;
- writeTypeRecords(MemberPointer);
- checkTypeReferences(0, MemberPointer.ReferentType,
- MemberPointer.MemberInfo->ContainingType);
-}
-
-TEST_F(TypeIndexIteratorTest, ManyTypes) {
-
- using namespace leafs;
- writeTypeRecords(FuncId, MemFuncId, StringId, StringList.Record,
- BuildInfo.Record, UdtSourceLine, UdtModSourceLine, Modifier,
- Procedure, MemberFunction, ArgList.Record, Array, Class,
- Union, Enum, BitField, VFTable, VTableShape,
- MethodOverloadList.Record, Pointer, MemberPointer);
-
- checkTypeReferences(0, FuncId.FunctionType, FuncId.ParentScope);
- checkTypeReferences(1, MemFuncId.ClassType, MemFuncId.FunctionType);
- checkTypeReferences(2, StringId.Id);
- checkTypeReferences(3, StringList.Ids[0], StringList.Ids[1],
- StringList.Ids[2]);
- checkTypeReferences(4, BuildInfo.Ids[0], BuildInfo.Ids[1], BuildInfo.Ids[2]);
- checkTypeReferences(5, UdtSourceLine.UDT, UdtSourceLine.SourceFile);
- checkTypeReferences(6, UdtModSourceLine.UDT, UdtModSourceLine.SourceFile);
- checkTypeReferences(7, Modifier.ModifiedType);
- checkTypeReferences(8, Procedure.ReturnType, Procedure.ArgumentList);
- checkTypeReferences(9, MemberFunction.ReturnType, MemberFunction.ClassType,
- MemberFunction.ThisType, MemberFunction.ArgumentList);
- checkTypeReferences(10, ArgList.Ids[0], ArgList.Ids[1], ArgList.Ids[2]);
- checkTypeReferences(11, Array.ElementType, Array.IndexType);
- checkTypeReferences(12, Class.FieldList, Class.DerivationList,
- Class.VTableShape);
- checkTypeReferences(13, Union.FieldList);
- checkTypeReferences(14, Enum.FieldList, Enum.UnderlyingType);
- checkTypeReferences(15, BitField.Type);
- checkTypeReferences(16, VFTable.CompleteClass, VFTable.OverriddenVFTable);
- checkTypeReferences(17);
- checkTypeReferences(18, MethodOverloadList.T1, MethodOverloadList.T2,
- MethodOverloadList.T3, MethodOverloadList.T4);
- checkTypeReferences(19, Pointer.ReferentType);
- checkTypeReferences(20, MemberPointer.ReferentType,
- MemberPointer.MemberInfo->ContainingType);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListBaseClass) {
- using namespace members;
- writeFieldList(BaseClass);
- checkTypeReferences(0, BaseClass.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListEnumerator) {
- using namespace members;
- writeFieldList(Enumerator);
- checkTypeReferences(0);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListMember) {
- using namespace members;
- writeFieldList(DataMember);
- checkTypeReferences(0, DataMember.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListMethod) {
- using namespace members;
- writeFieldList(OverloadedMethod);
- checkTypeReferences(0, OverloadedMethod.MethodList);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListOneMethod) {
- using namespace members;
- writeFieldList(OneMethod.R1, OneMethod.R2, OneMethod.R3, OneMethod.R4);
- checkTypeReferences(0, OneMethod.T1, OneMethod.T2, OneMethod.T3,
- OneMethod.T4);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListNestedType) {
- using namespace members;
- writeFieldList(NestedType);
- checkTypeReferences(0, NestedType.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListStaticMember) {
- using namespace members;
- writeFieldList(StaticDataMember);
- checkTypeReferences(0, StaticDataMember.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListVirtualBase) {
- using namespace members;
- writeFieldList(VirtualBaseClass);
- checkTypeReferences(0, VirtualBaseClass.BaseType, VirtualBaseClass.VBPtrType);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListVFTable) {
- using namespace members;
- writeFieldList(VFPtr);
- checkTypeReferences(0, VFPtr.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, FieldListContinuation) {
- using namespace members;
- writeFieldList(Continuation);
- checkTypeReferences(0, Continuation.ContinuationIndex);
-}
-
-TEST_F(TypeIndexIteratorTest, ManyMembers) {
- using namespace members;
- writeFieldList(BaseClass, Enumerator, DataMember, OverloadedMethod,
- OneMethod.R1, OneMethod.R2, OneMethod.R3, OneMethod.R4,
- NestedType, StaticDataMember, VirtualBaseClass, VFPtr,
- Continuation);
-
- checkTypeReferences(
- 0, BaseClass.Type, DataMember.Type, OverloadedMethod.MethodList,
- OneMethod.T1, OneMethod.T2, OneMethod.T3, OneMethod.T4, NestedType.Type,
- StaticDataMember.Type, VirtualBaseClass.BaseType,
- VirtualBaseClass.VBPtrType, VFPtr.Type, Continuation.ContinuationIndex);
-}
-
-TEST_F(TypeIndexIteratorTest, ProcSym) {
- ProcSym GS(SymbolRecordKind::GlobalProcSym);
- GS.FunctionType = TypeIndex::Float32();
- ProcSym LS(SymbolRecordKind::ProcSym);
- LS.FunctionType = TypeIndex::Float64();
- writeSymbolRecords(GS, LS);
- checkTypeReferences(0, GS.FunctionType);
- checkTypeReferences(1, LS.FunctionType);
-}
-
-TEST_F(TypeIndexIteratorTest, DataSym) {
- DataSym DS(SymbolRecordKind::GlobalData);
- DS.Type = TypeIndex::Float32();
- writeSymbolRecords(DS);
- checkTypeReferences(0, DS.Type);
-}
-
-TEST_F(TypeIndexIteratorTest, RegisterSym) {
- RegisterSym Reg(SymbolRecordKind::RegisterSym);
- Reg.Index = TypeIndex::UInt32();
- Reg.Register = RegisterId::EAX;
- Reg.Name = "Target";
- writeSymbolRecords(Reg);
- checkTypeReferences(0, Reg.Index);
-}
-
-TEST_F(TypeIndexIteratorTest, CallerSym) {
- CallerSym Callees(SymbolRecordKind::CalleeSym);
- Callees.Indices.push_back(TypeIndex(1));
- Callees.Indices.push_back(TypeIndex(2));
- Callees.Indices.push_back(TypeIndex(3));
- CallerSym Callers(SymbolRecordKind::CallerSym);
- Callers.Indices.push_back(TypeIndex(4));
- Callers.Indices.push_back(TypeIndex(5));
- Callers.Indices.push_back(TypeIndex(6));
- CallerSym Inlinees(SymbolRecordKind::InlineesSym);
- Inlinees.Indices.push_back(TypeIndex(7));
- Inlinees.Indices.push_back(TypeIndex(8));
- Inlinees.Indices.push_back(TypeIndex(9));
- writeSymbolRecords(Callees, Callers, Inlinees);
- checkTypeReferences(0, TypeIndex(1), TypeIndex(2), TypeIndex(3));
- checkTypeReferences(1, TypeIndex(4), TypeIndex(5), TypeIndex(6));
- checkTypeReferences(2, TypeIndex(7), TypeIndex(8), TypeIndex(9));
-}
-
-TEST_F(TypeIndexIteratorTest, Precomp) {
- PrecompRecord P(TypeRecordKind::Precomp);
- P.StartTypeIndex = TypeIndex::FirstNonSimpleIndex;
- P.TypesCount = 100;
- P.Signature = 0x12345678;
- P.PrecompFilePath = "C:/precomp.obj";
-
- EndPrecompRecord EP(TypeRecordKind::EndPrecomp);
- EP.Signature = P.Signature;
-
- writeTypeRecords(P, EP);
- checkTypeReferences(0);
-}
+//===- llvm/unittest/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" + +#include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" +#include "llvm/DebugInfo/CodeView/SymbolSerializer.h" +#include "llvm/Support/Allocator.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::codeview; + +class TypeIndexIteratorTest : public testing::Test { +public: + TypeIndexIteratorTest() {} + + void SetUp() override { + Refs.clear(); + TTB = make_unique<AppendingTypeTableBuilder>(Storage); + CRB = make_unique<ContinuationRecordBuilder>(); + Symbols.clear(); + } + + void TearDown() override { + CRB.reset(); + TTB.reset(); + } + +protected: + template <typename... Indices> + bool checkTypeReferences(uint32_t RecordIndex, Indices &&... TIs) const { + EXPECT_EQ(sizeof...(Indices), countRefs(RecordIndex)); + + // Choose between type or symbol records. The checking code doesn't care + // which we have. + std::vector<ArrayRef<uint8_t>> CVRecords; + if (Symbols.empty()) { + CVRecords = TTB->records(); + } else { + for (const CVSymbol &S : Symbols) + CVRecords.push_back(S.data()); + } + + return checkTypeReferencesImpl(RecordIndex, CVRecords, + std::forward<Indices>(TIs)...); + } + + template <typename... T> void writeFieldList(T &&... MemberRecords) { + CRB->begin(ContinuationRecordKind::FieldList); + writeFieldListImpl(std::forward<T>(MemberRecords)...); + auto Records = CRB->end(TTB->nextTypeIndex()); + ASSERT_EQ(1u, Records.size()); + TTB->insertRecordBytes(Records.front().RecordData); + discoverAllTypeIndices(); + } + + template <typename... T> void writeTypeRecords(T &&... Records) { + writeTypeRecordsImpl(std::forward<T>(Records)...); + ASSERT_EQ(sizeof...(T), TTB->records().size()); + discoverAllTypeIndices(); + } + + template <typename... T> void writeSymbolRecords(T &&... Records) { + writeSymbolRecordsImpl(std::forward<T>(Records)...); + ASSERT_EQ(sizeof...(T), Symbols.size()); + discoverTypeIndicesInSymbols(); + } + + std::unique_ptr<AppendingTypeTableBuilder> TTB; + +private: + uint32_t countRefs(uint32_t RecordIndex) const { + auto &R = Refs[RecordIndex]; + uint32_t Count = 0; + for (auto &Ref : R) { + Count += Ref.Count; + } + return Count; + } + + bool checkOneTypeReference(uint32_t RecordIndex, ArrayRef<uint8_t> RecordData, + TypeIndex TI) const { + RecordData = RecordData.drop_front(sizeof(RecordPrefix)); + auto &RefList = Refs[RecordIndex]; + for (auto &Ref : RefList) { + uint32_t Offset = Ref.Offset; + ArrayRef<uint8_t> Loc = RecordData.drop_front(Offset); + ArrayRef<TypeIndex> Indices( + reinterpret_cast<const TypeIndex *>(Loc.data()), Ref.Count); + if (llvm::any_of(Indices, + [TI](const TypeIndex &Other) { return Other == TI; })) + return true; + } + return false; + } + + template <typename... Indices> + bool checkTypeReferencesImpl(uint32_t RecordIndex, + ArrayRef<ArrayRef<uint8_t>> CVRecords) const { + return true; + } + + template <typename... Indices> + bool checkTypeReferencesImpl(uint32_t RecordIndex, + ArrayRef<ArrayRef<uint8_t>> CVRecords, + TypeIndex TI, Indices &&... Rest) const { + ArrayRef<uint8_t> Record = CVRecords[RecordIndex]; + bool Success = checkOneTypeReference(RecordIndex, Record, TI); + EXPECT_TRUE(Success); + return Success & checkTypeReferencesImpl(RecordIndex, CVRecords, + std::forward<Indices>(Rest)...); + } + + void discoverAllTypeIndices() { + Refs.resize(TTB->records().size()); + for (uint32_t I = 0; I < TTB->records().size(); ++I) { + ArrayRef<uint8_t> Data = TTB->records()[I]; + discoverTypeIndices(Data, Refs[I]); + } + } + + void discoverTypeIndicesInSymbols() { + Refs.resize(Symbols.size()); + for (uint32_t I = 0; I < Symbols.size(); ++I) + discoverTypeIndicesInSymbol(Symbols[I], Refs[I]); + } + + // Helper function to write out a field list record with the given list + // of member records. + void writeFieldListImpl() {} + + template <typename RecType, typename... Rest> + void writeFieldListImpl(RecType &&Record, Rest &&... Records) { + CRB->writeMemberType(Record); + writeFieldListImpl(std::forward<Rest>(Records)...); + } + + // Helper function to write out a list of type records. + void writeTypeRecordsImpl() {} + + template <typename RecType, typename... Rest> + void writeTypeRecordsImpl(RecType &&Record, Rest &&... Records) { + TTB->writeLeafType(Record); + writeTypeRecordsImpl(std::forward<Rest>(Records)...); + } + + // Helper function to write out a list of symbol records. + void writeSymbolRecordsImpl() {} + + template <typename RecType, typename... Rest> + void writeSymbolRecordsImpl(RecType &&Record, Rest &&... Records) { + Symbols.push_back(SymbolSerializer::writeOneSymbol(Record, Storage, + CodeViewContainer::Pdb)); + writeSymbolRecordsImpl(std::forward<Rest>(Records)...); + } + + std::vector<SmallVector<TiReference, 4>> Refs; + std::unique_ptr<ContinuationRecordBuilder> CRB; + std::vector<CVSymbol> Symbols; + BumpPtrAllocator Storage; +}; + +namespace leafs { +static FuncIdRecord FuncId(TypeIndex(1), TypeIndex(2), "FuncId"); +static MemberFuncIdRecord MemFuncId(TypeIndex(3), TypeIndex(4), "FuncId"); +static StringIdRecord StringId(TypeIndex(5), "TheString"); +static struct { + std::vector<TypeIndex> Ids = {TypeIndex(6), TypeIndex(7), TypeIndex(8)}; + StringListRecord Record{TypeRecordKind::StringList, Ids}; +} StringList; +static struct { + std::vector<TypeIndex> Ids = {TypeIndex(9), TypeIndex(10), TypeIndex(11)}; + BuildInfoRecord Record{Ids}; +} BuildInfo; +static UdtSourceLineRecord UdtSourceLine(TypeIndex(12), TypeIndex(13), 0); +static UdtModSourceLineRecord UdtModSourceLine(TypeIndex(14), TypeIndex(15), 0, + 0); +static ModifierRecord Modifier(TypeIndex(16), ModifierOptions::None); +static ProcedureRecord Procedure(TypeIndex(17), CallingConvention::PpcCall, + FunctionOptions::None, 0, TypeIndex(18)); +static MemberFunctionRecord MemberFunction(TypeIndex(19), TypeIndex(20), + TypeIndex(21), + CallingConvention::ThisCall, + FunctionOptions::None, 2, + TypeIndex(22), 0); +static struct { + std::vector<TypeIndex> Ids = {TypeIndex(23), TypeIndex(24), TypeIndex(25)}; + ArgListRecord Record{TypeRecordKind::ArgList, Ids}; +} ArgList; +static ArrayRecord Array(TypeIndex(26), TypeIndex(27), 10, "MyArray"); +static ClassRecord Class(TypeRecordKind::Class, 3, ClassOptions::None, + TypeIndex(28), TypeIndex(29), TypeIndex(30), 10, + "MyClass", "MyClassUniqueName"); +static ClassRecord Struct(TypeRecordKind::Struct, 3, ClassOptions::None, + TypeIndex(31), TypeIndex(32), TypeIndex(33), 10, + "MyClass", "MyClassUniqueName"); +static UnionRecord Union(1, ClassOptions::None, TypeIndex(34), 10, "MyUnion", + "MyUnionUniqueName"); +static EnumRecord Enum(1, ClassOptions::None, TypeIndex(35), "MyEnum", + "EnumUniqueName", TypeIndex(36)); +static BitFieldRecord BitField(TypeIndex(37), 1, 0); +static VFTableRecord VFTable(TypeIndex(38), TypeIndex(39), 1, "VFT", {}); +static VFTableShapeRecord VTableShape({}); +static struct { + const TypeIndex T1{40}; + const TypeIndex T2{41}; + const TypeIndex T3{42}; + const TypeIndex T4{43}; + + std::vector<OneMethodRecord> Methods{ + {T1, MemberAccess::Public, MethodKind::IntroducingVirtual, + MethodOptions::None, 0, "Method1"}, + {T2, MemberAccess::Public, MethodKind::PureVirtual, MethodOptions::None, + 0, "Method1"}, + {T3, MemberAccess::Public, MethodKind::PureIntroducingVirtual, + MethodOptions::None, 0, "Method1"}, + {T4, MemberAccess::Public, MethodKind::Static, MethodOptions::None, 0, + "Method1"}}; + + MethodOverloadListRecord Record{Methods}; +} MethodOverloadList; +static PointerRecord Pointer(TypeIndex(44), PointerKind::Near32, + PointerMode::Pointer, PointerOptions::Const, 3); +static PointerRecord MemberPointer( + TypeIndex(45), PointerKind::Near32, PointerMode::PointerToDataMember, + PointerOptions::Const, 3, + MemberPointerInfo(TypeIndex(46), + PointerToMemberRepresentation::GeneralData)); +} + +namespace members { +static BaseClassRecord BaseClass(MemberAccess::Public, TypeIndex(47), 0); +static EnumeratorRecord Enumerator(MemberAccess::Public, + APSInt(APInt(8, 3, false)), "Test"); +DataMemberRecord DataMember(MemberAccess::Public, TypeIndex(48), 0, "Test"); +OverloadedMethodRecord OverloadedMethod(3, TypeIndex(49), "MethodList"); +static struct { + const TypeIndex T1{50}; + const TypeIndex T2{51}; + const TypeIndex T3{52}; + const TypeIndex T4{53}; + OneMethodRecord R1{T1, + MemberAccess::Public, + MethodKind::IntroducingVirtual, + MethodOptions::None, + 0, + "M1"}; + OneMethodRecord R2{T2, + MemberAccess::Public, + MethodKind::PureVirtual, + MethodOptions::None, + 0, + "M2"}; + OneMethodRecord R3{T3, + MemberAccess::Public, + MethodKind::PureIntroducingVirtual, + MethodOptions::None, + 0, + "M3"}; + OneMethodRecord R4{T4, + MemberAccess::Protected, + MethodKind::Vanilla, + MethodOptions::CompilerGenerated, + 0, + "M4"}; +} OneMethod; +static NestedTypeRecord NestedType(TypeIndex(54), "MyClass"); +static StaticDataMemberRecord StaticDataMember(MemberAccess::Public, + TypeIndex(55), "Foo"); +static VirtualBaseClassRecord VirtualBaseClass(TypeRecordKind::VirtualBaseClass, + MemberAccess::Public, + TypeIndex(56), TypeIndex(57), 0, + 0); +static VFPtrRecord VFPtr(TypeIndex(58)); +static ListContinuationRecord Continuation(TypeIndex(59)); +} + +TEST_F(TypeIndexIteratorTest, FuncId) { + using namespace leafs; + writeTypeRecords(FuncId); + checkTypeReferences(0, FuncId.FunctionType, FuncId.ParentScope); +} + +TEST_F(TypeIndexIteratorTest, MemFuncId) { + using namespace leafs; + writeTypeRecords(MemFuncId); + checkTypeReferences(0, MemFuncId.ClassType, MemFuncId.FunctionType); +} + +TEST_F(TypeIndexIteratorTest, StringId) { + using namespace leafs; + writeTypeRecords(StringId); + checkTypeReferences(0, StringId.Id); +} + +TEST_F(TypeIndexIteratorTest, SubstrList) { + using namespace leafs; + writeTypeRecords(StringList.Record); + checkTypeReferences(0, StringList.Ids[0], StringList.Ids[1], + StringList.Ids[2]); +} + +TEST_F(TypeIndexIteratorTest, BuildInfo) { + using namespace leafs; + writeTypeRecords(BuildInfo.Record); + checkTypeReferences(0, BuildInfo.Ids[0], BuildInfo.Ids[1], BuildInfo.Ids[2]); +} + +TEST_F(TypeIndexIteratorTest, UdtSrcLine) { + using namespace leafs; + writeTypeRecords(UdtSourceLine); + checkTypeReferences(0, UdtSourceLine.UDT, UdtSourceLine.SourceFile); +} + +TEST_F(TypeIndexIteratorTest, UdtModSrcLine) { + using namespace leafs; + writeTypeRecords(UdtModSourceLine); + checkTypeReferences(0, UdtModSourceLine.UDT, UdtModSourceLine.SourceFile); +} + +TEST_F(TypeIndexIteratorTest, Modifier) { + using namespace leafs; + writeTypeRecords(Modifier); + checkTypeReferences(0, Modifier.ModifiedType); +} + +TEST_F(TypeIndexIteratorTest, Procedure) { + using namespace leafs; + writeTypeRecords(Procedure); + checkTypeReferences(0, Procedure.ReturnType, Procedure.ArgumentList); +} + +TEST_F(TypeIndexIteratorTest, MemFunc) { + using namespace leafs; + writeTypeRecords(MemberFunction); + checkTypeReferences(0, MemberFunction.ReturnType, MemberFunction.ClassType, + MemberFunction.ThisType, MemberFunction.ArgumentList); +} + +TEST_F(TypeIndexIteratorTest, ArgList) { + using namespace leafs; + writeTypeRecords(ArgList.Record); + checkTypeReferences(0, ArgList.Ids[0], ArgList.Ids[1], ArgList.Ids[2]); +} + +TEST_F(TypeIndexIteratorTest, Array) { + using namespace leafs; + writeTypeRecords(Array); + checkTypeReferences(0, Array.ElementType, Array.IndexType); +} + +TEST_F(TypeIndexIteratorTest, Class) { + using namespace leafs; + writeTypeRecords(Class); + checkTypeReferences(0, Class.FieldList, Class.DerivationList, + Class.VTableShape); +} + +TEST_F(TypeIndexIteratorTest, Struct) { + using namespace leafs; + writeTypeRecords(Struct); + checkTypeReferences(0, Struct.FieldList, Struct.DerivationList, + Struct.VTableShape); +} + +TEST_F(TypeIndexIteratorTest, Union) { + using namespace leafs; + writeTypeRecords(Union); + checkTypeReferences(0, Union.FieldList); +} + +TEST_F(TypeIndexIteratorTest, Enum) { + using namespace leafs; + writeTypeRecords(Enum); + checkTypeReferences(0, Enum.FieldList, Enum.UnderlyingType); +} + +TEST_F(TypeIndexIteratorTest, Bitfield) { + using namespace leafs; + writeTypeRecords(BitField); + checkTypeReferences(0, BitField.Type); +} + +TEST_F(TypeIndexIteratorTest, VTable) { + using namespace leafs; + writeTypeRecords(VFTable); + checkTypeReferences(0, VFTable.CompleteClass, VFTable.OverriddenVFTable); +} + +TEST_F(TypeIndexIteratorTest, VTShape) { + using namespace leafs; + writeTypeRecords(VTableShape); + checkTypeReferences(0); +} + +TEST_F(TypeIndexIteratorTest, OverloadList) { + using namespace leafs; + writeTypeRecords(MethodOverloadList.Record); + checkTypeReferences(0, MethodOverloadList.T1, MethodOverloadList.T2, + MethodOverloadList.T3, MethodOverloadList.T4); +} + +TEST_F(TypeIndexIteratorTest, Pointer) { + using namespace leafs; + writeTypeRecords(Pointer); + checkTypeReferences(0, Pointer.ReferentType); +} + +TEST_F(TypeIndexIteratorTest, MemberPointer) { + using namespace leafs; + writeTypeRecords(MemberPointer); + checkTypeReferences(0, MemberPointer.ReferentType, + MemberPointer.MemberInfo->ContainingType); +} + +TEST_F(TypeIndexIteratorTest, ManyTypes) { + + using namespace leafs; + writeTypeRecords(FuncId, MemFuncId, StringId, StringList.Record, + BuildInfo.Record, UdtSourceLine, UdtModSourceLine, Modifier, + Procedure, MemberFunction, ArgList.Record, Array, Class, + Union, Enum, BitField, VFTable, VTableShape, + MethodOverloadList.Record, Pointer, MemberPointer); + + checkTypeReferences(0, FuncId.FunctionType, FuncId.ParentScope); + checkTypeReferences(1, MemFuncId.ClassType, MemFuncId.FunctionType); + checkTypeReferences(2, StringId.Id); + checkTypeReferences(3, StringList.Ids[0], StringList.Ids[1], + StringList.Ids[2]); + checkTypeReferences(4, BuildInfo.Ids[0], BuildInfo.Ids[1], BuildInfo.Ids[2]); + checkTypeReferences(5, UdtSourceLine.UDT, UdtSourceLine.SourceFile); + checkTypeReferences(6, UdtModSourceLine.UDT, UdtModSourceLine.SourceFile); + checkTypeReferences(7, Modifier.ModifiedType); + checkTypeReferences(8, Procedure.ReturnType, Procedure.ArgumentList); + checkTypeReferences(9, MemberFunction.ReturnType, MemberFunction.ClassType, + MemberFunction.ThisType, MemberFunction.ArgumentList); + checkTypeReferences(10, ArgList.Ids[0], ArgList.Ids[1], ArgList.Ids[2]); + checkTypeReferences(11, Array.ElementType, Array.IndexType); + checkTypeReferences(12, Class.FieldList, Class.DerivationList, + Class.VTableShape); + checkTypeReferences(13, Union.FieldList); + checkTypeReferences(14, Enum.FieldList, Enum.UnderlyingType); + checkTypeReferences(15, BitField.Type); + checkTypeReferences(16, VFTable.CompleteClass, VFTable.OverriddenVFTable); + checkTypeReferences(17); + checkTypeReferences(18, MethodOverloadList.T1, MethodOverloadList.T2, + MethodOverloadList.T3, MethodOverloadList.T4); + checkTypeReferences(19, Pointer.ReferentType); + checkTypeReferences(20, MemberPointer.ReferentType, + MemberPointer.MemberInfo->ContainingType); +} + +TEST_F(TypeIndexIteratorTest, FieldListBaseClass) { + using namespace members; + writeFieldList(BaseClass); + checkTypeReferences(0, BaseClass.Type); +} + +TEST_F(TypeIndexIteratorTest, FieldListEnumerator) { + using namespace members; + writeFieldList(Enumerator); + checkTypeReferences(0); +} + +TEST_F(TypeIndexIteratorTest, FieldListMember) { + using namespace members; + writeFieldList(DataMember); + checkTypeReferences(0, DataMember.Type); +} + +TEST_F(TypeIndexIteratorTest, FieldListMethod) { + using namespace members; + writeFieldList(OverloadedMethod); + checkTypeReferences(0, OverloadedMethod.MethodList); +} + +TEST_F(TypeIndexIteratorTest, FieldListOneMethod) { + using namespace members; + writeFieldList(OneMethod.R1, OneMethod.R2, OneMethod.R3, OneMethod.R4); + checkTypeReferences(0, OneMethod.T1, OneMethod.T2, OneMethod.T3, + OneMethod.T4); +} + +TEST_F(TypeIndexIteratorTest, FieldListNestedType) { + using namespace members; + writeFieldList(NestedType); + checkTypeReferences(0, NestedType.Type); +} + +TEST_F(TypeIndexIteratorTest, FieldListStaticMember) { + using namespace members; + writeFieldList(StaticDataMember); + checkTypeReferences(0, StaticDataMember.Type); +} + +TEST_F(TypeIndexIteratorTest, FieldListVirtualBase) { + using namespace members; + writeFieldList(VirtualBaseClass); + checkTypeReferences(0, VirtualBaseClass.BaseType, VirtualBaseClass.VBPtrType); +} + +TEST_F(TypeIndexIteratorTest, FieldListVFTable) { + using namespace members; + writeFieldList(VFPtr); + checkTypeReferences(0, VFPtr.Type); +} + +TEST_F(TypeIndexIteratorTest, FieldListContinuation) { + using namespace members; + writeFieldList(Continuation); + checkTypeReferences(0, Continuation.ContinuationIndex); +} + +TEST_F(TypeIndexIteratorTest, ManyMembers) { + using namespace members; + writeFieldList(BaseClass, Enumerator, DataMember, OverloadedMethod, + OneMethod.R1, OneMethod.R2, OneMethod.R3, OneMethod.R4, + NestedType, StaticDataMember, VirtualBaseClass, VFPtr, + Continuation); + + checkTypeReferences( + 0, BaseClass.Type, DataMember.Type, OverloadedMethod.MethodList, + OneMethod.T1, OneMethod.T2, OneMethod.T3, OneMethod.T4, NestedType.Type, + StaticDataMember.Type, VirtualBaseClass.BaseType, + VirtualBaseClass.VBPtrType, VFPtr.Type, Continuation.ContinuationIndex); +} + +TEST_F(TypeIndexIteratorTest, ProcSym) { + ProcSym GS(SymbolRecordKind::GlobalProcSym); + GS.FunctionType = TypeIndex::Float32(); + ProcSym LS(SymbolRecordKind::ProcSym); + LS.FunctionType = TypeIndex::Float64(); + writeSymbolRecords(GS, LS); + checkTypeReferences(0, GS.FunctionType); + checkTypeReferences(1, LS.FunctionType); +} + +TEST_F(TypeIndexIteratorTest, DataSym) { + DataSym DS(SymbolRecordKind::GlobalData); + DS.Type = TypeIndex::Float32(); + writeSymbolRecords(DS); + checkTypeReferences(0, DS.Type); +} + +TEST_F(TypeIndexIteratorTest, RegisterSym) { + RegisterSym Reg(SymbolRecordKind::RegisterSym); + Reg.Index = TypeIndex::UInt32(); + Reg.Register = RegisterId::EAX; + Reg.Name = "Target"; + writeSymbolRecords(Reg); + checkTypeReferences(0, Reg.Index); +} + +TEST_F(TypeIndexIteratorTest, CallerSym) { + CallerSym Callees(SymbolRecordKind::CalleeSym); + Callees.Indices.push_back(TypeIndex(1)); + Callees.Indices.push_back(TypeIndex(2)); + Callees.Indices.push_back(TypeIndex(3)); + CallerSym Callers(SymbolRecordKind::CallerSym); + Callers.Indices.push_back(TypeIndex(4)); + Callers.Indices.push_back(TypeIndex(5)); + Callers.Indices.push_back(TypeIndex(6)); + CallerSym Inlinees(SymbolRecordKind::InlineesSym); + Inlinees.Indices.push_back(TypeIndex(7)); + Inlinees.Indices.push_back(TypeIndex(8)); + Inlinees.Indices.push_back(TypeIndex(9)); + writeSymbolRecords(Callees, Callers, Inlinees); + checkTypeReferences(0, TypeIndex(1), TypeIndex(2), TypeIndex(3)); + checkTypeReferences(1, TypeIndex(4), TypeIndex(5), TypeIndex(6)); + checkTypeReferences(2, TypeIndex(7), TypeIndex(8), TypeIndex(9)); +} + +TEST_F(TypeIndexIteratorTest, Precomp) { + PrecompRecord P(TypeRecordKind::Precomp); + P.StartTypeIndex = TypeIndex::FirstNonSimpleIndex; + P.TypesCount = 100; + P.Signature = 0x12345678; + P.PrecompFilePath = "C:/precomp.obj"; + + EndPrecompRecord EP(TypeRecordKind::EndPrecomp); + EP.Signature = P.Signature; + + writeTypeRecords(P, EP); + checkTypeReferences(0); +} |

