diff --git a/include/cling/Interpreter/Interpreter.h b/include/cling/Interpreter/Interpreter.h index 166a6b75..32877785 100644 --- a/include/cling/Interpreter/Interpreter.h +++ b/include/cling/Interpreter/Interpreter.h @@ -624,6 +624,9 @@ namespace cling { /// void AddAtExitFunc(void (*Func) (void*), void* Arg); + ///\brief Forwards to cling::IncrementalExecutor::addModule. + /// + void addModule(llvm::Module* module); void GenerateAutoloadingMap(llvm::StringRef inFile, llvm::StringRef outFile, bool enableMacros = false, bool enableLogs = true); diff --git a/lib/Interpreter/IncrementalExecutor.cpp b/lib/Interpreter/IncrementalExecutor.cpp index 2d7839d5..733a4944 100644 --- a/lib/Interpreter/IncrementalExecutor.cpp +++ b/lib/Interpreter/IncrementalExecutor.cpp @@ -262,7 +262,7 @@ IncrementalExecutor::executeFunction(llvm::StringRef funcname, PromptWrapper_t wrapperFunction; void* address; } p2f; - p2f.address = m_engine->getPointerToFunction(f); + p2f.address = (void*)m_engine->getFunctionAddress(funcname); // check if there is any unresolved symbol in the list if (diagnoseUnresolvedSymbols(funcname, "function")) @@ -279,6 +279,8 @@ IncrementalExecutor::runStaticInitializersOnce(llvm::Module* m) { assert(m && "Module must not be null"); assert(m_engine && "Code generation did not create an engine!"); + m_engine->finalizeObject(); + llvm::GlobalVariable* GV = m->getGlobalVariable("llvm.global_ctors", true); // Nothing to do is good, too. @@ -402,6 +404,11 @@ IncrementalExecutor::addSymbol(const char* symbolName, void* symbolAddress) { return true; } +void IncrementalExecutor::addModule(llvm::Module* module) { + m_engine->addModule(module); +} + + void* IncrementalExecutor::getAddressOfGlobal(llvm::Module* m, llvm::StringRef symbolName, bool* fromJIT /*=0*/) { diff --git a/lib/Interpreter/IncrementalExecutor.h b/lib/Interpreter/IncrementalExecutor.h index 56e7acaa..f1ef7090 100644 --- a/lib/Interpreter/IncrementalExecutor.h +++ b/lib/Interpreter/IncrementalExecutor.h @@ -148,6 +148,12 @@ namespace cling { /// bool addSymbol(const char* symbolName, void* symbolAddress); + ///\brief Add a llvm::Module to the ExecutionEngine, see + /// ExecutionEngine::addModule() + /// + /// @param[in] module - The module to pass to the execution engine. + void addModule(llvm::Module* module); + ///\brief Tells the execution context that we are shutting down the system. /// /// This that notification is needed because the execution context needs to diff --git a/lib/Interpreter/IncrementalParser.cpp b/lib/Interpreter/IncrementalParser.cpp index 1c94f39e..fba2dcd3 100644 --- a/lib/Interpreter/IncrementalParser.cpp +++ b/lib/Interpreter/IncrementalParser.cpp @@ -15,6 +15,7 @@ #include "DeclCollector.h" #include "DeclExtractor.h" #include "DynamicLookup.h" +#include "IncrementalExecutor.h" #include "NullDerefProtectionTransformer.h" #include "ValueExtractionSynthesizer.h" #include "TransactionPool.h" @@ -155,7 +156,7 @@ namespace cling { IncrementalParser::IncrementalParser(Interpreter* interp, int argc, const char* const *argv, const char* llvmdir): - m_Interpreter(interp), m_Consumer(0) { + m_Interpreter(interp), m_Consumer(0), m_ModuleNo(0) { CompilerInstance* CI = CIFactory::createCI("", argc, argv, llvmdir); assert(CI && "CompilerInstance is (null)!"); @@ -166,7 +167,7 @@ namespace cling { m_CI.reset(CI); if (CI->getFrontendOpts().ProgramAction != clang::frontend::ParseSyntaxOnly){ - m_CodeGen.reset(CreateLLVMCodeGen(CI->getDiagnostics(), "cling input", + m_CodeGen.reset(CreateLLVMCodeGen(CI->getDiagnostics(), "cling-module-0", CI->getCodeGenOpts(), CI->getTargetOpts(), *m_Interpreter->getLLVMContext() @@ -271,9 +272,6 @@ namespace cling { } IncrementalParser::~IncrementalParser() { - if (hasCodeGenerator()) { - getCodeGenerator()->ReleaseModule(); - } const Transaction* T = getFirstTransaction(); const Transaction* nextT = 0; while (T) { @@ -579,6 +577,25 @@ namespace cling { } // for deserialized DGRs getCodeGenerator()->HandleTranslationUnit(getCI()->getASTContext()); + + // This llvm::Module is done; finalize it and pass it to the execution + // engine. + if (!T->isNestedTransaction() && hasCodeGenerator()) { + if (llvm::Module* M = getCodeGenerator()->ReleaseModule()) { + assert(M == T->getModule() && "Transaction has inconsistent module"); + m_Interpreter->addModule(M); + } + + // Create a new module. + std::string ModuleName; + { + llvm::raw_string_ostream strm(ModuleName); + strm << "cling-module-" << ++m_ModuleNo; + } + getCodeGenerator()->StartModule(ModuleName, + *m_Interpreter->getLLVMContext()); + } + if ((deserT = endTransaction(deserT))) commitTransaction(deserT); } diff --git a/lib/Interpreter/IncrementalParser.h b/lib/Interpreter/IncrementalParser.h index 389b8bab..f9614546 100644 --- a/lib/Interpreter/IncrementalParser.h +++ b/lib/Interpreter/IncrementalParser.h @@ -77,6 +77,9 @@ namespace cling { /// std::deque m_Transactions; + ///\brief Number of created modules. + unsigned m_ModuleNo; + ///\brief Code generator /// std::unique_ptr m_CodeGen; diff --git a/lib/Interpreter/Interpreter.cpp b/lib/Interpreter/Interpreter.cpp index 5ef19130..adfe6e1d 100644 --- a/lib/Interpreter/Interpreter.cpp +++ b/lib/Interpreter/Interpreter.cpp @@ -1136,7 +1136,7 @@ namespace cling { assert(T.getState() == Transaction::kCommitted && "Must be committed"); // Forward to IncrementalExecutor; should not be called by // anyone except for IncrementalParser. - llvm::Module* module = m_IncrParser->getCodeGenerator()->GetModule(); + llvm::Module* module = T.getModule(); IncrementalExecutor::ExecutionResult ExeRes = m_Executor->runStaticInitializersOnce(module); @@ -1161,6 +1161,11 @@ namespace cling { return m_Executor->addSymbol(symbolName, symbolAddress); } + void Interpreter::addModule(llvm::Module* module) { + m_Executor->addModule(module); + } + + void* Interpreter::getAddressOfGlobal(const GlobalDecl& GD, bool* fromJIT /*=0*/) const { // Return a symbol's address, and whether it was jitted.