29#include <gmock/gmock.h>
30#include <gtest/gtest-spi.h>
31#include <gtest/gtest.h>
34#include <initializer_list>
56 ss <<
" symbols' bindings do not match: seen `" <<
57 (int)symbol.
binding() <<
"`, expected `" <<
62 ss <<
" symbols' types do not match: seen `" <<
63 (int)symbol.
type() <<
"`, expected `" <<
68 ss <<
" symbols' names do not match: seen `" << symbol.
name() <<
69 "`, expected `" <<
expected.name() <<
"`.\n";
73 ss <<
" symbols' addresses do not match: seen `" <<
90::testing::AssertionResult
96 return ::testing::AssertionFailure() <<
"Symbols do not match (" <<
97 m_symbol <<
" != " << m_expected <<
")\n" <<
error;
99 return ::testing::AssertionSuccess();
109::testing::AssertionResult
111 const std::initializer_list<loader::Symbol>&
expected)
114 return ::testing::AssertionFailure() <<
"the number of symbols in "
115 "the table does not match expectation (seen " <<
116 (symtab.
end() - symtab.
begin()) <<
", expected " <<
121 auto it = symtab.
begin();
122 for (
const auto& symbol :
expected) {
124 if (!
error.empty()) {
125 return ::testing::AssertionFailure() <<
error;
129 return ::testing::AssertionSuccess();
133TEST(LoaderSymtabTest, EmptyConstruction)
136 ASSERT_TRUE(symtab.
empty());
141TEST(LoaderSymtabTest, InsertSymbolNoName)
146 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
148 ASSERT_FALSE(symtab.
insert(symbol));
153TEST(LoaderSymtabTest, InsertOneSymbol)
158 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
160 ASSERT_TRUE(symtab.
insert(symbol));
162 ASSERT_FALSE(symtab.
empty());
167TEST(LoaderSymtabTest, InsertSymbolExistingName)
171 const std::string
name =
"symbol";
173 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
175 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
178 ASSERT_TRUE(symtab.
insert(symbols[0]));
179 ASSERT_FALSE(symtab.
insert(symbols[1]));
182 ASSERT_TRUE(
checkTable(symtab, {symbols[0]}));
186TEST(LoaderSymtabTest, InsertSymbolExistingAddress)
192 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
194 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
197 ASSERT_TRUE(symtab.
insert(symbols[0]));
198 ASSERT_TRUE(symtab.
insert(symbols[1]));
201 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1]}));
205TEST(LoaderSymtabTest, InsertMultipleSymbols)
210 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
212 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
214 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
217 EXPECT_TRUE(symtab.
insert(symbols[0]));
218 EXPECT_TRUE(symtab.
insert(symbols[1]));
219 EXPECT_TRUE(symtab.
insert(symbols[2]));
221 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2]}));
227TEST(LoaderSymtabTest, ClearMultiple)
232 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
234 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
236 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
239 EXPECT_TRUE(symtab.
insert(symbols[0]));
240 EXPECT_TRUE(symtab.
insert(symbols[1]));
241 EXPECT_TRUE(symtab.
insert(symbols[2]));
244 ASSERT_TRUE(symtab.
empty());
257 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
259 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
261 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
264 EXPECT_TRUE(symtab.
insert(symbols[0]));
265 EXPECT_TRUE(symtab.
insert(symbols[1]));
266 EXPECT_TRUE(symtab.
insert(symbols[2]));
272 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2]}));
283 ASSERT_TRUE(
checkTable(*symtab_new, {expected_symbols[0],
284 expected_symbols[1], expected_symbols[2]}));
296 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
298 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
300 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
302 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
305 EXPECT_TRUE(symtab.
insert(symbols[0]));
306 EXPECT_TRUE(symtab.
insert(symbols[1]));
307 EXPECT_TRUE(symtab.
insert(symbols[2]));
308 EXPECT_TRUE(symtab.
insert(symbols[3]));
311 const auto symtab_new = symtab.
mask(
mask);
314 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
328 ASSERT_TRUE(
checkTable(*symtab_new, {expected_symbols[0],
329 expected_symbols[1], expected_symbols[2], expected_symbols[3]}));
341 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
343 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
345 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
347 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
350 EXPECT_TRUE(symtab.
insert(symbols[0]));
351 EXPECT_TRUE(symtab.
insert(symbols[1]));
352 EXPECT_TRUE(symtab.
insert(symbols[2]));
353 EXPECT_TRUE(symtab.
insert(symbols[3]));
355 const auto symtab_new =
356 symtab.
rename([](
const std::string &
name) {
return name +
"_suffix"; });
359 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
364 {symbols[0].
binding(), symbols[0].
type(), symbols[0].
name() +
"_suffix",
366 {symbols[1].
binding(), symbols[1].
type(), symbols[1].
name() +
"_suffix",
368 {symbols[2].
binding(), symbols[2].
type(), symbols[2].
name() +
"_suffix",
370 {symbols[3].
binding(), symbols[3].
type(), symbols[3].
name() +
"_suffix",
373 ASSERT_TRUE(
checkTable(*symtab_new, {expected_symbols[0],
374 expected_symbols[1], expected_symbols[2], expected_symbols[3]}));
381TEST(LoaderSymtabTest, RenameNonUnique)
386 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
388 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
390 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
392 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
395 EXPECT_TRUE(symtab.
insert(symbols[0]));
396 EXPECT_TRUE(symtab.
insert(symbols[1]));
397 EXPECT_TRUE(symtab.
insert(symbols[2]));
398 EXPECT_TRUE(symtab.
insert(symbols[3]));
401 const auto symtab_new = symtab.
rename([&
i](
const std::string &
name)
403 if ((
i++ % 2) == 0) {
404 return std::string(
"NonUniqueName");
411 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
417 {symbols[0].
binding(), symbols[0].
type(),
"NonUniqueName",
424 ASSERT_TRUE(
checkTable(*symtab_new, {expected_symbols[0],
425 expected_symbols[1], expected_symbols[2]}));
437 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
439 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Other,
441 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
443 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
445 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
448 EXPECT_TRUE(symtab.
insert(symbols[0]));
449 EXPECT_TRUE(symtab.
insert(symbols[1]));
450 EXPECT_TRUE(symtab.
insert(symbols[2]));
451 EXPECT_TRUE(symtab.
insert(symbols[3]));
452 EXPECT_TRUE(symtab.
insert(symbols[4]));
454 const auto symtab_new = symtab.
globals();
457 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
458 symbols[3], symbols[4]}));
461 ASSERT_TRUE(
checkTable(*symtab_new, {symbols[1]}));
473 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
475 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Other,
477 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
479 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
481 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
484 EXPECT_TRUE(symtab.
insert(symbols[0]));
485 EXPECT_TRUE(symtab.
insert(symbols[1]));
486 EXPECT_TRUE(symtab.
insert(symbols[2]));
487 EXPECT_TRUE(symtab.
insert(symbols[3]));
488 EXPECT_TRUE(symtab.
insert(symbols[4]));
490 const auto symtab_new = symtab.
locals();
493 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
494 symbols[3], symbols[4]}));
497 ASSERT_TRUE(
checkTable(*symtab_new, {symbols[0], symbols[2]}));
509 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
511 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Other,
513 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
515 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
517 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
520 EXPECT_TRUE(symtab.
insert(symbols[0]));
521 EXPECT_TRUE(symtab.
insert(symbols[1]));
522 EXPECT_TRUE(symtab.
insert(symbols[2]));
523 EXPECT_TRUE(symtab.
insert(symbols[3]));
524 EXPECT_TRUE(symtab.
insert(symbols[4]));
526 const auto symtab_new = symtab.
weaks();
529 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
530 symbols[3], symbols[4]}));
533 ASSERT_TRUE(
checkTable(*symtab_new, {symbols[3], symbols[4]}));
540TEST(LoaderSymtabTest, FunctionSymbols)
545 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::NoType,
547 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::File,
549 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Function,
551 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Object,
553 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Function,
556 EXPECT_TRUE(symtab.
insert(symbols[0]));
557 EXPECT_TRUE(symtab.
insert(symbols[1]));
558 EXPECT_TRUE(symtab.
insert(symbols[2]));
559 EXPECT_TRUE(symtab.
insert(symbols[3]));
560 EXPECT_TRUE(symtab.
insert(symbols[4]));
565 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
566 symbols[3], symbols[4]}));
569 ASSERT_TRUE(
checkTable(*symtab_new, {symbols[2], symbols[4]}));
573TEST(LoaderSymtabTest, FindNonExistentAddress)
578 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
580 EXPECT_TRUE(symtab.
insert(symbol));
582 ASSERT_EQ(symtab.
find(0x0), symtab.
end());
586TEST(LoaderSymtabTest, FindUniqueAddress)
591 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
593 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
595 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
598 EXPECT_TRUE(symtab.
insert(symbols[0]));
599 EXPECT_TRUE(symtab.
insert(symbols[1]));
600 EXPECT_TRUE(symtab.
insert(symbols[2]));
602 const auto it = symtab.
find(symbols[2].address());
603 ASSERT_NE(it, symtab.
end());
610TEST(LoaderSymtabTest, FindNonUniqueAddress)
616 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
618 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
620 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
623 EXPECT_TRUE(symtab.
insert(symbols[0]));
624 EXPECT_TRUE(symtab.
insert(symbols[1]));
625 EXPECT_TRUE(symtab.
insert(symbols[2]));
627 const auto it = symtab.
find(symbols[1].address());
628 ASSERT_NE(it, symtab.
end());
633TEST(LoaderSymtabTest, FindNonExistentName)
638 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
640 EXPECT_TRUE(symtab.
insert(symbol));
642 const auto it = symtab.
find(
"symbol2");
643 ASSERT_EQ(it, symtab.
end());
647TEST(LoaderSymtabTest, FindExistingName)
652 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
654 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
656 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
659 EXPECT_TRUE(symtab.
insert(symbols[0]));
660 EXPECT_TRUE(symtab.
insert(symbols[1]));
661 EXPECT_TRUE(symtab.
insert(symbols[2]));
663 const auto it = symtab.
find(symbols[1].
name());
664 ASSERT_NE(it, symtab.
end());
669TEST(LoaderSymtabTest, FindNearestExact)
674 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
676 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
679 EXPECT_TRUE(symtab.
insert(symbols[0]));
680 EXPECT_TRUE(symtab.
insert(symbols[1]));
682 const auto it = symtab.
findNearest(symbols[1].address());
683 ASSERT_NE(it, symtab.
end());
691TEST(LoaderSymtabTest, FindNearestRound)
696 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
698 EXPECT_TRUE(symtab.
insert(symbol));
701 ASSERT_NE(it, symtab.
end());
710TEST(LoaderSymtabTest, FindNearestRoundWithNext)
715 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
717 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
720 EXPECT_TRUE(symtab.
insert(symbols[0]));
721 EXPECT_TRUE(symtab.
insert(symbols[1]));
724 const auto it = symtab.
findNearest(symbols[0].address() + 0x1, next_addr);
725 ASSERT_NE(it, symtab.
end());
727 ASSERT_EQ(next_addr, symbols[1].address());
735TEST(LoaderSymtabTest, FindNearestRoundWithNextNonExistent)
740 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
742 EXPECT_TRUE(symtab.
insert(symbol));
746 ASSERT_NE(it, symtab.
end());
748 ASSERT_EQ(next_addr, 0);
755TEST(LoaderSymtabTest, FindNearestNonExistent)
760 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
762 EXPECT_TRUE(symtab.
insert(symbol));
765 ASSERT_EQ(it, symtab.
end());
772TEST(LoaderSymtabTest, InsertTableConflicting)
774 const std::string
name =
"symbol";
776 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
778 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
780 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
782 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
785 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
791 EXPECT_TRUE(symtab.
insert(symbols[0]));
792 EXPECT_TRUE(symtab.
insert(symbols[1]));
793 EXPECT_TRUE(symtab.
insert(symbols[2]));
797 EXPECT_TRUE(symtab2.
insert(symbols[3]));
798 EXPECT_TRUE(symtab2.
insert(symbols[4]));
801 ASSERT_FALSE(symtab.
insert(symtab2));
804 ASSERT_TRUE(
checkTable(symtab2, {symbols[3], symbols[4]}));
805 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2]}));
812TEST(LoaderSymtabTest, InsertTable)
815 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
817 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
819 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
821 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
823 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
829 EXPECT_TRUE(symtab.
insert(symbols[0]));
830 EXPECT_TRUE(symtab.
insert(symbols[1]));
831 EXPECT_TRUE(symtab.
insert(symbols[2]));
835 EXPECT_TRUE(symtab2.
insert(symbols[3]));
836 EXPECT_TRUE(symtab2.
insert(symbols[4]));
842 ASSERT_TRUE(
checkTable(symtab2, {symbols[3], symbols[4]}));
845 ASSERT_TRUE(
checkTable(symtab, {symbols[0], symbols[1], symbols[2],
846 symbols[3], symbols[4]}));
857 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
859 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
861 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
864 EXPECT_TRUE(symtab.
insert(symbols[0]));
865 EXPECT_TRUE(symtab.
insert(symbols[1]));
866 EXPECT_TRUE(symtab.
insert(symbols[2]));
869 std::ostringstream cp;
874 ASSERT_THAT(cp.str(), ::testing::StrEq(
"\n[Section1]\ntest.size=3\n"
875 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
877 "test.addr_1=32\ntest.symbol_1=symbol2\ntest.binding_1=1\n"
879 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n"
887 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
889 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
891 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
894 simulateSerialization(
"\n[Section1]\ntest.size=3\n"
895 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
897 "test.addr_1=32\ntest.symbol_1=symbol2\ntest.binding_1=1\n"
899 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n"
909 ASSERT_TRUE(
checkTable(unserialized_symtab, {symbols[0], symbols[1],
921 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
923 {loader::Symbol::Binding::Global, loader::Symbol::SymbolType::Other,
925 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
928 simulateSerialization(
"\n[Section1]\ntest.size=3\n"
929 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
931 "test.addr_1=32\ntest.symbol_1=symbol2\ntest.type_1=5\n"
932 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n"
943 ASSERT_TRUE(
checkTable(unserialized_symtab, {symbols[0], symbols[1],
953 UnserializationMissingBindingChangeDefault)
956 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
958 {loader::Symbol::Binding::Weak, loader::Symbol::SymbolType::Other,
960 {loader::Symbol::Binding::Local, loader::Symbol::SymbolType::Other,
963 simulateSerialization(
"\n[Section1]\ntest.size=3\n"
964 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
966 "test.addr_1=32\ntest.symbol_1=symbol2\n"
968 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n"
976 loader::Symbol::Binding::Weak);
980 ASSERT_TRUE(
checkTable(unserialized_symtab, {symbols[0], symbols[1],
Container for serializing global variables (not associated with any serialized object).
Fixture class that handles temporary directory creation.
SymbolTablePtr functionSymbols() const
Generates a new symbol table containing only function symbols.
SymbolTablePtr locals() const
Generates a new symbol table containing only local symbols.
SymbolTablePtr weaks() const
Generates a new symbol table containing only weak symbols.
bool empty() const
Verifies whether the table is empty.
SymbolTablePtr globals() const
Generates a new symbol table containing only global symbols.
SymbolTablePtr rename(std::function< std::string(const std::string &)> func) const
Modify the symbols' name with a given transform function.
void clear()
Clears the table.
const_iterator end() const
void unserialize(const std::string &base, CheckpointIn &cp, Symbol::Binding default_binding=Symbol::Binding::Global)
Populate the table by unserializing a checkpoint.
const_iterator begin() const
const_iterator findNearest(Addr addr, Addr &next_addr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
SymbolTablePtr mask(Addr m) const
Generate a new table by a mask to the symbols of the current table.
SymbolTablePtr offset(Addr addr_offset) const
Generate a new table by applying an offset to the symbols of the current table.
void serialize(const std::string &base, CheckpointOut &cp) const
Serialize the table's contents.
bool insert(const Symbol &symbol)
Insert a new symbol in the table if it does not already exist.
const_iterator find(Addr address) const
Search for a symbol by its address.
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string getSymbolError(const loader::Symbol &symbol, const loader::Symbol &expected)
Checks if a symbol's contents matches the expected contents to generate an error message.
::testing::AssertionResult checkSymbol(const char *m_symbol, const char *m_expected, const loader::Symbol &symbol, const loader::Symbol &expected)
Checks that a symbol's contents matches the expected contents.
TEST_F(LoaderSymtabSerializationFixture, Serialization)
Test serialization.
::testing::AssertionResult checkTable(const loader::SymbolTable &symtab, const std::initializer_list< loader::Symbol > &expected)
Checks that a symbol table contains only the expected symbols.
TEST(LoaderSymtabTest, EmptyConstruction)
Test that the constructor creates an empty table.
const std::string & name()