summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/unittests/ExecutionEngine/Orc
diff options
context:
space:
mode:
authorpascal <pascal@openbsd.org>2016-09-03 22:46:54 +0000
committerpascal <pascal@openbsd.org>2016-09-03 22:46:54 +0000
commitb5500b9ca0102f1ccaf32f0e77e96d0739aded9b (patch)
treee1b7ebb5a0231f9e6d8d3f6f719582cebd64dc98 /gnu/llvm/unittests/ExecutionEngine/Orc
parentclarify purpose of src/gnu/ directory. (diff)
downloadwireguard-openbsd-b5500b9ca0102f1ccaf32f0e77e96d0739aded9b.tar.xz
wireguard-openbsd-b5500b9ca0102f1ccaf32f0e77e96d0739aded9b.zip
Use the space freed up by sparc and zaurus to import LLVM.
ok hackroom@
Diffstat (limited to 'gnu/llvm/unittests/ExecutionEngine/Orc')
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt22
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp75
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp55
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp48
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp32
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/Makefile16
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp176
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp275
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp160
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp25
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h179
-rw-r--r--gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp147
12 files changed, 1210 insertions, 0 deletions
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/gnu/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
new file mode 100644
index 00000000000..41fef24556b
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -0,0 +1,22 @@
+
+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
+ RPCUtilsTest.cpp
+ )
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
new file mode 100644
index 00000000000..a27e649b616
--- /dev/null
+++ b/gnu/llvm/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/gnu/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
new file mode 100644
index 00000000000..054fc16cabd
--- /dev/null
+++ b/gnu/llvm/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/gnu/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
new file mode 100644
index 00000000000..38b60ea7fcd
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
@@ -0,0 +1,48 @@
+//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting 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/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(IndirectionUtilsTest, MakeStub) {
+ ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", "");
+ Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>("");
+ SmallVector<AttributeSet, 4> Attrs;
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), 1U,
+ AttrBuilder().addAttribute(Attribute::StructRet)));
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), 2U,
+ AttrBuilder().addAttribute(Attribute::ByVal)));
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), ~0U,
+ AttrBuilder().addAttribute(Attribute::NoUnwind)));
+ F->setAttributes(AttributeSet::get(MB.getModule()->getContext(), Attrs));
+
+ auto ImplPtr = orc::createImplPointer(*F->getType(), *MB.getModule(), "", nullptr);
+ orc::makeStub(*F, *ImplPtr);
+
+ auto II = F->getEntryBlock().begin();
+ EXPECT_TRUE(isa<LoadInst>(*II)) << "First instruction of stub should be a load.";
+ auto *Call = dyn_cast<CallInst>(std::next(II));
+ EXPECT_TRUE(Call != nullptr) << "Second instruction of stub should be a call.";
+ EXPECT_TRUE(Call->isTailCall()) << "Indirect call from stub should be tail call.";
+ EXPECT_TRUE(Call->hasStructRetAttr())
+ << "makeStub should propagate sret attr on 1st argument.";
+ EXPECT_TRUE(Call->paramHasAttr(2U, Attribute::ByVal))
+ << "makeStub should propagate byval attr on 2nd argument.";
+}
+
+}
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
new file mode 100644
index 00000000000..a495766db91
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
@@ -0,0 +1,32 @@
+//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting 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/LazyEmittingLayer.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+struct MockBaseLayer {
+ typedef int ModuleSetHandleT;
+ ModuleSetHandleT addModuleSet(
+ std::list<std::unique_ptr<llvm::Module>>,
+ std::unique_ptr<llvm::RuntimeDyld::MemoryManager> MemMgr,
+ std::unique_ptr<llvm::RuntimeDyld::SymbolResolver> Resolver) {
+ EXPECT_FALSE(MemMgr);
+ return 42;
+ }
+};
+
+TEST(LazyEmittingLayerTest, Empty) {
+ MockBaseLayer M;
+ llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
+ L.addModuleSet(std::list<std::unique_ptr<llvm::Module>>(), nullptr, nullptr);
+}
+
+}
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/Makefile b/gnu/llvm/unittests/ExecutionEngine/Orc/Makefile
new file mode 100644
index 00000000000..c899728e507
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/Makefile
@@ -0,0 +1,16 @@
+##===- unittests/ExecutionEngine/Orc/Makefile --------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+TESTNAME = OrcJIT
+LINK_COMPONENTS := core ipo mcjit orcjit native support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
new file mode 100644
index 00000000000..59ee01f3601
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
@@ -0,0 +1,176 @@
+//===-- 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 "OrcTestCommon.h"
+#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 {
+
+class ObjectLinkingLayerExecutionTest : public testing::Test,
+ public OrcExecutionTest {
+};
+
+class SectionMemoryManagerWrapper : public SectionMemoryManager {
+public:
+ int FinalizationCount = 0;
+ bool finalizeMemory(std::string *ErrMsg = 0) override {
+ ++FinalizationCount;
+ return SectionMemoryManager::finalizeMemory(ErrMsg);
+ }
+};
+
+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);
+ }
+}
+
+
+TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
+
+ if (!TM)
+ return;
+
+ ObjectLinkingLayer<> ObjLayer;
+ SimpleCompiler Compile(*TM);
+
+ // Create a pair of modules that will trigger recursive finalization:
+ // Module 1:
+ // int bar() { return 42; }
+ // Module 2:
+ // int bar();
+ // int foo() { return bar(); }
+
+ ModuleBuilder MB1(getGlobalContext(), "", "dummy");
+ {
+ MB1.getModule()->setDataLayout(TM->createDataLayout());
+ Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
+ BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
+ BarImpl);
+ IRBuilder<> Builder(BarEntry);
+ IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
+ Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
+ Builder.CreateRet(FourtyTwo);
+ }
+
+ auto Obj1 = Compile(*MB1.getModule());
+ std::vector<object::ObjectFile*> Obj1Set;
+ Obj1Set.push_back(Obj1.getBinary());
+
+ ModuleBuilder MB2(getGlobalContext(), "", "dummy");
+ {
+ MB2.getModule()->setDataLayout(TM->createDataLayout());
+ Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
+ Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
+ BasicBlock *FooEntry = BasicBlock::Create(getGlobalContext(), "entry",
+ FooImpl);
+ IRBuilder<> Builder(FooEntry);
+ Builder.CreateRet(Builder.CreateCall(BarDecl));
+ }
+ auto Obj2 = Compile(*MB2.getModule());
+ std::vector<object::ObjectFile*> Obj2Set;
+ Obj2Set.push_back(Obj2.getBinary());
+
+ auto Resolver =
+ createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = ObjLayer.findSymbol(Name, true))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ SectionMemoryManagerWrapper SMMW;
+ ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver);
+ auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver);
+ ObjLayer.emitAndFinalize(H);
+
+ // Finalization of module 2 should trigger finalization of module 1.
+ // Verify that finalize on SMMW is only called once.
+ EXPECT_EQ(SMMW.FinalizationCount, 1)
+ << "Extra call to finalize";
+}
+
+}
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
new file mode 100644
index 00000000000..c88c94f17b1
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
@@ -0,0 +1,275 @@
+//===- ObjectTransformLayerTest.cpp - Unit tests for ObjectTransformLayer -===//
+//
+// 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/ObjectTransformLayer.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "gtest/gtest.h"
+
+using namespace llvm::orc;
+
+namespace {
+
+// Stand-in for RuntimeDyld::MemoryManager
+typedef int MockMemoryManager;
+
+// Stand-in for RuntimeDyld::SymbolResolver
+typedef int MockSymbolResolver;
+
+// stand-in for object::ObjectFile
+typedef int MockObjectFile;
+
+// stand-in for llvm::MemoryBuffer set
+typedef int MockMemoryBufferSet;
+
+// Mock transform that operates on unique pointers to object files, and
+// allocates new object files rather than mutating the given ones.
+struct AllocatingTransform {
+ std::unique_ptr<MockObjectFile>
+ operator()(std::unique_ptr<MockObjectFile> Obj) const {
+ return llvm::make_unique<MockObjectFile>(*Obj + 1);
+ }
+};
+
+// Mock base layer for verifying behavior of transform layer.
+// Each method "T foo(args)" is accompanied by two auxiliary methods:
+// - "void expectFoo(args)", to be called before calling foo on the transform
+// layer; saves values of args, which mock layer foo then verifies against.
+// - "void verifyFoo(T)", to be called after foo, which verifies that the
+// transform layer called the base layer and forwarded any return value.
+class MockBaseLayer {
+public:
+ typedef int ObjSetHandleT;
+
+ MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
+
+ template <typename ObjSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
+ ObjSetHandleT addObjectSet(ObjSetT &Objects, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+ EXPECT_EQ(MockManager, *MemMgr) << "MM should pass through";
+ EXPECT_EQ(MockResolver, *Resolver) << "Resolver should pass through";
+ size_t I = 0;
+ for (auto &ObjPtr : Objects) {
+ EXPECT_EQ(MockObjects[I++] + 1, *ObjPtr) << "Transform should be applied";
+ }
+ EXPECT_EQ(MockObjects.size(), I) << "Number of objects should match";
+ LastCalled = "addObjectSet";
+ MockObjSetHandle = 111;
+ return MockObjSetHandle;
+ }
+ template <typename ObjSetT>
+ void expectAddObjectSet(ObjSetT &Objects, MockMemoryManager *MemMgr,
+ MockSymbolResolver *Resolver) {
+ MockManager = *MemMgr;
+ MockResolver = *Resolver;
+ for (auto &ObjPtr : Objects) {
+ MockObjects.push_back(*ObjPtr);
+ }
+ }
+ void verifyAddObjectSet(ObjSetHandleT Returned) {
+ EXPECT_EQ("addObjectSet", LastCalled);
+ EXPECT_EQ(MockObjSetHandle, Returned) << "Return should pass through";
+ resetExpectations();
+ }
+
+ void removeObjectSet(ObjSetHandleT H) {
+ EXPECT_EQ(MockObjSetHandle, H);
+ LastCalled = "removeObjectSet";
+ }
+ void expectRemoveObjectSet(ObjSetHandleT H) { MockObjSetHandle = H; }
+ void verifyRemoveObjectSet() {
+ EXPECT_EQ("removeObjectSet", LastCalled);
+ resetExpectations();
+ }
+
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ EXPECT_EQ(MockName, Name) << "Name should pass through";
+ EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
+ LastCalled = "findSymbol";
+ MockSymbol = JITSymbol(122, llvm::JITSymbolFlags::None);
+ return MockSymbol;
+ }
+ void expectFindSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ MockName = Name;
+ MockBool = ExportedSymbolsOnly;
+ }
+ void verifyFindSymbol(llvm::orc::JITSymbol Returned) {
+ EXPECT_EQ("findSymbol", LastCalled);
+ EXPECT_EQ(MockSymbol.getAddress(), Returned.getAddress())
+ << "Return should pass through";
+ resetExpectations();
+ }
+
+ JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ EXPECT_EQ(MockObjSetHandle, H) << "Handle should pass through";
+ EXPECT_EQ(MockName, Name) << "Name should pass through";
+ EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
+ LastCalled = "findSymbolIn";
+ MockSymbol = JITSymbol(122, llvm::JITSymbolFlags::None);
+ return MockSymbol;
+ }
+ void expectFindSymbolIn(ObjSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ MockObjSetHandle = H;
+ MockName = Name;
+ MockBool = ExportedSymbolsOnly;
+ }
+ void verifyFindSymbolIn(llvm::orc::JITSymbol Returned) {
+ EXPECT_EQ("findSymbolIn", LastCalled);
+ EXPECT_EQ(MockSymbol.getAddress(), Returned.getAddress())
+ << "Return should pass through";
+ resetExpectations();
+ }
+
+ void emitAndFinalize(ObjSetHandleT H) {
+ EXPECT_EQ(MockObjSetHandle, H) << "Handle should pass through";
+ LastCalled = "emitAndFinalize";
+ }
+ void expectEmitAndFinalize(ObjSetHandleT H) { MockObjSetHandle = H; }
+ void verifyEmitAndFinalize() {
+ EXPECT_EQ("emitAndFinalize", LastCalled);
+ resetExpectations();
+ }
+
+ void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
+ TargetAddress TargetAddr) {
+ EXPECT_EQ(MockObjSetHandle, H);
+ EXPECT_EQ(MockLocalAddress, LocalAddress);
+ EXPECT_EQ(MockTargetAddress, TargetAddr);
+ LastCalled = "mapSectionAddress";
+ }
+ void expectMapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
+ TargetAddress TargetAddr) {
+ MockObjSetHandle = H;
+ MockLocalAddress = LocalAddress;
+ MockTargetAddress = TargetAddr;
+ }
+ void verifyMapSectionAddress() {
+ EXPECT_EQ("mapSectionAddress", LastCalled);
+ resetExpectations();
+ }
+
+private:
+ // Backing fields for remembering parameter/return values
+ std::string LastCalled;
+ MockMemoryManager MockManager;
+ MockSymbolResolver MockResolver;
+ std::vector<MockObjectFile> MockObjects;
+ ObjSetHandleT MockObjSetHandle;
+ std::string MockName;
+ bool MockBool;
+ JITSymbol MockSymbol;
+ const void *MockLocalAddress;
+ TargetAddress MockTargetAddress;
+ MockMemoryBufferSet MockBufferSet;
+
+ // Clear remembered parameters between calls
+ void resetExpectations() {
+ LastCalled = "nothing";
+ MockManager = 0;
+ MockResolver = 0;
+ MockObjects.clear();
+ MockObjSetHandle = 0;
+ MockName = "bogus";
+ MockSymbol = JITSymbol(nullptr);
+ MockLocalAddress = nullptr;
+ MockTargetAddress = 0;
+ MockBufferSet = 0;
+ }
+};
+
+// Test each operation on ObjectTransformLayer.
+TEST(ObjectTransformLayerTest, Main) {
+ MockBaseLayer M;
+
+ // Create one object transform layer using a transform (as a functor)
+ // that allocates new objects, and deals in unique pointers.
+ ObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
+
+ // Create a second object transform layer using a transform (as a lambda)
+ // that mutates objects in place, and deals in naked pointers
+ ObjectTransformLayer<MockBaseLayer,
+ std::function<MockObjectFile *(MockObjectFile *)>>
+ T2(M, [](MockObjectFile *Obj) {
+ ++(*Obj);
+ return Obj;
+ });
+
+ // Instantiate some mock objects to use below
+ MockObjectFile MockObject1 = 211;
+ MockObjectFile MockObject2 = 222;
+ MockMemoryManager MockManager = 233;
+ MockSymbolResolver MockResolver = 244;
+
+ // Test addObjectSet with T1 (allocating, unique pointers)
+ std::vector<std::unique_ptr<MockObjectFile>> Objs1;
+ Objs1.push_back(llvm::make_unique<MockObjectFile>(MockObject1));
+ Objs1.push_back(llvm::make_unique<MockObjectFile>(MockObject2));
+ auto MM = llvm::make_unique<MockMemoryManager>(MockManager);
+ auto SR = llvm::make_unique<MockSymbolResolver>(MockResolver);
+ M.expectAddObjectSet(Objs1, MM.get(), SR.get());
+ auto H = T1.addObjectSet(Objs1, std::move(MM), std::move(SR));
+ M.verifyAddObjectSet(H);
+
+ // Test addObjectSet with T2 (mutating, naked pointers)
+ llvm::SmallVector<MockObjectFile *, 2> Objs2;
+ Objs2.push_back(&MockObject1);
+ Objs2.push_back(&MockObject2);
+ M.expectAddObjectSet(Objs2, &MockManager, &MockResolver);
+ H = T2.addObjectSet(Objs2, &MockManager, &MockResolver);
+ M.verifyAddObjectSet(H);
+ EXPECT_EQ(212, MockObject1) << "Expected mutation";
+ EXPECT_EQ(223, MockObject2) << "Expected mutation";
+
+ // Test removeObjectSet
+ M.expectRemoveObjectSet(H);
+ T1.removeObjectSet(H);
+ M.verifyRemoveObjectSet();
+
+ // Test findSymbol
+ std::string Name = "foo";
+ bool ExportedOnly = true;
+ M.expectFindSymbol(Name, ExportedOnly);
+ JITSymbol Symbol = T2.findSymbol(Name, ExportedOnly);
+ M.verifyFindSymbol(Symbol);
+
+ // Test findSymbolIn
+ Name = "bar";
+ ExportedOnly = false;
+ M.expectFindSymbolIn(H, Name, ExportedOnly);
+ Symbol = T1.findSymbolIn(H, Name, ExportedOnly);
+ M.verifyFindSymbolIn(Symbol);
+
+ // Test emitAndFinalize
+ M.expectEmitAndFinalize(H);
+ T2.emitAndFinalize(H);
+ M.verifyEmitAndFinalize();
+
+ // Test mapSectionAddress
+ char Buffer[24];
+ TargetAddress MockAddress = 255;
+ M.expectMapSectionAddress(H, Buffer, MockAddress);
+ T1.mapSectionAddress(H, Buffer, MockAddress);
+ M.verifyMapSectionAddress();
+
+ // Verify transform getter (non-const)
+ MockObjectFile Mutatee = 277;
+ MockObjectFile *Out = T2.getTransform()(&Mutatee);
+ EXPECT_EQ(&Mutatee, Out) << "Expected in-place transform";
+ EXPECT_EQ(278, Mutatee) << "Expected incrementing transform";
+
+ // Verify transform getter (const)
+ auto OwnedObj = llvm::make_unique<MockObjectFile>(288);
+ const auto &T1C = T1;
+ OwnedObj = T1C.getTransform()(std::move(OwnedObj));
+ EXPECT_EQ(289, *OwnedObj) << "Expected incrementing transform";
+}
+}
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
new file mode 100644
index 00000000000..776d26970a3
--- /dev/null
+++ b/gnu/llvm/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/gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
new file mode 100644
index 00000000000..17d1e9c9276
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
@@ -0,0 +1,25 @@
+//===--------- OrcTestCommon.cpp - Utilities for Orc Unit Tests -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for Orc unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcTestCommon.h"
+
+using namespace llvm;
+
+bool OrcExecutionTest::NativeTargetInitialized = false;
+
+ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
+ StringRef Name)
+ : M(new Module(Name, Context)) {
+ if (Triple != "")
+ M->setTargetTriple(Triple);
+}
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
new file mode 100644
index 00000000000..f480e0789ae
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -0,0 +1,179 @@
+//===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for the Orc unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeBuilder.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/Support/TargetSelect.h"
+#include <memory>
+
+namespace llvm {
+
+// Base class for Orc tests that will execute code.
+class OrcExecutionTest {
+public:
+
+ OrcExecutionTest() {
+ if (!NativeTargetInitialized) {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmParser();
+ InitializeNativeTargetAsmPrinter();
+ NativeTargetInitialized = true;
+ }
+
+ // Try to select a TargetMachine for the host.
+ TM.reset(EngineBuilder().selectTarget());
+
+ 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;
+ }
+ };
+
+protected:
+ std::unique_ptr<TargetMachine> TM;
+private:
+ static bool NativeTargetInitialized;
+};
+
+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;
+};
+
+// 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
+
+#endif
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
new file mode 100644
index 00000000000..8215144a514
--- /dev/null
+++ b/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
@@ -0,0 +1,147 @@
+//===----------- RPCUtilsTest.cpp - Unit tests the Orc RPC utils ----------===//
+//
+// 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/RPCChannel.h"
+#include "llvm/ExecutionEngine/Orc/RPCUtils.h"
+#include "gtest/gtest.h"
+
+#include <queue>
+
+using namespace llvm;
+using namespace llvm::orc;
+using namespace llvm::orc::remote;
+
+class QueueChannel : public RPCChannel {
+public:
+ QueueChannel(std::queue<char> &Queue) : Queue(Queue) {}
+
+ std::error_code readBytes(char *Dst, unsigned Size) override {
+ while (Size--) {
+ *Dst++ = Queue.front();
+ Queue.pop();
+ }
+ return std::error_code();
+ }
+
+ std::error_code appendBytes(const char *Src, unsigned Size) override {
+ while (Size--)
+ Queue.push(*Src++);
+ return std::error_code();
+ }
+
+ std::error_code send() override { return std::error_code(); }
+
+private:
+ std::queue<char> &Queue;
+};
+
+class DummyRPC : public testing::Test,
+ public RPC<QueueChannel> {
+public:
+ typedef Procedure<1, bool> Proc1;
+ typedef Procedure<2, int8_t,
+ uint8_t,
+ int16_t,
+ uint16_t,
+ int32_t,
+ uint32_t,
+ int64_t,
+ uint64_t,
+ bool,
+ std::string,
+ std::vector<int>> AllTheTypes;
+};
+
+
+TEST_F(DummyRPC, TestBasic) {
+ std::queue<char> Queue;
+ QueueChannel C(Queue);
+
+ {
+ // Make a call to Proc1.
+ auto EC = call<Proc1>(C, true);
+ EXPECT_FALSE(EC) << "Simple call over queue failed";
+ }
+
+ {
+ // Expect a call to Proc1.
+ auto EC = expect<Proc1>(C,
+ [&](bool &B) {
+ EXPECT_EQ(B, true)
+ << "Bool serialization broken";
+ return std::error_code();
+ });
+ EXPECT_FALSE(EC) << "Simple expect over queue failed";
+ }
+}
+
+TEST_F(DummyRPC, TestSerialization) {
+ std::queue<char> Queue;
+ QueueChannel C(Queue);
+
+ {
+ // Make a call to Proc1.
+ std::vector<int> v({42, 7});
+ auto EC = call<AllTheTypes>(C,
+ -101,
+ 250,
+ -10000,
+ 10000,
+ -1000000000,
+ 1000000000,
+ -10000000000,
+ 10000000000,
+ true,
+ "foo",
+ v);
+ EXPECT_FALSE(EC) << "Big (serialization test) call over queue failed";
+ }
+
+ {
+ // Expect a call to Proc1.
+ auto EC = expect<AllTheTypes>(C,
+ [&](int8_t &s8,
+ uint8_t &u8,
+ int16_t &s16,
+ uint16_t &u16,
+ int32_t &s32,
+ uint32_t &u32,
+ int64_t &s64,
+ uint64_t &u64,
+ bool &b,
+ std::string &s,
+ std::vector<int> &v) {
+
+ EXPECT_EQ(s8, -101)
+ << "int8_t serialization broken";
+ EXPECT_EQ(u8, 250)
+ << "uint8_t serialization broken";
+ EXPECT_EQ(s16, -10000)
+ << "int16_t serialization broken";
+ EXPECT_EQ(u16, 10000)
+ << "uint16_t serialization broken";
+ EXPECT_EQ(s32, -1000000000)
+ << "int32_t serialization broken";
+ EXPECT_EQ(u32, 1000000000ULL)
+ << "uint32_t serialization broken";
+ EXPECT_EQ(s64, -10000000000)
+ << "int64_t serialization broken";
+ EXPECT_EQ(u64, 10000000000ULL)
+ << "uint64_t serialization broken";
+ EXPECT_EQ(b, true)
+ << "bool serialization broken";
+ EXPECT_EQ(s, "foo")
+ << "std::string serialization broken";
+ EXPECT_EQ(v, std::vector<int>({42, 7}))
+ << "std::vector serialization broken";
+ return std::error_code();
+ });
+ EXPECT_FALSE(EC) << "Big (serialization test) call over queue failed";
+ }
+}