Index: llvm/trunk/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h =================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -42,13 +42,13 @@ /// @return A handle for the added objects. template - ObjSetHandleT addObjectSet(ObjSetT &Objects, MemoryManagerPtrT MemMgr, + ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) { for (auto I = Objects.begin(), E = Objects.end(); I != E; ++I) *I = Transform(std::move(*I)); - return BaseLayer.addObjectSet(Objects, std::move(MemMgr), + return BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr), std::move(Resolver)); } Index: llvm/trunk/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp =================================================================== --- llvm/trunk/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ llvm/trunk/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -7,9 +7,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" +#include "llvm/ExecutionEngine/Orc/NullResolver.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" +#include "llvm/Object/ObjectFile.h" #include "gtest/gtest.h" using namespace llvm::orc; @@ -51,7 +56,7 @@ template - ObjSetHandleT addObjectSet(ObjSetT &Objects, MemoryManagerPtrT MemMgr, + ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) { EXPECT_EQ(MockManager, *MemMgr) << "MM should pass through"; EXPECT_EQ(MockResolver, *Resolver) << "Resolver should pass through"; @@ -216,13 +221,14 @@ auto MM = llvm::make_unique(MockManager); auto SR = llvm::make_unique(MockResolver); M.expectAddObjectSet(Objs1, MM.get(), SR.get()); - auto H = T1.addObjectSet(Objs1, std::move(MM), std::move(SR)); + auto H = T1.addObjectSet(std::move(Objs1), std::move(MM), std::move(SR)); M.verifyAddObjectSet(H); // Test addObjectSet with T2 (mutating, naked pointers) - llvm::SmallVector Objs2; - Objs2.push_back(&MockObject1); - Objs2.push_back(&MockObject2); + llvm::SmallVector Objs2Vec; + Objs2Vec.push_back(&MockObject1); + Objs2Vec.push_back(&MockObject2); + llvm::MutableArrayRef Objs2(Objs2Vec); M.expectAddObjectSet(Objs2, &MockManager, &MockResolver); H = T2.addObjectSet(Objs2, &MockManager, &MockResolver); M.verifyAddObjectSet(H); @@ -271,5 +277,62 @@ const auto &T1C = T1; OwnedObj = T1C.getTransform()(std::move(OwnedObj)); EXPECT_EQ(289, *OwnedObj) << "Expected incrementing transform"; + + volatile bool RunStaticChecks = false; + if (RunStaticChecks) { + // Make sure that ObjectTransformLayer implements the object layer concept + // correctly by sandwitching one between an ObjectLinkingLayer and an + // IRCompileLayer, verifying that it compiles if we have a call to the + // IRComileLayer's addModuleSet that should call the transform layer's + // addObjectSet, and also calling the other public transform layer methods + // directly to make sure the methods they intend to forward to exist on + // the ObjectLinkingLayer. + + // We'll need a concrete MemoryManager class. + class NullManager : public llvm::RuntimeDyld::MemoryManager { + public: + uint8_t *allocateCodeSection(uintptr_t, unsigned, unsigned, + llvm::StringRef) override { + return nullptr; + } + uint8_t *allocateDataSection(uintptr_t, unsigned, unsigned, + llvm::StringRef, bool) override { + return nullptr; + } + void registerEHFrames(uint8_t *, uint64_t, size_t) override {} + void deregisterEHFrames(uint8_t *, uint64_t, size_t) override {} + bool finalizeMemory(std::string *) { return false; } + }; + + // Construct the jit layers. + ObjectLinkingLayer<> BaseLayer; + auto IdentityTransform = []( + std::unique_ptr> + Obj) { return std::move(Obj); }; + ObjectTransformLayer + TransformLayer(BaseLayer, IdentityTransform); + auto NullCompiler = [](llvm::Module &) { + return llvm::object::OwningBinary(); + }; + IRCompileLayer CompileLayer(TransformLayer, + NullCompiler); + std::vector Modules; + + // Make sure that the calls from IRCompileLayer to ObjectTransformLayer + // compile. + NullResolver Resolver; + NullManager Manager; + CompileLayer.addModuleSet(std::vector(), &Manager, + &Resolver); + + // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer + // compile. + decltype(TransformLayer)::ObjSetHandleT ObjSet; + TransformLayer.emitAndFinalize(ObjSet); + TransformLayer.findSymbolIn(ObjSet, Name, false); + TransformLayer.findSymbol(Name, true); + TransformLayer.mapSectionAddress(ObjSet, nullptr, 0); + TransformLayer.removeObjectSet(ObjSet); + } } }