xref: /llvm-project/clang/lib/Interpreter/Interpreter.cpp (revision 61ab36a3e226df32855286dd31a2c3859800475d)
192f9852fSVassil Vassilev //===------ Interpreter.cpp - Incremental Compilation and Execution -------===//
292f9852fSVassil Vassilev //
392f9852fSVassil Vassilev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
492f9852fSVassil Vassilev // See https://llvm.org/LICENSE.txt for license information.
592f9852fSVassil Vassilev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
692f9852fSVassil Vassilev //
792f9852fSVassil Vassilev //===----------------------------------------------------------------------===//
892f9852fSVassil Vassilev //
992f9852fSVassil Vassilev // This file implements the component which performs incremental code
1092f9852fSVassil Vassilev // compilation and execution.
1192f9852fSVassil Vassilev //
1292f9852fSVassil Vassilev //===----------------------------------------------------------------------===//
1392f9852fSVassil Vassilev 
14ddeab07cSAnubhab Ghosh #include "DeviceOffload.h"
1592f9852fSVassil Vassilev #include "IncrementalExecutor.h"
1692f9852fSVassil Vassilev #include "IncrementalParser.h"
17752f87cdSVassil Vassilev #include "InterpreterUtils.h"
18df9a14d7SKadir Cetinkaya #include "llvm/Support/VirtualFileSystem.h"
199a9546e3SVassil Vassilev #ifdef __EMSCRIPTEN__
209a9546e3SVassil Vassilev #include "Wasm.h"
219a9546e3SVassil Vassilev #endif // __EMSCRIPTEN__
2279af92bbSFred Fu 
23a72d7eeaSVassil Vassilev #include "clang/AST/ASTConsumer.h"
2449f95321SVassil Vassilev #include "clang/AST/ASTContext.h"
255111286fSJun Zhang #include "clang/AST/Mangle.h"
265111286fSJun Zhang #include "clang/AST/TypeVisitor.h"
275111286fSJun Zhang #include "clang/Basic/DiagnosticSema.h"
2892f9852fSVassil Vassilev #include "clang/Basic/TargetInfo.h"
29ddeab07cSAnubhab Ghosh #include "clang/CodeGen/CodeGenAction.h"
3092f9852fSVassil Vassilev #include "clang/CodeGen/ModuleBuilder.h"
31d64eccf4SChuanqi Xu #include "clang/CodeGen/ObjectFilePCHContainerWriter.h"
3292f9852fSVassil Vassilev #include "clang/Driver/Compilation.h"
3392f9852fSVassil Vassilev #include "clang/Driver/Driver.h"
3492f9852fSVassil Vassilev #include "clang/Driver/Job.h"
3592f9852fSVassil Vassilev #include "clang/Driver/Options.h"
3692f9852fSVassil Vassilev #include "clang/Driver/Tool.h"
3792f9852fSVassil Vassilev #include "clang/Frontend/CompilerInstance.h"
38a72d7eeaSVassil Vassilev #include "clang/Frontend/FrontendAction.h"
39a72d7eeaSVassil Vassilev #include "clang/Frontend/MultiplexConsumer.h"
4092f9852fSVassil Vassilev #include "clang/Frontend/TextDiagnosticBuffer.h"
41a72d7eeaSVassil Vassilev #include "clang/FrontendTool/Utils.h"
4279af92bbSFred Fu #include "clang/Interpreter/Interpreter.h"
435111286fSJun Zhang #include "clang/Interpreter/Value.h"
4492f9852fSVassil Vassilev #include "clang/Lex/PreprocessorOptions.h"
455111286fSJun Zhang #include "clang/Sema/Lookup.h"
46d64eccf4SChuanqi Xu #include "clang/Serialization/ObjectFilePCHContainerReader.h"
475111286fSJun Zhang #include "llvm/ExecutionEngine/JITSymbol.h"
48d978730dSAnubhab Ghosh #include "llvm/ExecutionEngine/Orc/LLJIT.h"
4992f9852fSVassil Vassilev #include "llvm/IR/Module.h"
506283d468SLuke Drummond #include "llvm/Support/Errc.h"
515111286fSJun Zhang #include "llvm/Support/ErrorHandling.h"
525111286fSJun Zhang #include "llvm/Support/raw_ostream.h"
53d768bf99SArchibald Elliott #include "llvm/TargetParser/Host.h"
54a8744066SVassil Vassilev #include "llvm/Transforms/Utils/Cloning.h" // for CloneModule
55a8744066SVassil Vassilev 
56a8744066SVassil Vassilev #define DEBUG_TYPE "clang-repl"
577091dfc0SVassil Vassilev 
5892f9852fSVassil Vassilev using namespace clang;
5992f9852fSVassil Vassilev // FIXME: Figure out how to unify with namespace init_convenience from
60c24a5808SVassil Vassilev //        tools/clang-import-test/clang-import-test.cpp
6192f9852fSVassil Vassilev namespace {
6292f9852fSVassil Vassilev /// Retrieves the clang CC1 specific flags out of the compilation's jobs.
6392f9852fSVassil Vassilev /// \returns NULL on error.
6492f9852fSVassil Vassilev static llvm::Expected<const llvm::opt::ArgStringList *>
6592f9852fSVassil Vassilev GetCC1Arguments(DiagnosticsEngine *Diagnostics,
6692f9852fSVassil Vassilev                 driver::Compilation *Compilation) {
6792f9852fSVassil Vassilev   // We expect to get back exactly one Command job, if we didn't something
6892f9852fSVassil Vassilev   // failed. Extract that job from the Compilation.
6992f9852fSVassil Vassilev   const driver::JobList &Jobs = Compilation->getJobs();
7092f9852fSVassil Vassilev   if (!Jobs.size() || !isa<driver::Command>(*Jobs.begin()))
716283d468SLuke Drummond     return llvm::createStringError(llvm::errc::not_supported,
7292f9852fSVassil Vassilev                                    "Driver initialization failed. "
7392f9852fSVassil Vassilev                                    "Unable to create a driver job");
7492f9852fSVassil Vassilev 
7592f9852fSVassil Vassilev   // The one job we find should be to invoke clang again.
7692f9852fSVassil Vassilev   const driver::Command *Cmd = cast<driver::Command>(&(*Jobs.begin()));
7792f9852fSVassil Vassilev   if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
786283d468SLuke Drummond     return llvm::createStringError(llvm::errc::not_supported,
7992f9852fSVassil Vassilev                                    "Driver initialization failed");
8092f9852fSVassil Vassilev 
8192f9852fSVassil Vassilev   return &Cmd->getArguments();
8292f9852fSVassil Vassilev }
8392f9852fSVassil Vassilev 
8492f9852fSVassil Vassilev static llvm::Expected<std::unique_ptr<CompilerInstance>>
8592f9852fSVassil Vassilev CreateCI(const llvm::opt::ArgStringList &Argv) {
8692f9852fSVassil Vassilev   std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
8792f9852fSVassil Vassilev   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
8892f9852fSVassil Vassilev 
8992f9852fSVassil Vassilev   // Register the support for object-file-wrapped Clang modules.
9092f9852fSVassil Vassilev   // FIXME: Clang should register these container operations automatically.
9192f9852fSVassil Vassilev   auto PCHOps = Clang->getPCHContainerOperations();
9292f9852fSVassil Vassilev   PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
9392f9852fSVassil Vassilev   PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
9492f9852fSVassil Vassilev 
9592f9852fSVassil Vassilev   // Buffer diagnostics from argument parsing so that we can output them using
9692f9852fSVassil Vassilev   // a well formed diagnostic object.
9792f9852fSVassil Vassilev   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
9892f9852fSVassil Vassilev   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
9992f9852fSVassil Vassilev   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
10092f9852fSVassil Vassilev   bool Success = CompilerInvocation::CreateFromArgs(
101a3c248dbSserge-sans-paille       Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
10292f9852fSVassil Vassilev 
10392f9852fSVassil Vassilev   // Infer the builtin include path if unspecified.
10492f9852fSVassil Vassilev   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
10592f9852fSVassil Vassilev       Clang->getHeaderSearchOpts().ResourceDir.empty())
10692f9852fSVassil Vassilev     Clang->getHeaderSearchOpts().ResourceDir =
10792f9852fSVassil Vassilev         CompilerInvocation::GetResourcesPath(Argv[0], nullptr);
10892f9852fSVassil Vassilev 
10992f9852fSVassil Vassilev   // Create the actual diagnostics engine.
110df9a14d7SKadir Cetinkaya   Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
11192f9852fSVassil Vassilev   if (!Clang->hasDiagnostics())
1126283d468SLuke Drummond     return llvm::createStringError(llvm::errc::not_supported,
11392f9852fSVassil Vassilev                                    "Initialization failed. "
11492f9852fSVassil Vassilev                                    "Unable to create diagnostics engine");
11592f9852fSVassil Vassilev 
11692f9852fSVassil Vassilev   DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
11792f9852fSVassil Vassilev   if (!Success)
1186283d468SLuke Drummond     return llvm::createStringError(llvm::errc::not_supported,
11992f9852fSVassil Vassilev                                    "Initialization failed. "
12092f9852fSVassil Vassilev                                    "Unable to flush diagnostics");
12192f9852fSVassil Vassilev 
12292f9852fSVassil Vassilev   // FIXME: Merge with CompilerInstance::ExecuteAction.
12392f9852fSVassil Vassilev   llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release();
12492f9852fSVassil Vassilev   Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
12592f9852fSVassil Vassilev 
12692f9852fSVassil Vassilev   Clang->setTarget(TargetInfo::CreateTargetInfo(
12792f9852fSVassil Vassilev       Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
12892f9852fSVassil Vassilev   if (!Clang->hasTarget())
1296283d468SLuke Drummond     return llvm::createStringError(llvm::errc::not_supported,
13092f9852fSVassil Vassilev                                    "Initialization failed. "
13192f9852fSVassil Vassilev                                    "Target is missing");
13292f9852fSVassil Vassilev 
133aaba3718SMelanie Blower   Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts());
13492f9852fSVassil Vassilev 
13519b07ec0SArthur Eubanks   // Don't clear the AST before backend codegen since we do codegen multiple
13619b07ec0SArthur Eubanks   // times, reusing the same AST.
13719b07ec0SArthur Eubanks   Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
13819b07ec0SArthur Eubanks 
1397bc00ce5SSunho Kim   Clang->getFrontendOpts().DisableFree = false;
1407bc00ce5SSunho Kim   Clang->getCodeGenOpts().DisableFree = false;
14192f9852fSVassil Vassilev   return std::move(Clang);
14292f9852fSVassil Vassilev }
14392f9852fSVassil Vassilev 
14492f9852fSVassil Vassilev } // anonymous namespace
14592f9852fSVassil Vassilev 
146a72d7eeaSVassil Vassilev namespace clang {
147a72d7eeaSVassil Vassilev 
14892f9852fSVassil Vassilev llvm::Expected<std::unique_ptr<CompilerInstance>>
1492a4a852aSStefan Gränitz IncrementalCompilerBuilder::create(std::string TT,
1502a4a852aSStefan Gränitz                                    std::vector<const char *> &ClangArgv) {
15192f9852fSVassil Vassilev 
15292f9852fSVassil Vassilev   // If we don't know ClangArgv0 or the address of main() at this point, try
15392f9852fSVassil Vassilev   // to guess it anyway (it's possible on some platforms).
15492f9852fSVassil Vassilev   std::string MainExecutableName =
15592f9852fSVassil Vassilev       llvm::sys::fs::getMainExecutable(nullptr, nullptr);
15692f9852fSVassil Vassilev 
15792f9852fSVassil Vassilev   ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
15892f9852fSVassil Vassilev 
15992f9852fSVassil Vassilev   // Prepending -c to force the driver to do something if no action was
16092f9852fSVassil Vassilev   // specified. By prepending we allow users to override the default
16192f9852fSVassil Vassilev   // action and use other actions in incremental mode.
16292f9852fSVassil Vassilev   // FIXME: Print proper driver diagnostics if the driver flags are wrong.
16392f9852fSVassil Vassilev   // We do C++ by default; append right after argv[0] if no "-x" given
164dc488935SVassil Vassilev   ClangArgv.insert(ClangArgv.end(), "-Xclang");
165dc488935SVassil Vassilev   ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions");
166dc488935SVassil Vassilev   ClangArgv.insert(ClangArgv.end(), "-c");
16792f9852fSVassil Vassilev 
16892f9852fSVassil Vassilev   // Put a dummy C++ file on to ensure there's at least one compile job for the
16992f9852fSVassil Vassilev   // driver to construct.
17092f9852fSVassil Vassilev   ClangArgv.push_back("<<< inputs >>>");
17192f9852fSVassil Vassilev 
17292f9852fSVassil Vassilev   // Buffer diagnostics from argument parsing so that we can output them using a
17392f9852fSVassil Vassilev   // well formed diagnostic object.
17492f9852fSVassil Vassilev   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
175555a817dSJan Svoboda   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
176555a817dSJan Svoboda       CreateAndPopulateDiagOpts(ClangArgv);
17792f9852fSVassil Vassilev   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
17892f9852fSVassil Vassilev   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
17992f9852fSVassil Vassilev 
1802a4a852aSStefan Gränitz   driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
18192f9852fSVassil Vassilev   Driver.setCheckInputsExist(false); // the input comes from mem buffers
182a3c248dbSserge-sans-paille   llvm::ArrayRef<const char *> RF = llvm::ArrayRef(ClangArgv);
18392f9852fSVassil Vassilev   std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(RF));
18492f9852fSVassil Vassilev 
18592f9852fSVassil Vassilev   if (Compilation->getArgs().hasArg(driver::options::OPT_v))
18692f9852fSVassil Vassilev     Compilation->getJobs().Print(llvm::errs(), "\n", /*Quote=*/false);
18792f9852fSVassil Vassilev 
18892f9852fSVassil Vassilev   auto ErrOrCC1Args = GetCC1Arguments(&Diags, Compilation.get());
18992f9852fSVassil Vassilev   if (auto Err = ErrOrCC1Args.takeError())
19092f9852fSVassil Vassilev     return std::move(Err);
19192f9852fSVassil Vassilev 
19292f9852fSVassil Vassilev   return CreateCI(**ErrOrCC1Args);
19392f9852fSVassil Vassilev }
19492f9852fSVassil Vassilev 
195ddeab07cSAnubhab Ghosh llvm::Expected<std::unique_ptr<CompilerInstance>>
196ddeab07cSAnubhab Ghosh IncrementalCompilerBuilder::CreateCpp() {
197ddeab07cSAnubhab Ghosh   std::vector<const char *> Argv;
198ddeab07cSAnubhab Ghosh   Argv.reserve(5 + 1 + UserArgs.size());
199ddeab07cSAnubhab Ghosh   Argv.push_back("-xc++");
2009a9546e3SVassil Vassilev #ifdef __EMSCRIPTEN__
2019a9546e3SVassil Vassilev   Argv.push_back("-target");
2029a9546e3SVassil Vassilev   Argv.push_back("wasm32-unknown-emscripten");
203a174aa1eSAnutosh Bhat   Argv.push_back("-fvisibility=default");
2049a9546e3SVassil Vassilev #endif
205ddeab07cSAnubhab Ghosh   Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
206ddeab07cSAnubhab Ghosh 
2072a4a852aSStefan Gränitz   std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
2082a4a852aSStefan Gränitz   return IncrementalCompilerBuilder::create(TT, Argv);
209ddeab07cSAnubhab Ghosh }
210ddeab07cSAnubhab Ghosh 
211ddeab07cSAnubhab Ghosh llvm::Expected<std::unique_ptr<CompilerInstance>>
212ddeab07cSAnubhab Ghosh IncrementalCompilerBuilder::createCuda(bool device) {
213ddeab07cSAnubhab Ghosh   std::vector<const char *> Argv;
214ddeab07cSAnubhab Ghosh   Argv.reserve(5 + 4 + UserArgs.size());
215ddeab07cSAnubhab Ghosh 
216ddeab07cSAnubhab Ghosh   Argv.push_back("-xcuda");
217ddeab07cSAnubhab Ghosh   if (device)
218ddeab07cSAnubhab Ghosh     Argv.push_back("--cuda-device-only");
219ddeab07cSAnubhab Ghosh   else
220ddeab07cSAnubhab Ghosh     Argv.push_back("--cuda-host-only");
221ddeab07cSAnubhab Ghosh 
222ddeab07cSAnubhab Ghosh   std::string SDKPathArg = "--cuda-path=";
223ddeab07cSAnubhab Ghosh   if (!CudaSDKPath.empty()) {
224ddeab07cSAnubhab Ghosh     SDKPathArg += CudaSDKPath;
225ddeab07cSAnubhab Ghosh     Argv.push_back(SDKPathArg.c_str());
226ddeab07cSAnubhab Ghosh   }
227ddeab07cSAnubhab Ghosh 
228ddeab07cSAnubhab Ghosh   std::string ArchArg = "--offload-arch=";
229ddeab07cSAnubhab Ghosh   if (!OffloadArch.empty()) {
230ddeab07cSAnubhab Ghosh     ArchArg += OffloadArch;
231ddeab07cSAnubhab Ghosh     Argv.push_back(ArchArg.c_str());
232ddeab07cSAnubhab Ghosh   }
233ddeab07cSAnubhab Ghosh 
234ddeab07cSAnubhab Ghosh   Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
235ddeab07cSAnubhab Ghosh 
2362a4a852aSStefan Gränitz   std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
2372a4a852aSStefan Gränitz   return IncrementalCompilerBuilder::create(TT, Argv);
238ddeab07cSAnubhab Ghosh }
239ddeab07cSAnubhab Ghosh 
240ddeab07cSAnubhab Ghosh llvm::Expected<std::unique_ptr<CompilerInstance>>
241ddeab07cSAnubhab Ghosh IncrementalCompilerBuilder::CreateCudaDevice() {
242ddeab07cSAnubhab Ghosh   return IncrementalCompilerBuilder::createCuda(true);
243ddeab07cSAnubhab Ghosh }
244ddeab07cSAnubhab Ghosh 
245ddeab07cSAnubhab Ghosh llvm::Expected<std::unique_ptr<CompilerInstance>>
246ddeab07cSAnubhab Ghosh IncrementalCompilerBuilder::CreateCudaHost() {
247ddeab07cSAnubhab Ghosh   return IncrementalCompilerBuilder::createCuda(false);
248ddeab07cSAnubhab Ghosh }
249ddeab07cSAnubhab Ghosh 
250a72d7eeaSVassil Vassilev class InProcessPrintingASTConsumer final : public MultiplexConsumer {
251a72d7eeaSVassil Vassilev   Interpreter &Interp;
252a72d7eeaSVassil Vassilev 
253a72d7eeaSVassil Vassilev public:
254a72d7eeaSVassil Vassilev   InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I)
255a72d7eeaSVassil Vassilev       : MultiplexConsumer(std::move(C)), Interp(I) {}
256a72d7eeaSVassil Vassilev   bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
257a72d7eeaSVassil Vassilev     if (DGR.isNull())
258a72d7eeaSVassil Vassilev       return true;
259a72d7eeaSVassil Vassilev 
260a72d7eeaSVassil Vassilev     for (Decl *D : DGR)
261a72d7eeaSVassil Vassilev       if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(D))
262a72d7eeaSVassil Vassilev         if (TLSD && TLSD->isSemiMissing()) {
263a72d7eeaSVassil Vassilev           auto ExprOrErr =
264a72d7eeaSVassil Vassilev               Interp.ExtractValueFromExpr(cast<Expr>(TLSD->getStmt()));
265a72d7eeaSVassil Vassilev           if (llvm::Error E = ExprOrErr.takeError()) {
266a72d7eeaSVassil Vassilev             llvm::logAllUnhandledErrors(std::move(E), llvm::errs(),
267a72d7eeaSVassil Vassilev                                         "Value printing failed: ");
268a72d7eeaSVassil Vassilev             return false; // abort parsing
269a72d7eeaSVassil Vassilev           }
270a72d7eeaSVassil Vassilev           TLSD->setStmt(*ExprOrErr);
271a72d7eeaSVassil Vassilev         }
272a72d7eeaSVassil Vassilev 
273a72d7eeaSVassil Vassilev     return MultiplexConsumer::HandleTopLevelDecl(DGR);
274a72d7eeaSVassil Vassilev   }
275a72d7eeaSVassil Vassilev };
276a72d7eeaSVassil Vassilev 
277a72d7eeaSVassil Vassilev /// A custom action enabling the incremental processing functionality.
278a72d7eeaSVassil Vassilev ///
279a72d7eeaSVassil Vassilev /// The usual \p FrontendAction expects one call to ExecuteAction and once it
280a72d7eeaSVassil Vassilev /// sees a call to \p EndSourceFile it deletes some of the important objects
281a72d7eeaSVassil Vassilev /// such as \p Preprocessor and \p Sema assuming no further input will come.
282a72d7eeaSVassil Vassilev ///
283a72d7eeaSVassil Vassilev /// \p IncrementalAction ensures it keep its underlying action's objects alive
284a72d7eeaSVassil Vassilev /// as long as the \p IncrementalParser needs them.
285a72d7eeaSVassil Vassilev ///
286a72d7eeaSVassil Vassilev class IncrementalAction : public WrapperFrontendAction {
287a72d7eeaSVassil Vassilev private:
288a72d7eeaSVassil Vassilev   bool IsTerminating = false;
289a72d7eeaSVassil Vassilev   Interpreter &Interp;
290a72d7eeaSVassil Vassilev   std::unique_ptr<ASTConsumer> Consumer;
291a72d7eeaSVassil Vassilev 
292a72d7eeaSVassil Vassilev public:
293a72d7eeaSVassil Vassilev   IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
294a72d7eeaSVassil Vassilev                     llvm::Error &Err, Interpreter &I,
295a72d7eeaSVassil Vassilev                     std::unique_ptr<ASTConsumer> Consumer = nullptr)
296a72d7eeaSVassil Vassilev       : WrapperFrontendAction([&]() {
297a72d7eeaSVassil Vassilev           llvm::ErrorAsOutParameter EAO(&Err);
298a72d7eeaSVassil Vassilev           std::unique_ptr<FrontendAction> Act;
299a72d7eeaSVassil Vassilev           switch (CI.getFrontendOpts().ProgramAction) {
300a72d7eeaSVassil Vassilev           default:
301a72d7eeaSVassil Vassilev             Err = llvm::createStringError(
302a72d7eeaSVassil Vassilev                 std::errc::state_not_recoverable,
303a72d7eeaSVassil Vassilev                 "Driver initialization failed. "
304a72d7eeaSVassil Vassilev                 "Incremental mode for action %d is not supported",
305a72d7eeaSVassil Vassilev                 CI.getFrontendOpts().ProgramAction);
306a72d7eeaSVassil Vassilev             return Act;
307a72d7eeaSVassil Vassilev           case frontend::ASTDump:
308a72d7eeaSVassil Vassilev           case frontend::ASTPrint:
309a72d7eeaSVassil Vassilev           case frontend::ParseSyntaxOnly:
310a72d7eeaSVassil Vassilev             Act = CreateFrontendAction(CI);
311a72d7eeaSVassil Vassilev             break;
312a72d7eeaSVassil Vassilev           case frontend::PluginAction:
313a72d7eeaSVassil Vassilev           case frontend::EmitAssembly:
314a72d7eeaSVassil Vassilev           case frontend::EmitBC:
315a72d7eeaSVassil Vassilev           case frontend::EmitObj:
316a72d7eeaSVassil Vassilev           case frontend::PrintPreprocessedInput:
317a72d7eeaSVassil Vassilev           case frontend::EmitLLVMOnly:
318a72d7eeaSVassil Vassilev             Act.reset(new EmitLLVMOnlyAction(&LLVMCtx));
319a72d7eeaSVassil Vassilev             break;
320a72d7eeaSVassil Vassilev           }
321a72d7eeaSVassil Vassilev           return Act;
322a72d7eeaSVassil Vassilev         }()),
323a72d7eeaSVassil Vassilev         Interp(I), Consumer(std::move(Consumer)) {}
324a72d7eeaSVassil Vassilev   FrontendAction *getWrapped() const { return WrappedAction.get(); }
325a72d7eeaSVassil Vassilev   TranslationUnitKind getTranslationUnitKind() override {
326a72d7eeaSVassil Vassilev     return TU_Incremental;
327a72d7eeaSVassil Vassilev   }
328a72d7eeaSVassil Vassilev 
329a72d7eeaSVassil Vassilev   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
330a72d7eeaSVassil Vassilev                                                  StringRef InFile) override {
331a72d7eeaSVassil Vassilev     std::unique_ptr<ASTConsumer> C =
332a72d7eeaSVassil Vassilev         WrapperFrontendAction::CreateASTConsumer(CI, InFile);
333a72d7eeaSVassil Vassilev 
334a72d7eeaSVassil Vassilev     if (Consumer) {
335a72d7eeaSVassil Vassilev       std::vector<std::unique_ptr<ASTConsumer>> Cs;
336a72d7eeaSVassil Vassilev       Cs.push_back(std::move(Consumer));
337a72d7eeaSVassil Vassilev       Cs.push_back(std::move(C));
338a72d7eeaSVassil Vassilev       return std::make_unique<MultiplexConsumer>(std::move(Cs));
339a72d7eeaSVassil Vassilev     }
340a72d7eeaSVassil Vassilev 
341a72d7eeaSVassil Vassilev     return std::make_unique<InProcessPrintingASTConsumer>(std::move(C), Interp);
342a72d7eeaSVassil Vassilev   }
343a72d7eeaSVassil Vassilev 
344a72d7eeaSVassil Vassilev   void ExecuteAction() override {
345a8744066SVassil Vassilev     WrapperFrontendAction::ExecuteAction();
346a8744066SVassil Vassilev     getCompilerInstance().getSema().CurContext = nullptr;
347a72d7eeaSVassil Vassilev   }
348a72d7eeaSVassil Vassilev 
349a72d7eeaSVassil Vassilev   // Do not terminate after processing the input. This allows us to keep various
350a72d7eeaSVassil Vassilev   // clang objects alive and to incrementally grow the current TU.
351a72d7eeaSVassil Vassilev   void EndSourceFile() override {
352a72d7eeaSVassil Vassilev     // The WrappedAction can be nullptr if we issued an error in the ctor.
353a72d7eeaSVassil Vassilev     if (IsTerminating && getWrapped())
354a72d7eeaSVassil Vassilev       WrapperFrontendAction::EndSourceFile();
355a72d7eeaSVassil Vassilev   }
356a72d7eeaSVassil Vassilev 
357a72d7eeaSVassil Vassilev   void FinalizeAction() {
358a72d7eeaSVassil Vassilev     assert(!IsTerminating && "Already finalized!");
359a72d7eeaSVassil Vassilev     IsTerminating = true;
360a72d7eeaSVassil Vassilev     EndSourceFile();
361a72d7eeaSVassil Vassilev   }
362a72d7eeaSVassil Vassilev };
363a72d7eeaSVassil Vassilev 
364a72d7eeaSVassil Vassilev Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
365cb7995a1SStefan Gränitz                          llvm::Error &ErrOut,
366a72d7eeaSVassil Vassilev                          std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder,
367a72d7eeaSVassil Vassilev                          std::unique_ptr<clang::ASTConsumer> Consumer)
368cb7995a1SStefan Gränitz     : JITBuilder(std::move(JITBuilder)) {
369a72d7eeaSVassil Vassilev   CI = std::move(Instance);
370cb7995a1SStefan Gränitz   llvm::ErrorAsOutParameter EAO(&ErrOut);
37192f9852fSVassil Vassilev   auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
37292f9852fSVassil Vassilev   TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(std::move(LLVMCtx));
373a72d7eeaSVassil Vassilev 
374a72d7eeaSVassil Vassilev   Act = std::make_unique<IncrementalAction>(*CI, *TSCtx->getContext(), ErrOut,
375a72d7eeaSVassil Vassilev                                             *this, std::move(Consumer));
376a72d7eeaSVassil Vassilev   if (ErrOut)
377a72d7eeaSVassil Vassilev     return;
378a72d7eeaSVassil Vassilev   CI->ExecuteAction(*Act);
379a72d7eeaSVassil Vassilev 
380a72d7eeaSVassil Vassilev   IncrParser = std::make_unique<IncrementalParser>(*CI, ErrOut);
381a72d7eeaSVassil Vassilev 
382cb7995a1SStefan Gränitz   if (ErrOut)
383cb7995a1SStefan Gränitz     return;
384cb7995a1SStefan Gränitz 
385a72d7eeaSVassil Vassilev   if (getCodeGen()) {
386a72d7eeaSVassil Vassilev     CachedInCodeGenModule = GenModule();
387a8744066SVassil Vassilev     // The initial PTU is filled by `-include` or by CUDA includes
388a8744066SVassil Vassilev     // automatically.
389a8744066SVassil Vassilev     if (!CI->getPreprocessorOpts().Includes.empty()) {
390a8744066SVassil Vassilev       // We can't really directly pass the CachedInCodeGenModule to the Jit
391a8744066SVassil Vassilev       // because it will steal it, causing dangling references as explained in
392a8744066SVassil Vassilev       // Interpreter::Execute
393a8744066SVassil Vassilev       auto M = llvm::CloneModule(*CachedInCodeGenModule);
394a8744066SVassil Vassilev       ASTContext &C = CI->getASTContext();
395a8744066SVassil Vassilev       RegisterPTU(C.getTranslationUnitDecl(), std::move(M));
396a8744066SVassil Vassilev     }
397cb7995a1SStefan Gränitz     if (llvm::Error Err = CreateExecutor()) {
398cb7995a1SStefan Gränitz       ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
399cb7995a1SStefan Gränitz       return;
400cb7995a1SStefan Gränitz     }
401a72d7eeaSVassil Vassilev   }
402cb7995a1SStefan Gränitz 
403a72d7eeaSVassil Vassilev   // Not all frontends support code-generation, e.g. ast-dump actions don't
404a72d7eeaSVassil Vassilev   if (getCodeGen()) {
405cb7995a1SStefan Gränitz     // Process the PTUs that came from initialization. For example -include will
406cb7995a1SStefan Gränitz     // give us a header that's processed at initialization of the preprocessor.
407a72d7eeaSVassil Vassilev     for (PartialTranslationUnit &PTU : PTUs)
408cb7995a1SStefan Gränitz       if (llvm::Error Err = Execute(PTU)) {
409cb7995a1SStefan Gränitz         ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
410cb7995a1SStefan Gränitz         return;
411cb7995a1SStefan Gränitz       }
412cb7995a1SStefan Gränitz   }
41392f9852fSVassil Vassilev }
41492f9852fSVassil Vassilev 
415c619d4f8SSunho Kim Interpreter::~Interpreter() {
416a72d7eeaSVassil Vassilev   IncrParser.reset();
417a72d7eeaSVassil Vassilev   Act->FinalizeAction();
418c619d4f8SSunho Kim   if (IncrExecutor) {
419c619d4f8SSunho Kim     if (llvm::Error Err = IncrExecutor->cleanUp())
420c619d4f8SSunho Kim       llvm::report_fatal_error(
421c619d4f8SSunho Kim           llvm::Twine("Failed to clean up IncrementalExecutor: ") +
422c619d4f8SSunho Kim           toString(std::move(Err)));
423c619d4f8SSunho Kim   }
424c619d4f8SSunho Kim }
42592f9852fSVassil Vassilev 
4265111286fSJun Zhang // These better to put in a runtime header but we can't. This is because we
4275111286fSJun Zhang // can't find the precise resource directory in unittests so we have to hard
4285111286fSJun Zhang // code them.
4295111286fSJun Zhang const char *const Runtimes = R"(
4307091dfc0SVassil Vassilev     #define __CLANG_REPL__ 1
4311566f1ffSVassil Vassilev #ifdef __cplusplus
4327091dfc0SVassil Vassilev     #define EXTERN_C extern "C"
4335111286fSJun Zhang     void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
4341566f1ffSVassil Vassilev     struct __clang_Interpreter_NewTag{} __ci_newtag;
4351566f1ffSVassil Vassilev     void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
4365111286fSJun Zhang     template <class T, class = T (*)() /*disable for arrays*/>
4375111286fSJun Zhang     void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
4385111286fSJun Zhang       for (auto Idx = 0; Idx < Size; ++Idx)
4391566f1ffSVassil Vassilev         new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
4405111286fSJun Zhang     }
4415111286fSJun Zhang     template <class T, unsigned long N>
4425111286fSJun Zhang     void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
4435111286fSJun Zhang       __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
4445111286fSJun Zhang     }
4457091dfc0SVassil Vassilev #else
4467091dfc0SVassil Vassilev     #define EXTERN_C extern
4471566f1ffSVassil Vassilev #endif // __cplusplus
4487091dfc0SVassil Vassilev 
4497091dfc0SVassil Vassilev   EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
4505111286fSJun Zhang )";
4515111286fSJun Zhang 
45292f9852fSVassil Vassilev llvm::Expected<std::unique_ptr<Interpreter>>
453ebb35088SSahilPatidar Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
45492f9852fSVassil Vassilev   llvm::Error Err = llvm::Error::success();
455ebb35088SSahilPatidar   auto Interp =
456ebb35088SSahilPatidar       std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err));
45792f9852fSVassil Vassilev   if (Err)
45892f9852fSVassil Vassilev     return std::move(Err);
45979af92bbSFred Fu 
460aec92830SStefan Gränitz   // Add runtime code and set a marker to hide it from user code. Undo will not
461aec92830SStefan Gränitz   // go through that.
4625111286fSJun Zhang   auto PTU = Interp->Parse(Runtimes);
4635111286fSJun Zhang   if (!PTU)
4645111286fSJun Zhang     return PTU.takeError();
465aec92830SStefan Gränitz   Interp->markUserCodeStart();
4665111286fSJun Zhang 
4671566f1ffSVassil Vassilev   Interp->ValuePrintingInfo.resize(4);
46892f9852fSVassil Vassilev   return std::move(Interp);
46992f9852fSVassil Vassilev }
47092f9852fSVassil Vassilev 
471ddeab07cSAnubhab Ghosh llvm::Expected<std::unique_ptr<Interpreter>>
472ddeab07cSAnubhab Ghosh Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
473ddeab07cSAnubhab Ghosh                             std::unique_ptr<CompilerInstance> DCI) {
474ddeab07cSAnubhab Ghosh   // avoid writing fat binary to disk using an in-memory virtual file system
475ddeab07cSAnubhab Ghosh   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
476ddeab07cSAnubhab Ghosh       std::make_unique<llvm::vfs::InMemoryFileSystem>();
477ddeab07cSAnubhab Ghosh   llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
478ddeab07cSAnubhab Ghosh       std::make_unique<llvm::vfs::OverlayFileSystem>(
479ddeab07cSAnubhab Ghosh           llvm::vfs::getRealFileSystem());
480ddeab07cSAnubhab Ghosh   OverlayVFS->pushOverlay(IMVFS);
481ddeab07cSAnubhab Ghosh   CI->createFileManager(OverlayVFS);
482ddeab07cSAnubhab Ghosh 
483ddeab07cSAnubhab Ghosh   auto Interp = Interpreter::create(std::move(CI));
484ddeab07cSAnubhab Ghosh   if (auto E = Interp.takeError())
485ddeab07cSAnubhab Ghosh     return std::move(E);
486ddeab07cSAnubhab Ghosh 
487ddeab07cSAnubhab Ghosh   llvm::Error Err = llvm::Error::success();
488ddeab07cSAnubhab Ghosh   auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
489a72d7eeaSVassil Vassilev       std::move(DCI), *(*Interp)->getCompilerInstance(), IMVFS, Err,
490a72d7eeaSVassil Vassilev       (*Interp)->PTUs);
491ddeab07cSAnubhab Ghosh   if (Err)
492ddeab07cSAnubhab Ghosh     return std::move(Err);
493ddeab07cSAnubhab Ghosh 
494ddeab07cSAnubhab Ghosh   (*Interp)->DeviceParser = std::move(DeviceParser);
495ddeab07cSAnubhab Ghosh 
496ddeab07cSAnubhab Ghosh   return Interp;
497ddeab07cSAnubhab Ghosh }
498ddeab07cSAnubhab Ghosh 
49992f9852fSVassil Vassilev const CompilerInstance *Interpreter::getCompilerInstance() const {
500a72d7eeaSVassil Vassilev   return CI.get();
50192f9852fSVassil Vassilev }
50292f9852fSVassil Vassilev 
503a72d7eeaSVassil Vassilev CompilerInstance *Interpreter::getCompilerInstance() { return CI.get(); }
50435b366acSFred Fu 
505d978730dSAnubhab Ghosh llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
506d978730dSAnubhab Ghosh   if (!IncrExecutor) {
507d978730dSAnubhab Ghosh     if (auto Err = CreateExecutor())
508766d048dSAnubhab Ghosh       return std::move(Err);
509d978730dSAnubhab Ghosh   }
510d978730dSAnubhab Ghosh 
511d978730dSAnubhab Ghosh   return IncrExecutor->GetExecutionEngine();
512788e0f7fSVassil Vassilev }
513788e0f7fSVassil Vassilev 
5145111286fSJun Zhang ASTContext &Interpreter::getASTContext() {
5155111286fSJun Zhang   return getCompilerInstance()->getASTContext();
5165111286fSJun Zhang }
5175111286fSJun Zhang 
5185111286fSJun Zhang const ASTContext &Interpreter::getASTContext() const {
5195111286fSJun Zhang   return getCompilerInstance()->getASTContext();
5205111286fSJun Zhang }
5215111286fSJun Zhang 
522aec92830SStefan Gränitz void Interpreter::markUserCodeStart() {
523aec92830SStefan Gränitz   assert(!InitPTUSize && "We only do this once");
524a72d7eeaSVassil Vassilev   InitPTUSize = PTUs.size();
525aec92830SStefan Gränitz }
526aec92830SStefan Gränitz 
5275111286fSJun Zhang size_t Interpreter::getEffectivePTUSize() const {
5285111286fSJun Zhang   assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
5295111286fSJun Zhang   return PTUs.size() - InitPTUSize;
5305111286fSJun Zhang }
5315111286fSJun Zhang 
532a8744066SVassil Vassilev PartialTranslationUnit &
533a8744066SVassil Vassilev Interpreter::RegisterPTU(TranslationUnitDecl *TU,
534a8744066SVassil Vassilev                          std::unique_ptr<llvm::Module> M /*={}*/) {
535a72d7eeaSVassil Vassilev   PTUs.emplace_back(PartialTranslationUnit());
536a72d7eeaSVassil Vassilev   PartialTranslationUnit &LastPTU = PTUs.back();
537a72d7eeaSVassil Vassilev   LastPTU.TUPart = TU;
538a72d7eeaSVassil Vassilev 
539a8744066SVassil Vassilev   if (!M)
540a8744066SVassil Vassilev     M = GenModule();
541a72d7eeaSVassil Vassilev 
542a8744066SVassil Vassilev   assert((!getCodeGen() || M) && "Must have a llvm::Module at this point");
543a8744066SVassil Vassilev 
544a8744066SVassil Vassilev   LastPTU.TheModule = std::move(M);
545a8744066SVassil Vassilev   LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1
546a8744066SVassil Vassilev                           << ": [TU=" << LastPTU.TUPart);
547a8744066SVassil Vassilev   if (LastPTU.TheModule)
548a8744066SVassil Vassilev     LLVM_DEBUG(llvm::dbgs() << ", M=" << LastPTU.TheModule.get() << " ("
549a8744066SVassil Vassilev                             << LastPTU.TheModule->getName() << ")");
550a8744066SVassil Vassilev   LLVM_DEBUG(llvm::dbgs() << "]\n");
551a72d7eeaSVassil Vassilev   return LastPTU;
552a72d7eeaSVassil Vassilev }
553a72d7eeaSVassil Vassilev 
55411b47c10SVassil Vassilev llvm::Expected<PartialTranslationUnit &>
55511b47c10SVassil Vassilev Interpreter::Parse(llvm::StringRef Code) {
556a72d7eeaSVassil Vassilev   // If we have a device parser, parse it first. The generated code will be
557a72d7eeaSVassil Vassilev   // included in the host compilation
558ddeab07cSAnubhab Ghosh   if (DeviceParser) {
559a72d7eeaSVassil Vassilev     llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Code);
560a72d7eeaSVassil Vassilev     if (auto E = DeviceTU.takeError())
561ddeab07cSAnubhab Ghosh       return std::move(E);
562ddeab07cSAnubhab Ghosh   }
563ddeab07cSAnubhab Ghosh 
5645111286fSJun Zhang   // Tell the interpreter sliently ignore unused expressions since value
5655111286fSJun Zhang   // printing could cause it.
5665111286fSJun Zhang   getCompilerInstance()->getDiagnostics().setSeverity(
5675111286fSJun Zhang       clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation());
568a72d7eeaSVassil Vassilev 
569a72d7eeaSVassil Vassilev   llvm::Expected<TranslationUnitDecl *> TuOrErr = IncrParser->Parse(Code);
570a72d7eeaSVassil Vassilev   if (!TuOrErr)
571a72d7eeaSVassil Vassilev     return TuOrErr.takeError();
572a72d7eeaSVassil Vassilev 
573a72d7eeaSVassil Vassilev   return RegisterPTU(*TuOrErr);
57492f9852fSVassil Vassilev }
57592f9852fSVassil Vassilev 
5760cf4788dSStefan Gränitz static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
5770cf4788dSStefan Gränitz createJITTargetMachineBuilder(const std::string &TT) {
5780cf4788dSStefan Gränitz   if (TT == llvm::sys::getProcessTriple())
5790cf4788dSStefan Gränitz     // This fails immediately if the target backend is not registered
5800cf4788dSStefan Gränitz     return llvm::orc::JITTargetMachineBuilder::detectHost();
5810cf4788dSStefan Gränitz 
5820cf4788dSStefan Gränitz   // If the target backend is not registered, LLJITBuilder::create() will fail
5830cf4788dSStefan Gränitz   return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
5840cf4788dSStefan Gränitz }
5850cf4788dSStefan Gränitz 
586d978730dSAnubhab Ghosh llvm::Error Interpreter::CreateExecutor() {
587bde7a6b7SStefan Gränitz   if (IncrExecutor)
588bde7a6b7SStefan Gränitz     return llvm::make_error<llvm::StringError>("Operation failed. "
589bde7a6b7SStefan Gränitz                                                "Execution engine exists",
590bde7a6b7SStefan Gränitz                                                std::error_code());
591a72d7eeaSVassil Vassilev   if (!getCodeGen())
592cb7995a1SStefan Gränitz     return llvm::make_error<llvm::StringError>("Operation failed. "
593cb7995a1SStefan Gränitz                                                "No code generator available",
594cb7995a1SStefan Gränitz                                                std::error_code());
595cb7995a1SStefan Gränitz   if (!JITBuilder) {
596cb7995a1SStefan Gränitz     const std::string &TT = getCompilerInstance()->getTargetOpts().Triple;
597cb7995a1SStefan Gränitz     auto JTMB = createJITTargetMachineBuilder(TT);
598cb7995a1SStefan Gränitz     if (!JTMB)
599cb7995a1SStefan Gränitz       return JTMB.takeError();
600cb7995a1SStefan Gränitz     auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
6010cf4788dSStefan Gränitz     if (!JB)
6020cf4788dSStefan Gränitz       return JB.takeError();
603cb7995a1SStefan Gränitz     JITBuilder = std::move(*JB);
604cb7995a1SStefan Gränitz   }
605cb7995a1SStefan Gränitz 
60692f9852fSVassil Vassilev   llvm::Error Err = llvm::Error::success();
6079a9546e3SVassil Vassilev #ifdef __EMSCRIPTEN__
6089a9546e3SVassil Vassilev   auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx);
6099a9546e3SVassil Vassilev #else
610cb7995a1SStefan Gränitz   auto Executor =
611cb7995a1SStefan Gränitz       std::make_unique<IncrementalExecutor>(*TSCtx, *JITBuilder, Err);
6129a9546e3SVassil Vassilev #endif
613d978730dSAnubhab Ghosh   if (!Err)
614d978730dSAnubhab Ghosh     IncrExecutor = std::move(Executor);
61549f95321SVassil Vassilev 
616d978730dSAnubhab Ghosh   return Err;
617d978730dSAnubhab Ghosh }
618d978730dSAnubhab Ghosh 
619bde7a6b7SStefan Gränitz void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
620bde7a6b7SStefan Gränitz 
621d978730dSAnubhab Ghosh llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
622d978730dSAnubhab Ghosh   assert(T.TheModule);
623a8744066SVassil Vassilev   LLVM_DEBUG(llvm::dbgs()
624a8744066SVassil Vassilev              << "execute-ptu "
625a8744066SVassil Vassilev              << ((std::find(PTUs.begin(), PTUs.end(), T) != PTUs.end())
626a8744066SVassil Vassilev                      ? std::distance(PTUs.begin(),
627a8744066SVassil Vassilev                                      std::find(PTUs.begin(), PTUs.end(), T))
628a8744066SVassil Vassilev                      : -1)
629a8744066SVassil Vassilev              << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get() << " ("
630a8744066SVassil Vassilev              << T.TheModule->getName() << ")]\n");
631d978730dSAnubhab Ghosh   if (!IncrExecutor) {
632d978730dSAnubhab Ghosh     auto Err = CreateExecutor();
63392f9852fSVassil Vassilev     if (Err)
63492f9852fSVassil Vassilev       return Err;
63592f9852fSVassil Vassilev   }
63692f9852fSVassil Vassilev   // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
637dea5a9ccSJun Zhang   if (auto Err = IncrExecutor->addModule(T))
63892f9852fSVassil Vassilev     return Err;
63992f9852fSVassil Vassilev 
64092f9852fSVassil Vassilev   if (auto Err = IncrExecutor->runCtors())
64192f9852fSVassil Vassilev     return Err;
64292f9852fSVassil Vassilev 
64392f9852fSVassil Vassilev   return llvm::Error::success();
64492f9852fSVassil Vassilev }
645c24a5808SVassil Vassilev 
6465111286fSJun Zhang llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
6475111286fSJun Zhang 
6485111286fSJun Zhang   auto PTU = Parse(Code);
6495111286fSJun Zhang   if (!PTU)
6505111286fSJun Zhang     return PTU.takeError();
6515111286fSJun Zhang   if (PTU->TheModule)
6525111286fSJun Zhang     if (llvm::Error Err = Execute(*PTU))
6535111286fSJun Zhang       return Err;
6545111286fSJun Zhang 
6555111286fSJun Zhang   if (LastValue.isValid()) {
6565111286fSJun Zhang     if (!V) {
6575111286fSJun Zhang       LastValue.dump();
6585111286fSJun Zhang       LastValue.clear();
6595111286fSJun Zhang     } else
6605111286fSJun Zhang       *V = std::move(LastValue);
6615111286fSJun Zhang   }
6625111286fSJun Zhang   return llvm::Error::success();
6635111286fSJun Zhang }
6645111286fSJun Zhang 
665fe1f3445SJun Zhang llvm::Expected<llvm::orc::ExecutorAddr>
6664fb0805cSVassil Vassilev Interpreter::getSymbolAddress(GlobalDecl GD) const {
6674fb0805cSVassil Vassilev   if (!IncrExecutor)
6684fb0805cSVassil Vassilev     return llvm::make_error<llvm::StringError>("Operation failed. "
6694fb0805cSVassil Vassilev                                                "No execution engine",
6704fb0805cSVassil Vassilev                                                std::error_code());
671a72d7eeaSVassil Vassilev   llvm::StringRef MangledName = getCodeGen()->GetMangledName(GD);
6724fb0805cSVassil Vassilev   return getSymbolAddress(MangledName);
6734fb0805cSVassil Vassilev }
6744fb0805cSVassil Vassilev 
675fe1f3445SJun Zhang llvm::Expected<llvm::orc::ExecutorAddr>
6764fb0805cSVassil Vassilev Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
677c24a5808SVassil Vassilev   if (!IncrExecutor)
678c24a5808SVassil Vassilev     return llvm::make_error<llvm::StringError>("Operation failed. "
679c24a5808SVassil Vassilev                                                "No execution engine",
680c24a5808SVassil Vassilev                                                std::error_code());
681c24a5808SVassil Vassilev 
6824fb0805cSVassil Vassilev   return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName);
6834fb0805cSVassil Vassilev }
6844fb0805cSVassil Vassilev 
685fe1f3445SJun Zhang llvm::Expected<llvm::orc::ExecutorAddr>
6864fb0805cSVassil Vassilev Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
6874fb0805cSVassil Vassilev   if (!IncrExecutor)
6884fb0805cSVassil Vassilev     return llvm::make_error<llvm::StringError>("Operation failed. "
6894fb0805cSVassil Vassilev                                                "No execution engine",
6904fb0805cSVassil Vassilev                                                std::error_code());
6914fb0805cSVassil Vassilev 
6924fb0805cSVassil Vassilev   return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName);
693c24a5808SVassil Vassilev }
694dea5a9ccSJun Zhang 
695dea5a9ccSJun Zhang llvm::Error Interpreter::Undo(unsigned N) {
696dea5a9ccSJun Zhang 
6975111286fSJun Zhang   if (N > getEffectivePTUSize())
698dea5a9ccSJun Zhang     return llvm::make_error<llvm::StringError>("Operation failed. "
699dea5a9ccSJun Zhang                                                "Too many undos",
700dea5a9ccSJun Zhang                                                std::error_code());
701dea5a9ccSJun Zhang   for (unsigned I = 0; I < N; I++) {
702dea5a9ccSJun Zhang     if (IncrExecutor) {
703dea5a9ccSJun Zhang       if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back()))
704dea5a9ccSJun Zhang         return Err;
705dea5a9ccSJun Zhang     }
706dea5a9ccSJun Zhang 
707a72d7eeaSVassil Vassilev     IncrParser->CleanUpPTU(PTUs.back().TUPart);
708dea5a9ccSJun Zhang     PTUs.pop_back();
709dea5a9ccSJun Zhang   }
710dea5a9ccSJun Zhang   return llvm::Error::success();
711dea5a9ccSJun Zhang }
712d978730dSAnubhab Ghosh 
713d978730dSAnubhab Ghosh llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
714d978730dSAnubhab Ghosh   auto EE = getExecutionEngine();
715d978730dSAnubhab Ghosh   if (!EE)
716d978730dSAnubhab Ghosh     return EE.takeError();
717d978730dSAnubhab Ghosh 
718ebb35088SSahilPatidar   auto &DL = EE->getDataLayout();
719ebb35088SSahilPatidar 
720ebb35088SSahilPatidar   if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load(
721ebb35088SSahilPatidar           name, DL.getGlobalPrefix()))
722*61ab36a3SDavide Italiano     EE->getMainJITDylib().addGenerator(std::move(*DLSG));
723d978730dSAnubhab Ghosh   else
724d978730dSAnubhab Ghosh     return DLSG.takeError();
725d978730dSAnubhab Ghosh 
726d978730dSAnubhab Ghosh   return llvm::Error::success();
727d978730dSAnubhab Ghosh }
7285111286fSJun Zhang 
729a72d7eeaSVassil Vassilev std::unique_ptr<llvm::Module> Interpreter::GenModule() {
730a72d7eeaSVassil Vassilev   static unsigned ID = 0;
731a72d7eeaSVassil Vassilev   if (CodeGenerator *CG = getCodeGen()) {
732a72d7eeaSVassil Vassilev     // Clang's CodeGen is designed to work with a single llvm::Module. In many
733a72d7eeaSVassil Vassilev     // cases for convenience various CodeGen parts have a reference to the
734a72d7eeaSVassil Vassilev     // llvm::Module (TheModule or Module) which does not change when a new
735a72d7eeaSVassil Vassilev     // module is pushed. However, the execution engine wants to take ownership
736a72d7eeaSVassil Vassilev     // of the module which does not map well to CodeGen's design. To work this
737a72d7eeaSVassil Vassilev     // around we created an empty module to make CodeGen happy. We should make
738a72d7eeaSVassil Vassilev     // sure it always stays empty.
739a8744066SVassil Vassilev     assert(((!CachedInCodeGenModule ||
740a8744066SVassil Vassilev              !getCompilerInstance()->getPreprocessorOpts().Includes.empty()) ||
741a8744066SVassil Vassilev             (CachedInCodeGenModule->empty() &&
742a72d7eeaSVassil Vassilev              CachedInCodeGenModule->global_empty() &&
743a72d7eeaSVassil Vassilev              CachedInCodeGenModule->alias_empty() &&
744a72d7eeaSVassil Vassilev              CachedInCodeGenModule->ifunc_empty())) &&
745a72d7eeaSVassil Vassilev            "CodeGen wrote to a readonly module");
746a72d7eeaSVassil Vassilev     std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
747a72d7eeaSVassil Vassilev     CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
748a72d7eeaSVassil Vassilev     return M;
7495111286fSJun Zhang   }
750ec2875ceSStefan Gränitz   return nullptr;
7517091dfc0SVassil Vassilev }
752ec2875ceSStefan Gränitz 
753a72d7eeaSVassil Vassilev CodeGenerator *Interpreter::getCodeGen() const {
754a72d7eeaSVassil Vassilev   FrontendAction *WrappedAct = Act->getWrapped();
755a72d7eeaSVassil Vassilev   if (!WrappedAct->hasIRSupport())
756a72d7eeaSVassil Vassilev     return nullptr;
757a72d7eeaSVassil Vassilev   return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
7585111286fSJun Zhang }
759a72d7eeaSVassil Vassilev } // namespace clang
760