//===- NamePoolTest.cpp ---------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "NamePoolTest.h" #include <mcld/LD/NamePool.h> #include <mcld/LD/Resolver.h> #include <mcld/LD/StaticResolver.h> #include <mcld/LD/ResolveInfo.h> #include <mcld/LD/LDSymbol.h> #include <llvm/ADT/StringRef.h> #include <string> #include <cstdio> using namespace mcld; using namespace mcldtest; // Constructor can do set-up work for all test here. NamePoolTest::NamePoolTest() { // create testee. modify it if need StaticResolver resolver; m_pTestee = new NamePool(resolver, 10); } // Destructor can do clean-up work that doesn't throw exceptions here. NamePoolTest::~NamePoolTest() { delete m_pTestee; } // SetUp() will be called immediately before each test. void NamePoolTest::SetUp() { } // TearDown() will be called immediately after each test. void NamePoolTest::TearDown() { } //==========================================================================// // Testcases // TEST_F( NamePoolTest, insertString ) { const char *s1 = "Hello MCLinker"; llvm::StringRef result1 = m_pTestee->insertString(s1); EXPECT_NE(s1, result1.data()); EXPECT_STREQ(s1, result1.data()); } TEST_F( NamePoolTest, insertSameString ) { const char *s1 = "Hello MCLinker"; std::string s2(s1); llvm::StringRef result1 = m_pTestee->insertString(s1); llvm::StringRef result2 = m_pTestee->insertString(s2.c_str()); EXPECT_STREQ(s1, result1.data()); EXPECT_STREQ(s2.c_str(), result2.data()); EXPECT_EQ(result1.data(), result2.data()); } TEST_F( NamePoolTest, insert_local_defined_Symbol ) { const char *name = "Hello MCLinker"; bool isDyn = false; ResolveInfo::Type type = ResolveInfo::Function; ResolveInfo::Desc desc = ResolveInfo::Define; ResolveInfo::Binding binding = ResolveInfo::Local; uint64_t value = 0; uint64_t size = 0; ResolveInfo::Visibility other = ResolveInfo::Default; Resolver::Result result1; m_pTestee->insertSymbol(name, isDyn, type, desc, binding, size, other, NULL, result1); EXPECT_NE(name, result1.info->name()); EXPECT_STREQ(name, result1.info->name()); EXPECT_EQ(isDyn, result1.info->isDyn()); EXPECT_EQ(type, result1.info->type()); EXPECT_EQ(desc, result1.info->desc()); EXPECT_EQ(binding, result1.info->binding()); EXPECT_EQ(size, result1.info->size()); EXPECT_EQ(other, result1.info->visibility()); Resolver::Result result2; m_pTestee->insertSymbol(name, isDyn, type, desc, binding, size, other, NULL, result2); EXPECT_NE(name, result1.info->name()); EXPECT_STREQ(name, result1.info->name()); EXPECT_EQ(isDyn, result1.info->isDyn()); EXPECT_EQ(type, result1.info->type()); EXPECT_EQ(desc, result1.info->desc()); EXPECT_EQ(binding, result1.info->binding()); EXPECT_EQ(size, result1.info->size()); EXPECT_EQ(other, result1.info->visibility()); EXPECT_NE(result1.existent, result2.existent); } TEST_F( NamePoolTest, insert_global_reference_Symbol ) { const char *name = "Hello MCLinker"; bool isDyn = false; ResolveInfo::Type type = ResolveInfo::NoType; ResolveInfo::Desc desc = ResolveInfo::Undefined; ResolveInfo::Binding binding = ResolveInfo::Global; uint64_t size = 0; ResolveInfo::Visibility other = ResolveInfo::Default; Resolver::Result result1; m_pTestee->insertSymbol(name, isDyn, type, desc, binding, size, other, NULL, result1); EXPECT_NE(name, result1.info->name()); EXPECT_STREQ(name, result1.info->name()); EXPECT_EQ(isDyn, result1.info->isDyn()); EXPECT_EQ(type, result1.info->type()); EXPECT_EQ(desc, result1.info->desc()); EXPECT_EQ(binding, result1.info->binding()); EXPECT_EQ(size, result1.info->size()); EXPECT_EQ(other, result1.info->visibility()); Resolver::Result result2; m_pTestee->insertSymbol(name, isDyn, type, desc, binding, size, other, NULL, result2); EXPECT_EQ(result1.info, result2.info); Resolver::Result result3; m_pTestee->insertSymbol("Different Symbol", isDyn, type, desc, binding, size, other, NULL, result3); EXPECT_NE(result1.info, result3.info); } TEST_F( NamePoolTest, insertSymbol_after_insert_same_string ) { const char *name = "Hello MCLinker"; bool isDyn = false; LDSymbol::Type type = LDSymbol::Defined; LDSymbol::Binding binding = LDSymbol::Global; const llvm::MCSectionData *section = 0; uint64_t value = 0; uint64_t size = 0; uint8_t other = 0; const char *result1 = m_pTestee->insertString(name); LDSymbol *sym = m_pTestee->insertSymbol(name, isDyn, type, binding, section, value, size, other); EXPECT_STREQ(name, sym->name()); EXPECT_EQ(result1, sym->name()); char s[16]; strcpy(s, result1); const char *result2 = m_pTestee->insertString(result1); const char *result3 = m_pTestee->insertString(s); EXPECT_EQ(result1, result2); EXPECT_EQ(result1, result3); } TEST_F( NamePoolTest, insert_16384_weak_reference_symbols ) { char name[16]; bool isDyn = false; LDSymbol::Type type = LDSymbol::Reference; LDSymbol::Binding binding = LDSymbol::Weak; const llvm::MCSectionData *section = 0; uint64_t value = 0; uint64_t size = 0; uint8_t other = 0; strcpy(name, "Hello MCLinker"); LDSymbol *syms[128][128]; for(int i=0; i<128 ;++i) { name[0] = i; for(int j=0; j<128 ;++j) { name[1] = j; syms[i][j] = m_pTestee->insertSymbol(name, isDyn, type, binding, section, value, size, other); ASSERT_STREQ(name, syms[i][j]->name()); } } for(int i=127; i>=0 ;--i) { name[0] = i; for(int j=0; j<128 ;++j) { name[1] = j; LDSymbol *sym = m_pTestee->insertSymbol(name, isDyn, type, binding, section, value, size, other); ASSERT_EQ(sym, syms[i][j]); } } for(int i=0; i<128 ;++i) { name[0] = i; for(int j=0; j<128 ;++j) { name[1] = j; LDSymbol *sym = m_pTestee->insertSymbol(name, isDyn, type, binding, section, value, size, other); ASSERT_EQ(sym, syms[i][j]); } } }