1 //===- StringTableBuilderTest.cpp -----------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" 10 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" 11 #include "llvm/Support/BinaryByteStream.h" 12 #include "llvm/Support/BinaryStreamReader.h" 13 #include "llvm/Support/BinaryStreamWriter.h" 14 #include "llvm/Testing/Support/Error.h" 15 16 #include "gtest/gtest.h" 17 18 using namespace llvm; 19 using namespace llvm::pdb; 20 using namespace llvm::support; 21 22 TEST(StringTableBuilderTest, Simple) { 23 // Create /names table contents. 24 PDBStringTableBuilder Builder; 25 26 // This test case is carefully constructed to ensure that at least one 27 // string gets bucketed into slot 0, *and* to ensure that at least one 28 // has a hash collision at the end of the bucket list so it has to 29 // wrap around. 30 uint32_t FooID = Builder.insert("foo"); 31 uint32_t BarID = Builder.insert("bar"); 32 uint32_t BazID = Builder.insert("baz"); 33 uint32_t BuzzID = Builder.insert("buzz"); 34 uint32_t BazzID = Builder.insert("bazz"); 35 uint32_t BarrID = Builder.insert("barr"); 36 37 // Re-inserting the same item should return the same id. 38 EXPECT_EQ(FooID, Builder.insert("foo")); 39 EXPECT_EQ(BarID, Builder.insert("bar")); 40 EXPECT_EQ(BazID, Builder.insert("baz")); 41 EXPECT_EQ(BuzzID, Builder.insert("buzz")); 42 EXPECT_EQ(BazzID, Builder.insert("bazz")); 43 EXPECT_EQ(BarrID, Builder.insert("barr")); 44 45 // Each ID should be distinct. 46 std::set<uint32_t> Distinct{FooID, BarID, BazID, BuzzID, BazzID, BarrID}; 47 EXPECT_EQ(6U, Distinct.size()); 48 49 std::vector<uint8_t> Buffer(Builder.calculateSerializedSize()); 50 MutableBinaryByteStream OutStream(Buffer, little); 51 BinaryStreamWriter Writer(OutStream); 52 EXPECT_THAT_ERROR(Builder.commit(Writer), Succeeded()); 53 54 // Reads the contents back. 55 BinaryByteStream InStream(Buffer, little); 56 BinaryStreamReader Reader(InStream); 57 PDBStringTable Table; 58 EXPECT_THAT_ERROR(Table.reload(Reader), Succeeded()); 59 60 EXPECT_EQ(6U, Table.getNameCount()); 61 EXPECT_EQ(1U, Table.getHashVersion()); 62 63 EXPECT_THAT_EXPECTED(Table.getStringForID(FooID), HasValue("foo")); 64 EXPECT_THAT_EXPECTED(Table.getStringForID(BarID), HasValue("bar")); 65 EXPECT_THAT_EXPECTED(Table.getStringForID(BazID), HasValue("baz")); 66 EXPECT_THAT_EXPECTED(Table.getStringForID(BuzzID), HasValue("buzz")); 67 EXPECT_THAT_EXPECTED(Table.getStringForID(BazzID), HasValue("bazz")); 68 EXPECT_THAT_EXPECTED(Table.getStringForID(BarrID), HasValue("barr")); 69 70 EXPECT_THAT_EXPECTED(Table.getIDForString("foo"), HasValue(FooID)); 71 EXPECT_THAT_EXPECTED(Table.getIDForString("bar"), HasValue(BarID)); 72 EXPECT_THAT_EXPECTED(Table.getIDForString("baz"), HasValue(BazID)); 73 EXPECT_THAT_EXPECTED(Table.getIDForString("buzz"), HasValue(BuzzID)); 74 EXPECT_THAT_EXPECTED(Table.getIDForString("bazz"), HasValue(BazzID)); 75 EXPECT_THAT_EXPECTED(Table.getIDForString("barr"), HasValue(BarrID)); 76 } 77 78 TEST(StringTableHashTraitsTest, Simple) { 79 PDBStringTableBuilder Builder; 80 81 // Create more than 64kiB of dummy entries. 82 for (int i = 0; i < 320; ++i) { 83 std::string aaaaa = std::string(220, 'a') + std::to_string(i); 84 Builder.insert(aaaaa); 85 } 86 87 std::string S = "foo.natvis"; 88 uint32_t Pos = Builder.insert(S); 89 90 EXPECT_GT(Pos, 0xFFFFu); 91 92 StringTableHashTraits Traits(Builder); 93 EXPECT_LE(Traits.hashLookupKey(S), 0xFFFFu); 94 } 95