…ition.
Renames the SimpleSymbolTable addSymbolsUnique method to addUnique. The
new class name (from c727cd9a4b) already implies that we're adding
symbols.
This commit also relaxes the error condition for addUnique: Rather than
rejecting any duplicate symbols, it only rejects symbols that were
previously added with a different address. This makes it safe to add the
same symbol(s) multiple time, as long as all definitions point to the
same address. The intent of this is to allow ORC runtime components to
unconditionally add their interfaces to symbols, even if that interface
might have been added previously.
157 lines
4.7 KiB
C++
157 lines
4.7 KiB
C++
//===- SimpleSymbolTableTest.cpp ------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Tests for orc-rt's SimpleSymbolTable.h APIs.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "orc-rt/SimpleSymbolTable.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <set>
|
|
#include <string>
|
|
|
|
using namespace orc_rt;
|
|
|
|
TEST(SimpleSymbolTableTest, EmptyByDefault) {
|
|
SimpleSymbolTable ST;
|
|
EXPECT_TRUE(ST.empty());
|
|
EXPECT_EQ(ST.size(), 0U);
|
|
EXPECT_EQ(ST.begin(), ST.end());
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddSymbolsUnique) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0, Y = 0;
|
|
std::pair<const char *, void *> Syms[] = {{"orc_rt_A", &X}, {"orc_rt_B", &Y}};
|
|
|
|
auto Err = ST.addUnique(Syms);
|
|
EXPECT_FALSE(Err) << "Unexpected error adding unique symbols";
|
|
|
|
EXPECT_EQ(ST.size(), 2U);
|
|
EXPECT_FALSE(ST.empty());
|
|
EXPECT_TRUE(ST.count("orc_rt_A"));
|
|
EXPECT_TRUE(ST.count("orc_rt_B"));
|
|
EXPECT_EQ(ST.at("orc_rt_A"), &X);
|
|
EXPECT_EQ(ST.at("orc_rt_B"), &Y);
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddConstPointers) {
|
|
SimpleSymbolTable ST;
|
|
const int X = 42;
|
|
const int Y = 7;
|
|
std::pair<const char *, const void *> Syms[] = {{"orc_rt_A", &X},
|
|
{"orc_rt_B", &Y}};
|
|
cantFail(ST.addUnique(Syms));
|
|
|
|
EXPECT_EQ(ST.at("orc_rt_A"), &X);
|
|
EXPECT_EQ(ST.at("orc_rt_B"), &Y);
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddSymbolsUniqueMultipleCalls) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0, Y = 0;
|
|
|
|
std::pair<const char *, void *> First[] = {{"orc_rt_A", &X}};
|
|
std::pair<const char *, void *> Second[] = {{"orc_rt_B", &Y}};
|
|
|
|
cantFail(ST.addUnique(First));
|
|
cantFail(ST.addUnique(Second));
|
|
|
|
EXPECT_EQ(ST.size(), 2U);
|
|
EXPECT_EQ(ST.at("orc_rt_A"), &X);
|
|
EXPECT_EQ(ST.at("orc_rt_B"), &Y);
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddSymbolsUniqueDuplicateRejected) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0, Y = 0;
|
|
|
|
std::pair<const char *, void *> First[] = {{"orc_rt_A", &X}};
|
|
cantFail(ST.addUnique(First));
|
|
|
|
std::pair<const char *, void *> Second[] = {{"orc_rt_A", &Y}};
|
|
auto Err = ST.addUnique(Second);
|
|
EXPECT_TRUE(Err.isA<StringError>());
|
|
|
|
auto ErrMsg = toString(std::move(Err));
|
|
EXPECT_NE(ErrMsg.find("orc_rt_A"), std::string::npos)
|
|
<< "Error message should mention the duplicate symbol name";
|
|
|
|
// Original not overwritten.
|
|
EXPECT_EQ(ST.at("orc_rt_A"), &X);
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddSymbolsUniqueMultipleDuplicates) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0, Y = 0, Z = 0;
|
|
|
|
std::pair<const char *, void *> First[] = {{"orc_rt_A", &X},
|
|
{"orc_rt_B", &Y}};
|
|
cantFail(ST.addUnique(First));
|
|
|
|
std::pair<const char *, void *> Second[] = {{"orc_rt_A", &Z},
|
|
{"orc_rt_B", &Z}};
|
|
auto Err = ST.addUnique(Second);
|
|
EXPECT_TRUE(Err.isA<StringError>());
|
|
|
|
auto ErrMsg = toString(std::move(Err));
|
|
EXPECT_NE(ErrMsg.find("orc_rt_A"), std::string::npos);
|
|
EXPECT_NE(ErrMsg.find("orc_rt_B"), std::string::npos);
|
|
|
|
// Originals not overwritten.
|
|
EXPECT_EQ(ST.at("orc_rt_A"), &X);
|
|
EXPECT_EQ(ST.at("orc_rt_B"), &Y);
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddSymbolsUniqueAllOrNothing) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0, Y = 0, Z = 0;
|
|
|
|
std::pair<const char *, void *> First[] = {{"orc_rt_existing", &X}};
|
|
cantFail(ST.addUnique(First));
|
|
|
|
// One new, one incompatible — neither should be added.
|
|
std::pair<const char *, void *> Second[] = {{"orc_rt_new", &Y},
|
|
{"orc_rt_existing", &Z}};
|
|
auto Err = ST.addUnique(Second);
|
|
EXPECT_TRUE(Err.isA<StringError>());
|
|
consumeError(std::move(Err));
|
|
|
|
EXPECT_EQ(ST.size(), 1U);
|
|
EXPECT_EQ(ST.at("orc_rt_existing"), &X);
|
|
EXPECT_FALSE(ST.count("orc_rt_new"));
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, AddUniqueSameAddressSucceeds) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0;
|
|
std::pair<const char *, void *> Syms[] = {{"orc_rt_A", &X}};
|
|
cantFail(ST.addUnique(Syms));
|
|
cantFail(ST.addUnique(Syms)); // Same name, same address — should succeed.
|
|
EXPECT_EQ(ST.size(), 1U);
|
|
EXPECT_EQ(ST.at("orc_rt_A"), &X);
|
|
}
|
|
|
|
TEST(SimpleSymbolTableTest, Iteration) {
|
|
SimpleSymbolTable ST;
|
|
int X = 0, Y = 0, Z = 0;
|
|
std::pair<const char *, void *> Syms[] = {
|
|
{"orc_rt_A", &X}, {"orc_rt_B", &Y}, {"orc_rt_C", &Z}};
|
|
cantFail(ST.addUnique(Syms));
|
|
|
|
std::set<std::string> Names;
|
|
for (auto &[Name, Addr] : ST)
|
|
Names.insert(Name);
|
|
|
|
EXPECT_EQ(Names.size(), 3U);
|
|
EXPECT_TRUE(Names.count("orc_rt_A"));
|
|
EXPECT_TRUE(Names.count("orc_rt_B"));
|
|
EXPECT_TRUE(Names.count("orc_rt_C"));
|
|
}
|