<div dir="ltr"><div>Greetings, LLVM wizards,</div><div><br></div><div>I am trying to use Clang to compile a function in memory once, then to execute it several times with different parameters. That is, I want to keep the resulting ExecutionEngine instance around and reuse it. (Or, if there is a better way to do this, I am open to suggestions.) (And if this is not the right mailing list for this kind of question, I am open to suggestions, too.)<br></div><div><br></div><div>In the code below, the ExecutionEngine works fine if I use it immediately. But if I return from the function and use it afterward, I get memory corruption and crashes, presumably because it contains references to something that has been deleted. And in fact, if I change the code so that the CodeGenAction is not deleted, it seems to work.</div><div><br></div><div>My question is: why should deleting the CodeGenAction corrupt the ExecutionEngine? Are there other things I should avoid deleting as well? (The following code was adapted from the clang-interpreter example in the v4.0.1 source code.)</div><div><br></div><div>Geoff</div><div><br></div><div><br></div><div><font face="monospace,monospace">ExecutionEngine* compile(const std::string& filename)<br>{<br>    const char *resource_dir = getenv("CLANG_RESOURCE_DIR");<br>    if (resource_dir == NULL) {<br>        std::cerr << "Clang resource directory has not been defined.\n";<br>        return NULL;<br>    }<br><br>    IntrusiveRefCntPtr<DiagnosticO<wbr>ptions> diag_opts(new DiagnosticOptions);<br>    TextDiagnosticPrinter *diag_client =<br>        new TextDiagnosticPrinter(llvm::er<wbr>rs(), diag_opts.get());<br>    IntrusiveRefCntPtr<DiagnosticI<wbr>Ds> diag_ids(new DiagnosticIDs);<br>    DiagnosticsEngine diags(diag_ids, diag_opts.get(), diag_client);<br>    std::string executable = "dg2";<br>    Driver driver(executable, llvm::sys::getDefaultTargetTri<wbr>ple(), diags);<br><br>    SmallVector<const char*, 16> args;<br>    args.push_back(executable.c_st<wbr>r());<br>    args.push_back(filename.c_str(<wbr>));<br>    args.push_back("-fsyntax-only"<wbr>);<br>    args.push_back("-fno-use-cxa-a<wbr>texit");<br>    args.push_back("-resource-dir"<wbr>);<br>    args.push_back(resource_dir);<br>    args.push_back("-std=c++11");<br>    args.push_back("-O3");<br><br>    std::unique_ptr<Compilation> compilation(driver.BuildCompil<wbr>ation(args));<br>    const JobList& jobs = compilation->getJobs();<br>    if (jobs.size() != 1 || !llvm::isa<Command>(*jobs.begi<wbr>n())) {<br>        std::cerr << "Expected a single Command job from Compilation...\n";<br>        return NULL;<br>    }<br><br>    const Command& cmd = llvm::cast<Command>(*jobs.begi<wbr>n());<br>    if (StringRef(cmd.getCreator().ge<wbr>tName()) != "clang") {<br>        std::cerr << "Expected a single clang Command from Compilation...\n";<br>        return NULL;<br>    }<br><br>    const ArgStringList& ccargs = cmd.getArguments();<br>    std::unique_ptr<CompilerInvoca<wbr>tion> invocation(new CompilerInvocation);<br>    CompilerInvocation::CreateFrom<wbr>Args(<br>        *invocation,<br>        const_cast<const char**>(ccargs.data()),<br>        const_cast<const char**>(ccargs.data()) + ccargs.size(),<br>        diags);<br><br>    CompilerInstance clang;<br>    clang.setInvocation(std::move(<wbr>invocation));<br>    clang.createDiagnostics();<br><br>    std::unique_ptr<CodeGenAction> action(new EmitLLVMOnlyAction);<br>    if (!clang.ExecuteAction(*action)<wbr>) {<br>        return NULL;<br>    }<br>    std::unique_ptr<Module> module(action->takeModule());<br><br>    llvm::InitializeNativeTarget()<wbr>;<br>    llvm::InitializeNativeTargetAs<wbr>mPrinter();<br><br>    std::string error;<br><br>    ExecutionEngine *exec_engine =<br>        EngineBuilder(std::move(module<wbr>))<br>        .setEngineKind(llvm::EngineKin<wbr>d::Either)<br>        .setErrorStr(&error)<br>        .create();<br><br>    if (!exec_engine) {<br>        std::cerr << "Could not create execution engine: " << error << std::endl;<br>        return NULL;<br>    }<br><br>    exec_engine->finalizeObject();<br>    return exec_engine;<br>}<br></font><br></div></div>