diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
| commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
| tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /unittests/ExecutionEngine/Orc | |
| parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
Notes
Diffstat (limited to 'unittests/ExecutionEngine/Orc')
9 files changed, 537 insertions, 56 deletions
diff --git a/unittests/ExecutionEngine/Orc/CMakeLists.txt b/unittests/ExecutionEngine/Orc/CMakeLists.txt index 30bd19fa3d23..74cc5b57015c 100644 --- a/unittests/ExecutionEngine/Orc/CMakeLists.txt +++ b/unittests/ExecutionEngine/Orc/CMakeLists.txt @@ -1,12 +1,21 @@ + set(LLVM_LINK_COMPONENTS Core + ExecutionEngine + Object OrcJIT + RuntimeDyld Support + native ) add_llvm_unittest(OrcJITTests + CompileOnDemandLayerTest.cpp IndirectionUtilsTest.cpp + GlobalMappingLayerTest.cpp LazyEmittingLayerTest.cpp + ObjectLinkingLayerTest.cpp ObjectTransformLayerTest.cpp + OrcCAPITest.cpp OrcTestCommon.cpp ) diff --git a/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp new file mode 100644 index 000000000000..a27e649b616f --- /dev/null +++ b/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp @@ -0,0 +1,75 @@ +//===----- CompileOnDemandLayerTest.cpp - Unit tests for the COD layer ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "OrcTestCommon.h" +#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::orc; + +namespace { + +class DummyCallbackManager : public orc::JITCompileCallbackManager { +public: + DummyCallbackManager() : JITCompileCallbackManager(0) { } +public: + void grow() override { llvm_unreachable("not implemented"); } +}; + +class DummyStubsManager : public orc::IndirectStubsManager { +public: + std::error_code createStub(StringRef StubName, TargetAddress InitAddr, + JITSymbolFlags Flags) override { + llvm_unreachable("Not implemented"); + } + + std::error_code createStubs(const StubInitsMap &StubInits) override { + llvm_unreachable("Not implemented"); + } + + JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { + llvm_unreachable("Not implemented"); + } + + JITSymbol findPointer(StringRef Name) override { + llvm_unreachable("Not implemented"); + } + + std::error_code updatePointer(StringRef Name, + TargetAddress NewAddr) override { + llvm_unreachable("Not implemented"); + } +}; + +TEST(CompileOnDemandLayerTest, FindSymbol) { + auto MockBaseLayer = + createMockBaseLayer<int>(DoNothingAndReturn<int>(0), + DoNothingAndReturn<void>(), + [](const std::string &Name, bool) { + if (Name == "foo") + return JITSymbol(1, JITSymbolFlags::Exported); + return JITSymbol(nullptr); + }, + DoNothingAndReturn<JITSymbol>(nullptr)); + + typedef decltype(MockBaseLayer) MockBaseLayerT; + DummyCallbackManager CallbackMgr; + + llvm::orc::CompileOnDemandLayer<MockBaseLayerT> COD( + MockBaseLayer, [](Function &F) { return std::set<Function *>{&F}; }, + CallbackMgr, [] { return llvm::make_unique<DummyStubsManager>(); }, true); + + auto Sym = COD.findSymbol("foo", true); + + EXPECT_TRUE(!!Sym) + << "CompileOnDemand::findSymbol should call findSymbol in the base layer."; +} + +} diff --git a/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp b/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp new file mode 100644 index 000000000000..054fc16cabd4 --- /dev/null +++ b/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp @@ -0,0 +1,55 @@ +//===--- GlobalMappingLayerTest.cpp - Unit test the global mapping layer --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/GlobalMappingLayer.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::orc; + +namespace { + +struct MockBaseLayer { + + typedef int ModuleSetHandleT; + + JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { + if (Name == "bar") + return llvm::orc::JITSymbol(0x4567, JITSymbolFlags::Exported); + return nullptr; + } + +}; + +TEST(GlobalMappingLayerTest, Empty) { + MockBaseLayer M; + GlobalMappingLayer<MockBaseLayer> L(M); + + // Test fall-through for missing symbol. + auto FooSym = L.findSymbol("foo", true); + EXPECT_FALSE(FooSym) << "Found unexpected symbol."; + + // Test fall-through for symbol in base layer. + auto BarSym = L.findSymbol("bar", true); + EXPECT_EQ(BarSym.getAddress(), static_cast<TargetAddress>(0x4567)) + << "Symbol lookup fall-through failed."; + + // Test setup of a global mapping. + L.setGlobalMapping("foo", 0x0123); + auto FooSym2 = L.findSymbol("foo", true); + EXPECT_EQ(FooSym2.getAddress(), static_cast<TargetAddress>(0x0123)) + << "Symbol mapping setup failed."; + + // Test removal of a global mapping. + L.eraseGlobalMapping("foo"); + auto FooSym3 = L.findSymbol("foo", true); + EXPECT_FALSE(FooSym3) << "Symbol mapping removal failed."; +} + +} diff --git a/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp index 1a533b05838d..38b60ea7fcd4 100644 --- a/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp +++ b/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp @@ -18,7 +18,7 @@ namespace { TEST(IndirectionUtilsTest, MakeStub) { ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", ""); - Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>(MB.getModule(), ""); + Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>(""); SmallVector<AttributeSet, 4> Attrs; Attrs.push_back( AttributeSet::get(MB.getModule()->getContext(), 1U, diff --git a/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp new file mode 100644 index 000000000000..a37177c5d1db --- /dev/null +++ b/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp @@ -0,0 +1,94 @@ +//===-- ObjectLinkingLayerTest.cpp - Unit tests for object linking layer --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" +#include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/LLVMContext.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::orc; + +namespace { + +TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) { + + class SectionMemoryManagerWrapper : public SectionMemoryManager { + public: + SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {} + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + StringRef SectionName, + bool IsReadOnly) override { + if (SectionName == ".debug_str") + DebugSeen = true; + return SectionMemoryManager::allocateDataSection(Size, Alignment, + SectionID, + SectionName, + IsReadOnly); + } + private: + bool DebugSeen; + }; + + ObjectLinkingLayer<> ObjLayer; + + auto M = llvm::make_unique<Module>("", getGlobalContext()); + M->setTargetTriple("x86_64-unknown-linux-gnu"); + Type *Int32Ty = IntegerType::get(getGlobalContext(), 32); + GlobalVariable *GV = + new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage, + ConstantInt::get(Int32Ty, 42), "foo"); + + GV->setSection(".debug_str"); + + std::unique_ptr<TargetMachine> TM( + EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "", + SmallVector<std::string, 1>())); + if (!TM) + return; + + auto OwningObj = SimpleCompiler(*TM)(*M); + std::vector<object::ObjectFile*> Objs; + Objs.push_back(OwningObj.getBinary()); + + bool DebugSectionSeen = false; + SectionMemoryManagerWrapper SMMW(DebugSectionSeen); + auto Resolver = + createLambdaResolver( + [](const std::string &Name) { + return RuntimeDyld::SymbolInfo(nullptr); + }, + [](const std::string &Name) { + return RuntimeDyld::SymbolInfo(nullptr); + }); + + { + // Test with ProcessAllSections = false (the default). + auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver); + EXPECT_EQ(DebugSectionSeen, false) + << "Unexpected debug info section"; + ObjLayer.removeObjectSet(H); + } + + { + // Test with ProcessAllSections = true. + ObjLayer.setProcessAllSections(true); + auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver); + EXPECT_EQ(DebugSectionSeen, true) + << "Expected debug info section not seen"; + ObjLayer.removeObjectSet(H); + } +} + +} diff --git a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp index 41b2307cadd8..c88c94f17b1c 100644 --- a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -157,21 +157,6 @@ public: resetExpectations(); } - template <typename OwningMBSet> - void takeOwnershipOfBuffers(ObjSetHandleT H, OwningMBSet MBs) { - EXPECT_EQ(MockObjSetHandle, H); - EXPECT_EQ(MockBufferSet, *MBs); - LastCalled = "takeOwnershipOfBuffers"; - } - void expectTakeOwnershipOfBuffers(ObjSetHandleT H, MockMemoryBufferSet *MBs) { - MockObjSetHandle = H; - MockBufferSet = *MBs; - } - void verifyTakeOwnershipOfBuffers() { - EXPECT_EQ("takeOwnershipOfBuffers", LastCalled); - resetExpectations(); - } - private: // Backing fields for remembering parameter/return values std::string LastCalled; @@ -275,18 +260,6 @@ TEST(ObjectTransformLayerTest, Main) { T1.mapSectionAddress(H, Buffer, MockAddress); M.verifyMapSectionAddress(); - // Test takeOwnershipOfBuffers, using unique pointer to buffer set - auto MockBufferSetPtr = llvm::make_unique<MockMemoryBufferSet>(366); - M.expectTakeOwnershipOfBuffers(H, MockBufferSetPtr.get()); - T2.takeOwnershipOfBuffers(H, std::move(MockBufferSetPtr)); - M.verifyTakeOwnershipOfBuffers(); - - // Test takeOwnershipOfBuffers, using naked pointer to buffer set - MockMemoryBufferSet MockBufferSet = 266; - M.expectTakeOwnershipOfBuffers(H, &MockBufferSet); - T1.takeOwnershipOfBuffers(H, &MockBufferSet); - M.verifyTakeOwnershipOfBuffers(); - // Verify transform getter (non-const) MockObjectFile Mutatee = 277; MockObjectFile *Out = T2.getTransform()(&Mutatee); diff --git a/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp new file mode 100644 index 000000000000..776d26970a31 --- /dev/null +++ b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp @@ -0,0 +1,160 @@ +//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "OrcTestCommon.h" +#include "gtest/gtest.h" +#include "llvm-c/Core.h" +#include "llvm-c/OrcBindings.h" +#include "llvm-c/Target.h" +#include "llvm-c/TargetMachine.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +namespace llvm { + +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) + +class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest { +protected: + std::unique_ptr<Module> createTestModule(const Triple &TT) { + ModuleBuilder MB(getGlobalContext(), TT.str(), ""); + Function *TestFunc = MB.createFunctionDecl<int()>("testFunc"); + Function *Main = MB.createFunctionDecl<int(int, char*[])>("main"); + + Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext())); + IRBuilder<> B(&Main->back()); + Value* Result = B.CreateCall(TestFunc); + B.CreateRet(Result); + + return MB.takeModule(); + } + + typedef int (*MainFnTy)(); + + static int myTestFuncImpl() { + return 42; + } + + static char *testFuncName; + + static uint64_t myResolver(const char *Name, void *Ctx) { + if (!strncmp(Name, testFuncName, 8)) + return (uint64_t)&myTestFuncImpl; + return 0; + } + + struct CompileContext { + CompileContext() : Compiled(false) { } + + OrcCAPIExecutionTest* APIExecTest; + std::unique_ptr<Module> M; + LLVMOrcModuleHandle H; + bool Compiled; + }; + + static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack, + void *Ctx) { + CompileContext *CCtx = static_cast<CompileContext*>(Ctx); + auto *ET = CCtx->APIExecTest; + CCtx->M = ET->createTestModule(ET->TM->getTargetTriple()); + CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()), + myResolver, nullptr); + CCtx->Compiled = true; + LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main"); + LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr); + return MainAddr; + } +}; + +char *OrcCAPIExecutionTest::testFuncName = nullptr; + +TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) { + if (!TM) + return; + + LLVMOrcJITStackRef JIT = + LLVMOrcCreateInstance(wrap(TM.get())); + + std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple()); + + LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + + LLVMOrcModuleHandle H = + LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr); + MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main"); + int Result = MainFn(); + EXPECT_EQ(Result, 42) + << "Eagerly JIT'd code did not return expected result"; + + LLVMOrcRemoveModule(JIT, H); + + LLVMOrcDisposeMangledSymbol(testFuncName); + LLVMOrcDisposeInstance(JIT); +} + +TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) { + if (!TM) + return; + + LLVMOrcJITStackRef JIT = + LLVMOrcCreateInstance(wrap(TM.get())); + + std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple()); + + LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + + LLVMOrcModuleHandle H = + LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr); + MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main"); + int Result = MainFn(); + EXPECT_EQ(Result, 42) + << "Lazily JIT'd code did not return expected result"; + + LLVMOrcRemoveModule(JIT, H); + + LLVMOrcDisposeMangledSymbol(testFuncName); + LLVMOrcDisposeInstance(JIT); +} + +TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) { + if (!TM) + return; + + LLVMOrcJITStackRef JIT = + LLVMOrcCreateInstance(wrap(TM.get())); + + LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + + CompileContext C; + C.APIExecTest = this; + LLVMOrcCreateIndirectStub(JIT, "foo", + LLVMOrcCreateLazyCompileCallback(JIT, + myCompileCallback, + &C)); + MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo"); + int Result = FooFn(); + EXPECT_TRUE(C.Compiled) + << "Function wasn't lazily compiled"; + EXPECT_EQ(Result, 42) + << "Direct-callback JIT'd code did not return expected result"; + + C.Compiled = false; + FooFn(); + EXPECT_FALSE(C.Compiled) + << "Direct-callback JIT'd code was JIT'd twice"; + + LLVMOrcRemoveModule(JIT, C.H); + + LLVMOrcDisposeMangledSymbol(testFuncName); + LLVMOrcDisposeInstance(JIT); +} + +} // namespace llvm diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp b/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp index 5fea3c89f86c..1b5485d3b33b 100644 --- a/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp +++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp @@ -15,6 +15,8 @@ using namespace llvm; +bool OrcExecutionTest::NativeTargetInitialized = false; + ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple, StringRef Name) : M(new Module(Name, Context)), diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/unittests/ExecutionEngine/Orc/OrcTestCommon.h index 1b2859b51d09..15d9f54a37fc 100644 --- a/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -20,46 +20,159 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/TypeBuilder.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/Orc/JITSymbol.h" +#include "llvm/Support/TargetSelect.h" #include <memory> namespace llvm { - class ModuleBuilder { - public: - ModuleBuilder(LLVMContext &Context, StringRef Triple, - StringRef Name); +// Base class for Orc tests that will execute code. +class OrcExecutionTest { +public: - template <typename FuncType> - Function* createFunctionDecl(Module *M, StringRef Name) { - return Function::Create( - TypeBuilder<FuncType, false>::get(M->getContext()), - GlobalValue::ExternalLinkage, Name, M); + OrcExecutionTest() { + if (!NativeTargetInitialized) { + InitializeNativeTarget(); + InitializeNativeTargetAsmParser(); + InitializeNativeTargetAsmPrinter(); + NativeTargetInitialized = true; } - Module* getModule() { return M.get(); } - const Module* getModule() const { return M.get(); } - std::unique_ptr<Module> takeModule() { return std::move(M); } + // Try to select a TargetMachine for the host. + TM.reset(EngineBuilder().selectTarget()); - private: - std::unique_ptr<Module> M; - IRBuilder<> Builder; + if (TM) { + // If we found a TargetMachine, check that it's one that Orc supports. + const Triple& TT = TM->getTargetTriple(); + if (TT.getArch() != Triple::x86_64 || !TT.isOSDarwin()) + TM = nullptr; + } }; - // Dummy struct type. - struct DummyStruct { - int X[256]; - }; +protected: + std::unique_ptr<TargetMachine> TM; +private: + static bool NativeTargetInitialized; +}; - // TypeBuilder specialization for DummyStruct. - template <bool XCompile> - class TypeBuilder<DummyStruct, XCompile> { - public: - static StructType *get(LLVMContext &Context) { - return StructType::get( - TypeBuilder<types::i<32>[256], XCompile>::get(Context), nullptr); - } - }; +class ModuleBuilder { +public: + ModuleBuilder(LLVMContext &Context, StringRef Triple, + StringRef Name); + + template <typename FuncType> + Function* createFunctionDecl(StringRef Name) { + return Function::Create( + TypeBuilder<FuncType, false>::get(M->getContext()), + GlobalValue::ExternalLinkage, Name, M.get()); + } + + Module* getModule() { return M.get(); } + const Module* getModule() const { return M.get(); } + std::unique_ptr<Module> takeModule() { return std::move(M); } + +private: + std::unique_ptr<Module> M; + IRBuilder<> Builder; +}; + +// Dummy struct type. +struct DummyStruct { + int X[256]; +}; + +// TypeBuilder specialization for DummyStruct. +template <bool XCompile> +class TypeBuilder<DummyStruct, XCompile> { +public: + static StructType *get(LLVMContext &Context) { + return StructType::get( + TypeBuilder<types::i<32>[256], XCompile>::get(Context), nullptr); + } +}; + +template <typename HandleT, + typename AddModuleSetFtor, + typename RemoveModuleSetFtor, + typename FindSymbolFtor, + typename FindSymbolInFtor> +class MockBaseLayer { +public: + + typedef HandleT ModuleSetHandleT; + + MockBaseLayer(AddModuleSetFtor &&AddModuleSet, + RemoveModuleSetFtor &&RemoveModuleSet, + FindSymbolFtor &&FindSymbol, + FindSymbolInFtor &&FindSymbolIn) + : AddModuleSet(AddModuleSet), RemoveModuleSet(RemoveModuleSet), + FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn) + {} + + template <typename ModuleSetT, typename MemoryManagerPtrT, + typename SymbolResolverPtrT> + ModuleSetHandleT addModuleSet(ModuleSetT Ms, MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return AddModuleSet(std::move(Ms), std::move(MemMgr), std::move(Resolver)); + } + + void removeModuleSet(ModuleSetHandleT H) { + RemoveModuleSet(H); + } + + orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { + return FindSymbol(Name, ExportedSymbolsOnly); + } + + orc::JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + bool ExportedSymbolsOnly) { + return FindSymbolIn(H, Name, ExportedSymbolsOnly); + } + +private: + AddModuleSetFtor AddModuleSet; + RemoveModuleSetFtor RemoveModuleSet; + FindSymbolFtor FindSymbol; + FindSymbolInFtor FindSymbolIn; +}; + +template <typename ModuleSetHandleT, + typename AddModuleSetFtor, + typename RemoveModuleSetFtor, + typename FindSymbolFtor, + typename FindSymbolInFtor> +MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor, + FindSymbolFtor, FindSymbolInFtor> +createMockBaseLayer(AddModuleSetFtor &&AddModuleSet, + RemoveModuleSetFtor &&RemoveModuleSet, + FindSymbolFtor &&FindSymbol, + FindSymbolInFtor &&FindSymbolIn) { + return MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor, + FindSymbolFtor, FindSymbolInFtor>( + std::forward<AddModuleSetFtor>(AddModuleSet), + std::forward<RemoveModuleSetFtor>(RemoveModuleSet), + std::forward<FindSymbolFtor>(FindSymbol), + std::forward<FindSymbolInFtor>(FindSymbolIn)); +} + +template <typename ReturnT> +class DoNothingAndReturn { +public: + DoNothingAndReturn(ReturnT Val) : Val(Val) {} + + template <typename... Args> + ReturnT operator()(Args...) const { return Val; } +private: + ReturnT Val; +}; +template <> +class DoNothingAndReturn<void> { +public: + template <typename... Args> + void operator()(Args...) const { } +}; } // namespace llvm |
