//===------ 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 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.getArch() != Triple::x86) || TT.isOSWindows()) TM = nullptr; } }; protected: LLVMContext Context; std::unique_ptr TM; private: static bool NativeTargetInitialized; }; class ModuleBuilder { public: ModuleBuilder(LLVMContext &Context, StringRef Triple, StringRef Name); template Function* createFunctionDecl(StringRef Name) { return Function::Create( TypeBuilder::get(M->getContext()), GlobalValue::ExternalLinkage, Name, M.get()); } Module* getModule() { return M.get(); } const Module* getModule() const { return M.get(); } std::unique_ptr takeModule() { return std::move(M); } private: std::unique_ptr M; }; // Dummy struct type. struct DummyStruct { int X[256]; }; // TypeBuilder specialization for DummyStruct. template class TypeBuilder { public: static StructType *get(LLVMContext &Context) { return StructType::get( TypeBuilder[256], XCompile>::get(Context), nullptr); } }; template class MockBaseLayer { public: typedef HandleT ModuleSetHandleT; MockBaseLayer(AddModuleSetFtor &&AddModuleSet, RemoveModuleSetFtor &&RemoveModuleSet, FindSymbolFtor &&FindSymbol, FindSymbolInFtor &&FindSymbolIn) : AddModuleSet(AddModuleSet), RemoveModuleSet(RemoveModuleSet), FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn) {} template 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 MockBaseLayer createMockBaseLayer(AddModuleSetFtor &&AddModuleSet, RemoveModuleSetFtor &&RemoveModuleSet, FindSymbolFtor &&FindSymbol, FindSymbolInFtor &&FindSymbolIn) { return MockBaseLayer( std::forward(AddModuleSet), std::forward(RemoveModuleSet), std::forward(FindSymbol), std::forward(FindSymbolIn)); } template class DoNothingAndReturn { public: DoNothingAndReturn(ReturnT Val) : Val(Val) {} template ReturnT operator()(Args...) const { return Val; } private: ReturnT Val; }; template <> class DoNothingAndReturn { public: template void operator()(Args...) const { } }; } // namespace llvm #endif