diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-26 20:32:52 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-26 20:32:52 +0000 |
| commit | 08bbd35a80bf7765fe0d3043f9eb5a2f2786b649 (patch) | |
| tree | 80108f0f128657f8623f8f66ad9735b4d88e7b47 /unittests/DebugInfo | |
| parent | 7c7aba6e5fef47a01a136be655b0a92cfd7090f6 (diff) | |
Notes
Diffstat (limited to 'unittests/DebugInfo')
| -rw-r--r-- | unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp | 52 | ||||
| -rw-r--r-- | unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp | 87 | ||||
| -rw-r--r-- | unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp | 29 | ||||
| -rw-r--r-- | unittests/DebugInfo/PDB/PDBApiTest.cpp | 4 |
4 files changed, 151 insertions, 21 deletions
diff --git a/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp b/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp index 4fa172a37ef2..92134513b75b 100644 --- a/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp +++ b/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp @@ -351,3 +351,55 @@ TEST_F(RandomAccessVisitorTest, InnerChunk) { for (auto &I : enumerate(IndicesToVisit)) EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value())); } + +TEST_F(RandomAccessVisitorTest, CrossChunkName) { + TypeTableBuilder Builder(GlobalState->Allocator); + + // TypeIndex 0 + ClassRecord Class(TypeRecordKind::Class); + Class.Name = "FooClass"; + Class.Options = ClassOptions::None; + Class.MemberCount = 0; + Class.Size = 4U; + Class.DerivationList = TypeIndex::fromArrayIndex(0); + Class.FieldList = TypeIndex::fromArrayIndex(0); + Class.VTableShape = TypeIndex::fromArrayIndex(0); + TypeIndex IndexZero = Builder.writeKnownType(Class); + + // TypeIndex 1 refers to type index 0. + ModifierRecord Modifier(TypeRecordKind::Modifier); + Modifier.ModifiedType = TypeIndex::fromArrayIndex(0); + Modifier.Modifiers = ModifierOptions::Const; + TypeIndex IndexOne = Builder.writeKnownType(Modifier); + + // set up a type stream that refers to the above two serialized records. + std::vector<CVType> TypeArray; + TypeArray.push_back( + CVType(static_cast<TypeLeafKind>(Class.Kind), Builder.records()[0])); + TypeArray.push_back( + CVType(static_cast<TypeLeafKind>(Modifier.Kind), Builder.records()[1])); + BinaryItemStream<CVType> ItemStream(llvm::support::little); + ItemStream.setItems(TypeArray); + VarStreamArray<CVType> TypeStream(ItemStream); + + // Figure out the byte offset of the second item. + auto ItemOneIter = TypeStream.begin(); + ++ItemOneIter; + + // Set up a partial offsets buffer that contains the first and second items + // in separate chunks. + std::vector<TypeIndexOffset> TIO; + TIO.push_back({IndexZero, ulittle32_t(0u)}); + TIO.push_back({IndexOne, ulittle32_t(ItemOneIter.offset())}); + ArrayRef<uint8_t> Buffer(reinterpret_cast<const uint8_t *>(TIO.data()), + TIO.size() * sizeof(TypeIndexOffset)); + + BinaryStreamReader Reader(Buffer, llvm::support::little); + FixedStreamArray<TypeIndexOffset> PartialOffsets; + ASSERT_THAT_ERROR(Reader.readArray(PartialOffsets, 2), Succeeded()); + + LazyRandomTypeCollection Types(TypeStream, 2, PartialOffsets); + + StringRef Name = Types.getTypeName(IndexOne); + EXPECT_EQ("const FooClass", Name); +}
\ No newline at end of file diff --git a/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp index 99c84906be9c..fa9e96123184 100644 --- a/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp +++ b/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp @@ -10,6 +10,7 @@ #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/SymbolSerializer.h" #include "llvm/Support/Allocator.h" #include "gmock/gmock.h" @@ -26,6 +27,7 @@ public: Refs.clear(); TTB = make_unique<TypeTableBuilder>(Storage); FLRB = make_unique<FieldListRecordBuilder>(*TTB); + Symbols.clear(); } void TearDown() override { @@ -37,7 +39,19 @@ protected: template <typename... Indices> bool checkTypeReferences(uint32_t RecordIndex, Indices &&... TIs) const { EXPECT_EQ(sizeof...(Indices), countRefs(RecordIndex)); - return checkTypeReferencesImpl(RecordIndex, std::forward<Indices>(TIs)...); + + // 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) { @@ -54,6 +68,13 @@ protected: discoverAllTypeIndices(); } + template <typename... T> void writeSymbolRecords(T &&... Records) { + writeSymbolRecordsImpl(std::forward<T>(Records)...); + ASSERT_EQ(sizeof...(T), Symbols.size()); + discoverTypeIndicesInSymbols(); + } + + std::unique_ptr<TypeTableBuilder> TTB; private: @@ -83,18 +104,20 @@ private: } template <typename... Indices> - bool checkTypeReferencesImpl(uint32_t RecordIndex) const { + bool checkTypeReferencesImpl(uint32_t RecordIndex, + ArrayRef<ArrayRef<uint8_t>> CVRecords) const { return true; } template <typename... Indices> - bool checkTypeReferencesImpl(uint32_t RecordIndex, TypeIndex TI, - Indices &&... Rest) const { - ArrayRef<uint8_t> Record = TTB->records()[RecordIndex]; + 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, std::forward<Indices>(Rest)...); + return Success & checkTypeReferencesImpl(RecordIndex, CVRecords, + std::forward<Indices>(Rest)...); } void discoverAllTypeIndices() { @@ -105,6 +128,12 @@ private: } } + void discoverTypeIndicesInSymbols() { + Refs.resize(Symbols.size()); + for (uint32_t I = 0; I < Symbols.size(); ++I) + discoverTypeIndices(Symbols[I], Refs[I]); + } + // Helper function to write out a field list record with the given list // of member records. void writeFieldListImpl() {} @@ -124,8 +153,19 @@ private: 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<FieldListRecordBuilder> FLRB; + std::vector<CVSymbol> Symbols; BumpPtrAllocator Storage; }; @@ -492,4 +532,35 @@ TEST_F(TypeIndexIteratorTest, ManyMembers) { OneMethod.T1, OneMethod.T2, OneMethod.T3, OneMethod.T4, NestedType.Type, StaticDataMember.Type, VirtualBaseClass.BaseType, VirtualBaseClass.VBPtrType, VFPtr.Type, Continuation.ContinuationIndex); -}
\ No newline at end of file +} + +TEST_F(TypeIndexIteratorTest, ProcSym) { + ProcSym GS(SymbolRecordKind::GlobalProcSym); + GS.FunctionType = TypeIndex(0x40); + ProcSym LS(SymbolRecordKind::ProcSym); + LS.FunctionType = TypeIndex(0x41); + writeSymbolRecords(GS, LS); + checkTypeReferences(0, GS.FunctionType); + checkTypeReferences(1, LS.FunctionType); +} + +TEST_F(TypeIndexIteratorTest, DataSym) { + DataSym DS(SymbolRecordKind::GlobalData); + DS.Type = TypeIndex(0x40); + writeSymbolRecords(DS); + checkTypeReferences(0, DS.Type); +} + +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)); + writeSymbolRecords(Callees, Callers); + checkTypeReferences(0, TypeIndex(1), TypeIndex(2), TypeIndex(3)); + checkTypeReferences(1, TypeIndex(4), TypeIndex(5), TypeIndex(6)); +} diff --git a/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp b/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp index da7f43e721aa..621796b684d6 100644 --- a/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp +++ b/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp @@ -23,43 +23,52 @@ namespace { TEST(DWARFFormValue, FixedFormSizes) { Optional<uint8_t> RefSize; Optional<uint8_t> AddrSize; + // Test 32 bit DWARF version 2 with 4 byte addresses. - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 4, DWARF32); - AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 4, DWARF32); + DWARFFormParams Params_2_4_32 = {2, 4, DWARF32}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_4_32); + AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_4_32); EXPECT_TRUE(RefSize.hasValue()); EXPECT_TRUE(AddrSize.hasValue()); EXPECT_EQ(*RefSize, *AddrSize); // Test 32 bit DWARF version 2 with 8 byte addresses. - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 8, DWARF32); - AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 8, DWARF32); + DWARFFormParams Params_2_8_32 = {2, 8, DWARF32}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_8_32); + AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_8_32); EXPECT_TRUE(RefSize.hasValue()); EXPECT_TRUE(AddrSize.hasValue()); EXPECT_EQ(*RefSize, *AddrSize); // DW_FORM_ref_addr is 4 bytes in DWARF 32 in DWARF version 3 and beyond. - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 3, 4, DWARF32); + DWARFFormParams Params_3_4_32 = {3, 4, DWARF32}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_3_4_32); EXPECT_TRUE(RefSize.hasValue()); EXPECT_EQ(*RefSize, 4); - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 4, 4, DWARF32); + DWARFFormParams Params_4_4_32 = {4, 4, DWARF32}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_4_4_32); EXPECT_TRUE(RefSize.hasValue()); EXPECT_EQ(*RefSize, 4); - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 5, 4, DWARF32); + DWARFFormParams Params_5_4_32 = {5, 4, DWARF32}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_5_4_32); EXPECT_TRUE(RefSize.hasValue()); EXPECT_EQ(*RefSize, 4); // DW_FORM_ref_addr is 8 bytes in DWARF 64 in DWARF version 3 and beyond. - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 3, 8, DWARF64); + DWARFFormParams Params_3_8_64 = {3, 8, DWARF64}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_3_8_64); EXPECT_TRUE(RefSize.hasValue()); EXPECT_EQ(*RefSize, 8); - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 4, 8, DWARF64); + DWARFFormParams Params_4_8_64 = {4, 8, DWARF64}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_4_8_64); EXPECT_TRUE(RefSize.hasValue()); EXPECT_EQ(*RefSize, 8); - RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 5, 8, DWARF64); + DWARFFormParams Params_5_8_64 = {5, 8, DWARF64}; + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_5_8_64); EXPECT_TRUE(RefSize.hasValue()); EXPECT_EQ(*RefSize, 8); } diff --git a/unittests/DebugInfo/PDB/PDBApiTest.cpp b/unittests/DebugInfo/PDB/PDBApiTest.cpp index 6afe83cd90dd..257a8879e439 100644 --- a/unittests/DebugInfo/PDB/PDBApiTest.cpp +++ b/unittests/DebugInfo/PDB/PDBApiTest.cpp @@ -63,9 +63,7 @@ namespace { class MockSession : public IPDBSession { uint64_t getLoadAddress() const override { return 0; } void setLoadAddress(uint64_t Address) override {} - std::unique_ptr<PDBSymbolExe> getGlobalScope() const override { - return nullptr; - } + std::unique_ptr<PDBSymbolExe> getGlobalScope() override { return nullptr; } std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override { return nullptr; } |
