1//===------ Interpreter.cpp - Incremental Compilation and Execution -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the component which performs incremental code
10// compilation and execution.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DeviceOffload.h"
15#include "IncrementalExecutor.h"
16#include "IncrementalParser.h"
17#include "InterpreterUtils.h"
18#include "llvm/Support/VirtualFileSystem.h"
19#ifdef __EMSCRIPTEN__
20#include "Wasm.h"
21#include <dlfcn.h>
22#endif // __EMSCRIPTEN__
23
24#include "clang/AST/ASTConsumer.h"
25#include "clang/AST/ASTContext.h"
26#include "clang/AST/Mangle.h"
27#include "clang/AST/TypeVisitor.h"
28#include "clang/Basic/DiagnosticSema.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/CodeGen/CodeGenAction.h"
31#include "clang/CodeGen/ModuleBuilder.h"
32#include "clang/CodeGen/ObjectFilePCHContainerWriter.h"
33#include "clang/Driver/Compilation.h"
34#include "clang/Driver/Driver.h"
35#include "clang/Driver/Job.h"
36#include "clang/Driver/Options.h"
37#include "clang/Driver/Tool.h"
38#include "clang/Frontend/CompilerInstance.h"
39#include "clang/Frontend/FrontendAction.h"
40#include "clang/Frontend/MultiplexConsumer.h"
41#include "clang/Frontend/TextDiagnosticBuffer.h"
42#include "clang/FrontendTool/Utils.h"
43#include "clang/Interpreter/Interpreter.h"
44#include "clang/Interpreter/Value.h"
45#include "clang/Lex/PreprocessorOptions.h"
46#include "clang/Sema/Lookup.h"
47#include "clang/Serialization/ObjectFilePCHContainerReader.h"
48#include "llvm/ExecutionEngine/JITSymbol.h"
49#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
50#include "llvm/ExecutionEngine/Orc/LLJIT.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/Errc.h"
53#include "llvm/Support/ErrorHandling.h"
54#include "llvm/Support/raw_ostream.h"
55#include "llvm/TargetParser/Host.h"
56#include "llvm/Transforms/Utils/Cloning.h" // for CloneModule
57
58#define DEBUG_TYPE "clang-repl"
59
60using namespace clang;
61// FIXME: Figure out how to unify with namespace init_convenience from
62// tools/clang-import-test/clang-import-test.cpp
63namespace {
64/// Retrieves the clang CC1 specific flags out of the compilation's jobs.
65/// \returns NULL on error.
66static llvm::Expected<const llvm::opt::ArgStringList *>
67GetCC1Arguments(DiagnosticsEngine *Diagnostics,
68 driver::Compilation *Compilation) {
69 // We expect to get back exactly one Command job, if we didn't something
70 // failed. Extract that job from the Compilation.
71 const driver::JobList &Jobs = Compilation->getJobs();
72 if (!Jobs.size() || !isa<driver::Command>(Val: *Jobs.begin()))
73 return llvm::createStringError(EC: llvm::errc::not_supported,
74 S: "Driver initialization failed. "
75 "Unable to create a driver job");
76
77 // The one job we find should be to invoke clang again.
78 const driver::Command *Cmd = cast<driver::Command>(Val: &(*Jobs.begin()));
79 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
80 return llvm::createStringError(EC: llvm::errc::not_supported,
81 S: "Driver initialization failed");
82
83 return &Cmd->getArguments();
84}
85
86static llvm::Expected<std::unique_ptr<CompilerInstance>>
87CreateCI(const llvm::opt::ArgStringList &Argv) {
88 std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
89 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
90
91 // Register the support for object-file-wrapped Clang modules.
92 // FIXME: Clang should register these container operations automatically.
93 auto PCHOps = Clang->getPCHContainerOperations();
94 PCHOps->registerWriter(Writer: std::make_unique<ObjectFilePCHContainerWriter>());
95 PCHOps->registerReader(Reader: std::make_unique<ObjectFilePCHContainerReader>());
96
97 // Buffer diagnostics from argument parsing so that we can output them using
98 // a well formed diagnostic object.
99 DiagnosticOptions DiagOpts;
100 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
101 DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer);
102 bool Success = CompilerInvocation::CreateFromArgs(
103 Res&: Clang->getInvocation(), CommandLineArgs: llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
104
105 // Infer the builtin include path if unspecified.
106 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
107 Clang->getHeaderSearchOpts().ResourceDir.empty())
108 Clang->getHeaderSearchOpts().ResourceDir =
109 CompilerInvocation::GetResourcesPath(Argv0: Argv[0], MainAddr: nullptr);
110
111 // Create the actual diagnostics engine.
112 Clang->createDiagnostics(VFS&: *llvm::vfs::getRealFileSystem());
113 if (!Clang->hasDiagnostics())
114 return llvm::createStringError(EC: llvm::errc::not_supported,
115 S: "Initialization failed. "
116 "Unable to create diagnostics engine");
117
118 DiagsBuffer->FlushDiagnostics(Diags&: Clang->getDiagnostics());
119 if (!Success)
120 return llvm::createStringError(EC: llvm::errc::not_supported,
121 S: "Initialization failed. "
122 "Unable to flush diagnostics");
123
124 // FIXME: Merge with CompilerInstance::ExecuteAction.
125 llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer(InputData: "").release();
126 Clang->getPreprocessorOpts().addRemappedFile(From: "<<< inputs >>>", To: MB);
127
128 Clang->setTarget(TargetInfo::CreateTargetInfo(
129 Diags&: Clang->getDiagnostics(), Opts&: Clang->getInvocation().getTargetOpts()));
130 if (!Clang->hasTarget())
131 return llvm::createStringError(EC: llvm::errc::not_supported,
132 S: "Initialization failed. "
133 "Target is missing");
134
135 Clang->getTarget().adjust(Diags&: Clang->getDiagnostics(), Opts&: Clang->getLangOpts(),
136 Aux: Clang->getAuxTarget());
137
138 // Don't clear the AST before backend codegen since we do codegen multiple
139 // times, reusing the same AST.
140 Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
141
142 Clang->getFrontendOpts().DisableFree = false;
143 Clang->getCodeGenOpts().DisableFree = false;
144 return std::move(Clang);
145}
146
147} // anonymous namespace
148
149namespace clang {
150
151llvm::Expected<std::unique_ptr<CompilerInstance>>
152IncrementalCompilerBuilder::create(std::string TT,
153 std::vector<const char *> &ClangArgv) {
154
155 // If we don't know ClangArgv0 or the address of main() at this point, try
156 // to guess it anyway (it's possible on some platforms).
157 std::string MainExecutableName =
158 llvm::sys::fs::getMainExecutable(argv0: nullptr, MainExecAddr: nullptr);
159
160 ClangArgv.insert(position: ClangArgv.begin(), x: MainExecutableName.c_str());
161
162 // Prepending -c to force the driver to do something if no action was
163 // specified. By prepending we allow users to override the default
164 // action and use other actions in incremental mode.
165 // FIXME: Print proper driver diagnostics if the driver flags are wrong.
166 // We do C++ by default; append right after argv[0] if no "-x" given
167 ClangArgv.insert(position: ClangArgv.end(), x: "-Xclang");
168 ClangArgv.insert(position: ClangArgv.end(), x: "-fincremental-extensions");
169 ClangArgv.insert(position: ClangArgv.end(), x: "-c");
170
171 // Put a dummy C++ file on to ensure there's at least one compile job for the
172 // driver to construct.
173 ClangArgv.push_back(x: "<<< inputs >>>");
174
175 // Buffer diagnostics from argument parsing so that we can output them using a
176 // well formed diagnostic object.
177 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
178 std::unique_ptr<DiagnosticOptions> DiagOpts =
179 CreateAndPopulateDiagOpts(Argv: ClangArgv);
180 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
181 DiagnosticsEngine Diags(DiagID, *DiagOpts, DiagsBuffer);
182
183 driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
184 Driver.setCheckInputsExist(false); // the input comes from mem buffers
185 llvm::ArrayRef<const char *> RF = llvm::ArrayRef(ClangArgv);
186 std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(Args: RF));
187
188 if (Compilation->getArgs().hasArg(Ids: driver::options::OPT_v))
189 Compilation->getJobs().Print(OS&: llvm::errs(), Terminator: "\n", /*Quote=*/false);
190
191 auto ErrOrCC1Args = GetCC1Arguments(Diagnostics: &Diags, Compilation: Compilation.get());
192 if (auto Err = ErrOrCC1Args.takeError())
193 return std::move(Err);
194
195 return CreateCI(Argv: **ErrOrCC1Args);
196}
197
198llvm::Expected<std::unique_ptr<CompilerInstance>>
199IncrementalCompilerBuilder::CreateCpp() {
200 std::vector<const char *> Argv;
201 Argv.reserve(n: 5 + 1 + UserArgs.size());
202 Argv.push_back(x: "-xc++");
203#ifdef __EMSCRIPTEN__
204 Argv.push_back("-target");
205 Argv.push_back("wasm32-unknown-emscripten");
206 Argv.push_back("-fvisibility=default");
207#endif
208 llvm::append_range(C&: Argv, R&: UserArgs);
209
210 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
211 return IncrementalCompilerBuilder::create(TT, ClangArgv&: Argv);
212}
213
214llvm::Expected<std::unique_ptr<CompilerInstance>>
215IncrementalCompilerBuilder::createCuda(bool device) {
216 std::vector<const char *> Argv;
217 Argv.reserve(n: 5 + 4 + UserArgs.size());
218
219 Argv.push_back(x: "-xcuda");
220 if (device)
221 Argv.push_back(x: "--cuda-device-only");
222 else
223 Argv.push_back(x: "--cuda-host-only");
224
225 std::string SDKPathArg = "--cuda-path=";
226 if (!CudaSDKPath.empty()) {
227 SDKPathArg += CudaSDKPath;
228 Argv.push_back(x: SDKPathArg.c_str());
229 }
230
231 std::string ArchArg = "--offload-arch=";
232 if (!OffloadArch.empty()) {
233 ArchArg += OffloadArch;
234 Argv.push_back(x: ArchArg.c_str());
235 }
236
237 llvm::append_range(C&: Argv, R&: UserArgs);
238
239 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
240 return IncrementalCompilerBuilder::create(TT, ClangArgv&: Argv);
241}
242
243llvm::Expected<std::unique_ptr<CompilerInstance>>
244IncrementalCompilerBuilder::CreateCudaDevice() {
245 return IncrementalCompilerBuilder::createCuda(device: true);
246}
247
248llvm::Expected<std::unique_ptr<CompilerInstance>>
249IncrementalCompilerBuilder::CreateCudaHost() {
250 return IncrementalCompilerBuilder::createCuda(device: false);
251}
252
253class InProcessPrintingASTConsumer final : public MultiplexConsumer {
254 Interpreter &Interp;
255
256public:
257 InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I)
258 : MultiplexConsumer(std::move(C)), Interp(I) {}
259 bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
260 if (DGR.isNull())
261 return true;
262
263 for (Decl *D : DGR)
264 if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(Val: D))
265 if (TLSD && TLSD->isSemiMissing()) {
266 auto ExprOrErr =
267 Interp.ExtractValueFromExpr(E: cast<Expr>(Val: TLSD->getStmt()));
268 if (llvm::Error E = ExprOrErr.takeError()) {
269 llvm::logAllUnhandledErrors(E: std::move(E), OS&: llvm::errs(),
270 ErrorBanner: "Value printing failed: ");
271 return false; // abort parsing
272 }
273 TLSD->setStmt(*ExprOrErr);
274 }
275
276 return MultiplexConsumer::HandleTopLevelDecl(D: DGR);
277 }
278};
279
280/// A custom action enabling the incremental processing functionality.
281///
282/// The usual \p FrontendAction expects one call to ExecuteAction and once it
283/// sees a call to \p EndSourceFile it deletes some of the important objects
284/// such as \p Preprocessor and \p Sema assuming no further input will come.
285///
286/// \p IncrementalAction ensures it keep its underlying action's objects alive
287/// as long as the \p IncrementalParser needs them.
288///
289class IncrementalAction : public WrapperFrontendAction {
290private:
291 bool IsTerminating = false;
292 Interpreter &Interp;
293 std::unique_ptr<ASTConsumer> Consumer;
294
295public:
296 IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
297 llvm::Error &Err, Interpreter &I,
298 std::unique_ptr<ASTConsumer> Consumer = nullptr)
299 : WrapperFrontendAction([&]() {
300 llvm::ErrorAsOutParameter EAO(&Err);
301 std::unique_ptr<FrontendAction> Act;
302 switch (CI.getFrontendOpts().ProgramAction) {
303 default:
304 Err = llvm::createStringError(
305 EC: std::errc::state_not_recoverable,
306 Fmt: "Driver initialization failed. "
307 "Incremental mode for action %d is not supported",
308 Vals: CI.getFrontendOpts().ProgramAction);
309 return Act;
310 case frontend::ASTDump:
311 case frontend::ASTPrint:
312 case frontend::ParseSyntaxOnly:
313 Act = CreateFrontendAction(CI);
314 break;
315 case frontend::PluginAction:
316 case frontend::EmitAssembly:
317 case frontend::EmitBC:
318 case frontend::EmitObj:
319 case frontend::PrintPreprocessedInput:
320 case frontend::EmitLLVMOnly:
321 Act.reset(p: new EmitLLVMOnlyAction(&LLVMCtx));
322 break;
323 }
324 return Act;
325 }()),
326 Interp(I), Consumer(std::move(Consumer)) {}
327 FrontendAction *getWrapped() const { return WrappedAction.get(); }
328 TranslationUnitKind getTranslationUnitKind() override {
329 return TU_Incremental;
330 }
331
332 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
333 StringRef InFile) override {
334 std::unique_ptr<ASTConsumer> C =
335 WrapperFrontendAction::CreateASTConsumer(CI, InFile);
336
337 if (Consumer) {
338 std::vector<std::unique_ptr<ASTConsumer>> Cs;
339 Cs.push_back(x: std::move(Consumer));
340 Cs.push_back(x: std::move(C));
341 return std::make_unique<MultiplexConsumer>(args: std::move(Cs));
342 }
343
344 return std::make_unique<InProcessPrintingASTConsumer>(args: std::move(C), args&: Interp);
345 }
346
347 void ExecuteAction() override {
348 WrapperFrontendAction::ExecuteAction();
349 getCompilerInstance().getSema().CurContext = nullptr;
350 }
351
352 // Do not terminate after processing the input. This allows us to keep various
353 // clang objects alive and to incrementally grow the current TU.
354 void EndSourceFile() override {
355 // The WrappedAction can be nullptr if we issued an error in the ctor.
356 if (IsTerminating && getWrapped())
357 WrapperFrontendAction::EndSourceFile();
358 }
359
360 void FinalizeAction() {
361 assert(!IsTerminating && "Already finalized!");
362 IsTerminating = true;
363 EndSourceFile();
364 }
365};
366
367Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
368 llvm::Error &ErrOut,
369 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder,
370 std::unique_ptr<clang::ASTConsumer> Consumer)
371 : JITBuilder(std::move(JITBuilder)) {
372 CI = std::move(Instance);
373 llvm::ErrorAsOutParameter EAO(&ErrOut);
374 auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
375 TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(args: std::move(LLVMCtx));
376
377 Act = TSCtx->withContextDo(F: [&](llvm::LLVMContext *Ctx) {
378 return std::make_unique<IncrementalAction>(args&: *CI, args&: *Ctx, args&: ErrOut, args&: *this,
379 args: std::move(Consumer));
380 });
381
382 if (ErrOut)
383 return;
384 CI->ExecuteAction(Act&: *Act);
385
386 IncrParser = std::make_unique<IncrementalParser>(args&: *CI, args&: ErrOut);
387
388 if (ErrOut)
389 return;
390
391 if (getCodeGen()) {
392 CachedInCodeGenModule = GenModule();
393 // The initial PTU is filled by `-include` or by CUDA includes
394 // automatically.
395 if (!CI->getPreprocessorOpts().Includes.empty()) {
396 // We can't really directly pass the CachedInCodeGenModule to the Jit
397 // because it will steal it, causing dangling references as explained in
398 // Interpreter::Execute
399 auto M = llvm::CloneModule(M: *CachedInCodeGenModule);
400 ASTContext &C = CI->getASTContext();
401 RegisterPTU(TU: C.getTranslationUnitDecl(), M: std::move(M));
402 }
403 if (llvm::Error Err = CreateExecutor()) {
404 ErrOut = joinErrors(E1: std::move(ErrOut), E2: std::move(Err));
405 return;
406 }
407 }
408
409 // Not all frontends support code-generation, e.g. ast-dump actions don't
410 if (getCodeGen()) {
411 // Process the PTUs that came from initialization. For example -include will
412 // give us a header that's processed at initialization of the preprocessor.
413 for (PartialTranslationUnit &PTU : PTUs)
414 if (llvm::Error Err = Execute(T&: PTU)) {
415 ErrOut = joinErrors(E1: std::move(ErrOut), E2: std::move(Err));
416 return;
417 }
418 }
419}
420
421Interpreter::~Interpreter() {
422 IncrParser.reset();
423 Act->FinalizeAction();
424 if (DeviceParser)
425 DeviceParser.reset();
426 if (DeviceAct)
427 DeviceAct->FinalizeAction();
428 if (IncrExecutor) {
429 if (llvm::Error Err = IncrExecutor->cleanUp())
430 llvm::report_fatal_error(
431 reason: llvm::Twine("Failed to clean up IncrementalExecutor: ") +
432 toString(E: std::move(Err)));
433 }
434}
435
436// These better to put in a runtime header but we can't. This is because we
437// can't find the precise resource directory in unittests so we have to hard
438// code them.
439const char *const Runtimes = R"(
440 #define __CLANG_REPL__ 1
441#ifdef __cplusplus
442 #define EXTERN_C extern "C"
443 void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
444 struct __clang_Interpreter_NewTag{} __ci_newtag;
445 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
446 template <class T, class = T (*)() /*disable for arrays*/>
447 void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
448 for (auto Idx = 0; Idx < Size; ++Idx)
449 new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
450 }
451 template <class T, unsigned long N>
452 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
453 __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
454 }
455#else
456 #define EXTERN_C extern
457#endif // __cplusplus
458
459 EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
460)";
461
462llvm::Expected<std::unique_ptr<Interpreter>>
463Interpreter::create(std::unique_ptr<CompilerInstance> CI,
464 std::unique_ptr<llvm::orc::LLJITBuilder> JB) {
465 llvm::Error Err = llvm::Error::success();
466 auto Interp = std::unique_ptr<Interpreter>(
467 new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr));
468 if (Err)
469 return std::move(Err);
470
471 // Add runtime code and set a marker to hide it from user code. Undo will not
472 // go through that.
473 auto PTU = Interp->Parse(Code: Runtimes);
474 if (!PTU)
475 return PTU.takeError();
476 Interp->markUserCodeStart();
477
478 Interp->ValuePrintingInfo.resize(N: 4);
479 return std::move(Interp);
480}
481
482llvm::Expected<std::unique_ptr<Interpreter>>
483Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
484 std::unique_ptr<CompilerInstance> DCI) {
485 // avoid writing fat binary to disk using an in-memory virtual file system
486 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
487 std::make_unique<llvm::vfs::InMemoryFileSystem>();
488 llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
489 std::make_unique<llvm::vfs::OverlayFileSystem>(
490 args: llvm::vfs::getRealFileSystem());
491 OverlayVFS->pushOverlay(FS: IMVFS);
492 CI->createFileManager(VFS: OverlayVFS);
493
494 llvm::Expected<std::unique_ptr<Interpreter>> InterpOrErr =
495 Interpreter::create(CI: std::move(CI));
496 if (!InterpOrErr)
497 return InterpOrErr;
498
499 std::unique_ptr<Interpreter> Interp = std::move(*InterpOrErr);
500
501 llvm::Error Err = llvm::Error::success();
502
503 auto DeviceAct = Interp->TSCtx->withContextDo(F: [&](llvm::LLVMContext *Ctx) {
504 return std::make_unique<IncrementalAction>(args&: *DCI, args&: *Ctx, args&: Err, args&: *Interp);
505 });
506
507 if (Err)
508 return std::move(Err);
509
510 Interp->DeviceAct = std::move(DeviceAct);
511
512 DCI->ExecuteAction(Act&: *Interp->DeviceAct);
513
514 Interp->DeviceCI = std::move(DCI);
515
516 auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
517 args&: *Interp->DeviceCI, args&: *Interp->getCompilerInstance(), args&: IMVFS, args&: Err,
518 args&: Interp->PTUs);
519
520 if (Err)
521 return std::move(Err);
522
523 Interp->DeviceParser = std::move(DeviceParser);
524 return std::move(Interp);
525}
526
527const CompilerInstance *Interpreter::getCompilerInstance() const {
528 return CI.get();
529}
530
531CompilerInstance *Interpreter::getCompilerInstance() { return CI.get(); }
532
533llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
534 if (!IncrExecutor) {
535 if (auto Err = CreateExecutor())
536 return std::move(Err);
537 }
538
539 return IncrExecutor->GetExecutionEngine();
540}
541
542ASTContext &Interpreter::getASTContext() {
543 return getCompilerInstance()->getASTContext();
544}
545
546const ASTContext &Interpreter::getASTContext() const {
547 return getCompilerInstance()->getASTContext();
548}
549
550void Interpreter::markUserCodeStart() {
551 assert(!InitPTUSize && "We only do this once");
552 InitPTUSize = PTUs.size();
553}
554
555size_t Interpreter::getEffectivePTUSize() const {
556 assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
557 return PTUs.size() - InitPTUSize;
558}
559
560PartialTranslationUnit &
561Interpreter::RegisterPTU(TranslationUnitDecl *TU,
562 std::unique_ptr<llvm::Module> M /*={}*/,
563 IncrementalAction *Action) {
564 PTUs.emplace_back(args: PartialTranslationUnit());
565 PartialTranslationUnit &LastPTU = PTUs.back();
566 LastPTU.TUPart = TU;
567
568 if (!M)
569 M = GenModule(Action);
570
571 assert((!getCodeGen(Action) || M) &&
572 "Must have a llvm::Module at this point");
573
574 LastPTU.TheModule = std::move(M);
575 LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1
576 << ": [TU=" << LastPTU.TUPart);
577 if (LastPTU.TheModule)
578 LLVM_DEBUG(llvm::dbgs() << ", M=" << LastPTU.TheModule.get() << " ("
579 << LastPTU.TheModule->getName() << ")");
580 LLVM_DEBUG(llvm::dbgs() << "]\n");
581 return LastPTU;
582}
583
584llvm::Expected<PartialTranslationUnit &>
585Interpreter::Parse(llvm::StringRef Code) {
586 // If we have a device parser, parse it first. The generated code will be
587 // included in the host compilation
588 if (DeviceParser) {
589 llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Input: Code);
590 if (auto E = DeviceTU.takeError())
591 return std::move(E);
592
593 RegisterPTU(TU: *DeviceTU, M: nullptr, Action: DeviceAct.get());
594
595 llvm::Expected<llvm::StringRef> PTX = DeviceParser->GeneratePTX();
596 if (!PTX)
597 return PTX.takeError();
598
599 llvm::Error Err = DeviceParser->GenerateFatbinary();
600 if (Err)
601 return std::move(Err);
602 }
603
604 // Tell the interpreter sliently ignore unused expressions since value
605 // printing could cause it.
606 getCompilerInstance()->getDiagnostics().setSeverity(
607 Diag: clang::diag::warn_unused_expr, Map: diag::Severity::Ignored, Loc: SourceLocation());
608
609 llvm::Expected<TranslationUnitDecl *> TuOrErr = IncrParser->Parse(Input: Code);
610 if (!TuOrErr)
611 return TuOrErr.takeError();
612
613 return RegisterPTU(TU: *TuOrErr);
614}
615
616static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
617createJITTargetMachineBuilder(const std::string &TT) {
618 if (TT == llvm::sys::getProcessTriple())
619 // This fails immediately if the target backend is not registered
620 return llvm::orc::JITTargetMachineBuilder::detectHost();
621
622 // If the target backend is not registered, LLJITBuilder::create() will fail
623 return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
624}
625
626llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
627Interpreter::createLLJITBuilder(
628 std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
629 llvm::StringRef OrcRuntimePath) {
630 const std::string &TT = EPC->getTargetTriple().getTriple();
631 auto JTMB = createJITTargetMachineBuilder(TT);
632 if (!JTMB)
633 return JTMB.takeError();
634 auto JB = IncrementalExecutor::createDefaultJITBuilder(JTMB: std::move(*JTMB));
635 if (!JB)
636 return JB.takeError();
637
638 (*JB)->setExecutorProcessControl(std::move(EPC));
639 (*JB)->setPlatformSetUp(
640 llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
641
642 return std::move(*JB);
643}
644
645llvm::Error Interpreter::CreateExecutor() {
646 if (IncrExecutor)
647 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
648 "Execution engine exists",
649 Args: std::error_code());
650 if (!getCodeGen())
651 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
652 "No code generator available",
653 Args: std::error_code());
654 if (!JITBuilder) {
655 const std::string &TT = getCompilerInstance()->getTargetOpts().Triple;
656 auto JTMB = createJITTargetMachineBuilder(TT);
657 if (!JTMB)
658 return JTMB.takeError();
659 auto JB = IncrementalExecutor::createDefaultJITBuilder(JTMB: std::move(*JTMB));
660 if (!JB)
661 return JB.takeError();
662 JITBuilder = std::move(*JB);
663 }
664
665 llvm::Error Err = llvm::Error::success();
666#ifdef __EMSCRIPTEN__
667 auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx);
668#else
669 auto Executor =
670 std::make_unique<IncrementalExecutor>(args&: *TSCtx, args&: *JITBuilder, args&: Err);
671#endif
672 if (!Err)
673 IncrExecutor = std::move(Executor);
674
675 return Err;
676}
677
678void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
679
680llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
681 assert(T.TheModule);
682 LLVM_DEBUG(
683 llvm::dbgs() << "execute-ptu "
684 << (llvm::is_contained(PTUs, T)
685 ? std::distance(PTUs.begin(), llvm::find(PTUs, T))
686 : -1)
687 << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get()
688 << " (" << T.TheModule->getName() << ")]\n");
689 if (!IncrExecutor) {
690 auto Err = CreateExecutor();
691 if (Err)
692 return Err;
693 }
694 // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
695 if (auto Err = IncrExecutor->addModule(PTU&: T))
696 return Err;
697
698 if (auto Err = IncrExecutor->runCtors())
699 return Err;
700
701 return llvm::Error::success();
702}
703
704llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
705
706 auto PTU = Parse(Code);
707 if (!PTU)
708 return PTU.takeError();
709 if (PTU->TheModule)
710 if (llvm::Error Err = Execute(T&: *PTU))
711 return Err;
712
713 if (LastValue.isValid()) {
714 if (!V) {
715 LastValue.dump();
716 LastValue.clear();
717 } else
718 *V = std::move(LastValue);
719 }
720 return llvm::Error::success();
721}
722
723llvm::Expected<llvm::orc::ExecutorAddr>
724Interpreter::getSymbolAddress(GlobalDecl GD) const {
725 if (!IncrExecutor)
726 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
727 "No execution engine",
728 Args: std::error_code());
729 llvm::StringRef MangledName = getCodeGen()->GetMangledName(GD);
730 return getSymbolAddress(IRName: MangledName);
731}
732
733llvm::Expected<llvm::orc::ExecutorAddr>
734Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
735 if (!IncrExecutor)
736 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
737 "No execution engine",
738 Args: std::error_code());
739
740 return IncrExecutor->getSymbolAddress(Name: IRName, NameKind: IncrementalExecutor::IRName);
741}
742
743llvm::Expected<llvm::orc::ExecutorAddr>
744Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
745 if (!IncrExecutor)
746 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
747 "No execution engine",
748 Args: std::error_code());
749
750 return IncrExecutor->getSymbolAddress(Name, NameKind: IncrementalExecutor::LinkerName);
751}
752
753llvm::Error Interpreter::Undo(unsigned N) {
754
755 if (N > getEffectivePTUSize())
756 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
757 "Too many undos",
758 Args: std::error_code());
759 for (unsigned I = 0; I < N; I++) {
760 if (IncrExecutor) {
761 if (llvm::Error Err = IncrExecutor->removeModule(PTU&: PTUs.back()))
762 return Err;
763 }
764
765 IncrParser->CleanUpPTU(MostRecentTU: PTUs.back().TUPart);
766 PTUs.pop_back();
767 }
768 return llvm::Error::success();
769}
770
771llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
772#ifdef __EMSCRIPTEN__
773 void *handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
774 if (!handle) {
775 llvm::errs() << dlerror() << '\n';
776 return llvm::make_error<llvm::StringError>("Failed to load dynamic library",
777 llvm::inconvertibleErrorCode());
778 }
779#else
780 auto EE = getExecutionEngine();
781 if (!EE)
782 return EE.takeError();
783
784 if (llvm::Expected<
785 std::unique_ptr<llvm::orc::EPCDynamicLibrarySearchGenerator>>
786 DLSG = llvm::orc::EPCDynamicLibrarySearchGenerator::Load(
787 ES&: EE->getExecutionSession(), LibraryPath: name))
788 // FIXME: Eventually we should put each library in its own JITDylib and
789 // turn off process symbols by default.
790 EE->getProcessSymbolsJITDylib()->addGenerator(DefGenerator: std::move(*DLSG));
791 else
792 return DLSG.takeError();
793#endif
794
795 return llvm::Error::success();
796}
797
798std::unique_ptr<llvm::Module>
799Interpreter::GenModule(IncrementalAction *Action) {
800 static unsigned ID = 0;
801 if (CodeGenerator *CG = getCodeGen(Action)) {
802 // Clang's CodeGen is designed to work with a single llvm::Module. In many
803 // cases for convenience various CodeGen parts have a reference to the
804 // llvm::Module (TheModule or Module) which does not change when a new
805 // module is pushed. However, the execution engine wants to take ownership
806 // of the module which does not map well to CodeGen's design. To work this
807 // around we created an empty module to make CodeGen happy. We should make
808 // sure it always stays empty.
809 assert(((!CachedInCodeGenModule ||
810 !getCompilerInstance()->getPreprocessorOpts().Includes.empty()) ||
811 (CachedInCodeGenModule->empty() &&
812 CachedInCodeGenModule->global_empty() &&
813 CachedInCodeGenModule->alias_empty() &&
814 CachedInCodeGenModule->ifunc_empty())) &&
815 "CodeGen wrote to a readonly module");
816 std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
817 CG->StartModule(ModuleName: "incr_module_" + std::to_string(val: ID++), C&: M->getContext());
818 return M;
819 }
820 return nullptr;
821}
822
823CodeGenerator *Interpreter::getCodeGen(IncrementalAction *Action) const {
824 if (!Action)
825 Action = Act.get();
826 FrontendAction *WrappedAct = Action->getWrapped();
827 if (!WrappedAct->hasIRSupport())
828 return nullptr;
829 return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
830}
831} // namespace clang
832

source code of clang/lib/Interpreter/Interpreter.cpp