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 #ifdef __EMSCRIPTEN__
19 #include "Wasm.h"
20 #endif // __EMSCRIPTEN__
21
22 #include "clang/AST/ASTContext.h"
23 #include "clang/AST/Mangle.h"
24 #include "clang/AST/TypeVisitor.h"
25 #include "clang/Basic/DiagnosticSema.h"
26 #include "clang/Basic/TargetInfo.h"
27 #include "clang/CodeGen/CodeGenAction.h"
28 #include "clang/CodeGen/ModuleBuilder.h"
29 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
30 #include "clang/Driver/Compilation.h"
31 #include "clang/Driver/Driver.h"
32 #include "clang/Driver/Job.h"
33 #include "clang/Driver/Options.h"
34 #include "clang/Driver/Tool.h"
35 #include "clang/Frontend/CompilerInstance.h"
36 #include "clang/Frontend/TextDiagnosticBuffer.h"
37 #include "clang/Interpreter/Interpreter.h"
38 #include "clang/Interpreter/Value.h"
39 #include "clang/Lex/PreprocessorOptions.h"
40 #include "clang/Sema/Lookup.h"
41 #include "llvm/ExecutionEngine/JITSymbol.h"
42 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
43 #include "llvm/IR/Module.h"
44 #include "llvm/Support/Errc.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/raw_ostream.h"
47 #include "llvm/TargetParser/Host.h"
48
49 #include <cstdarg>
50
51 using namespace clang;
52
53 // FIXME: Figure out how to unify with namespace init_convenience from
54 // tools/clang-import-test/clang-import-test.cpp
55 namespace {
56 /// Retrieves the clang CC1 specific flags out of the compilation's jobs.
57 /// \returns NULL on error.
58 static llvm::Expected<const llvm::opt::ArgStringList *>
GetCC1Arguments(DiagnosticsEngine * Diagnostics,driver::Compilation * Compilation)59 GetCC1Arguments(DiagnosticsEngine *Diagnostics,
60 driver::Compilation *Compilation) {
61 // We expect to get back exactly one Command job, if we didn't something
62 // failed. Extract that job from the Compilation.
63 const driver::JobList &Jobs = Compilation->getJobs();
64 if (!Jobs.size() || !isa<driver::Command>(*Jobs.begin()))
65 return llvm::createStringError(llvm::errc::not_supported,
66 "Driver initialization failed. "
67 "Unable to create a driver job");
68
69 // The one job we find should be to invoke clang again.
70 const driver::Command *Cmd = cast<driver::Command>(&(*Jobs.begin()));
71 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
72 return llvm::createStringError(llvm::errc::not_supported,
73 "Driver initialization failed");
74
75 return &Cmd->getArguments();
76 }
77
78 static llvm::Expected<std::unique_ptr<CompilerInstance>>
CreateCI(const llvm::opt::ArgStringList & Argv)79 CreateCI(const llvm::opt::ArgStringList &Argv) {
80 std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
81 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
82
83 // Register the support for object-file-wrapped Clang modules.
84 // FIXME: Clang should register these container operations automatically.
85 auto PCHOps = Clang->getPCHContainerOperations();
86 PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
87 PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
88
89 // Buffer diagnostics from argument parsing so that we can output them using
90 // a well formed diagnostic object.
91 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
92 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
93 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
94 bool Success = CompilerInvocation::CreateFromArgs(
95 Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
96
97 // Infer the builtin include path if unspecified.
98 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
99 Clang->getHeaderSearchOpts().ResourceDir.empty())
100 Clang->getHeaderSearchOpts().ResourceDir =
101 CompilerInvocation::GetResourcesPath(Argv[0], nullptr);
102
103 // Create the actual diagnostics engine.
104 Clang->createDiagnostics();
105 if (!Clang->hasDiagnostics())
106 return llvm::createStringError(llvm::errc::not_supported,
107 "Initialization failed. "
108 "Unable to create diagnostics engine");
109
110 DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
111 if (!Success)
112 return llvm::createStringError(llvm::errc::not_supported,
113 "Initialization failed. "
114 "Unable to flush diagnostics");
115
116 // FIXME: Merge with CompilerInstance::ExecuteAction.
117 llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release();
118 Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
119
120 Clang->setTarget(TargetInfo::CreateTargetInfo(
121 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
122 if (!Clang->hasTarget())
123 return llvm::createStringError(llvm::errc::not_supported,
124 "Initialization failed. "
125 "Target is missing");
126
127 Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts());
128
129 // Don't clear the AST before backend codegen since we do codegen multiple
130 // times, reusing the same AST.
131 Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
132
133 Clang->getFrontendOpts().DisableFree = false;
134 Clang->getCodeGenOpts().DisableFree = false;
135 return std::move(Clang);
136 }
137
138 } // anonymous namespace
139
140 llvm::Expected<std::unique_ptr<CompilerInstance>>
create(std::string TT,std::vector<const char * > & ClangArgv)141 IncrementalCompilerBuilder::create(std::string TT,
142 std::vector<const char *> &ClangArgv) {
143
144 // If we don't know ClangArgv0 or the address of main() at this point, try
145 // to guess it anyway (it's possible on some platforms).
146 std::string MainExecutableName =
147 llvm::sys::fs::getMainExecutable(nullptr, nullptr);
148
149 ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
150
151 // Prepending -c to force the driver to do something if no action was
152 // specified. By prepending we allow users to override the default
153 // action and use other actions in incremental mode.
154 // FIXME: Print proper driver diagnostics if the driver flags are wrong.
155 // We do C++ by default; append right after argv[0] if no "-x" given
156 ClangArgv.insert(ClangArgv.end(), "-Xclang");
157 ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions");
158 ClangArgv.insert(ClangArgv.end(), "-c");
159
160 // Put a dummy C++ file on to ensure there's at least one compile job for the
161 // driver to construct.
162 ClangArgv.push_back("<<< inputs >>>");
163
164 // Buffer diagnostics from argument parsing so that we can output them using a
165 // well formed diagnostic object.
166 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
167 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
168 CreateAndPopulateDiagOpts(ClangArgv);
169 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
170 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
171
172 driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
173 Driver.setCheckInputsExist(false); // the input comes from mem buffers
174 llvm::ArrayRef<const char *> RF = llvm::ArrayRef(ClangArgv);
175 std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(RF));
176
177 if (Compilation->getArgs().hasArg(driver::options::OPT_v))
178 Compilation->getJobs().Print(llvm::errs(), "\n", /*Quote=*/false);
179
180 auto ErrOrCC1Args = GetCC1Arguments(&Diags, Compilation.get());
181 if (auto Err = ErrOrCC1Args.takeError())
182 return std::move(Err);
183
184 return CreateCI(**ErrOrCC1Args);
185 }
186
187 llvm::Expected<std::unique_ptr<CompilerInstance>>
CreateCpp()188 IncrementalCompilerBuilder::CreateCpp() {
189 std::vector<const char *> Argv;
190 Argv.reserve(5 + 1 + UserArgs.size());
191 Argv.push_back("-xc++");
192 #ifdef __EMSCRIPTEN__
193 Argv.push_back("-target");
194 Argv.push_back("wasm32-unknown-emscripten");
195 Argv.push_back("-pie");
196 Argv.push_back("-shared");
197 #endif
198 Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
199
200 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
201 return IncrementalCompilerBuilder::create(TT, Argv);
202 }
203
204 llvm::Expected<std::unique_ptr<CompilerInstance>>
createCuda(bool device)205 IncrementalCompilerBuilder::createCuda(bool device) {
206 std::vector<const char *> Argv;
207 Argv.reserve(5 + 4 + UserArgs.size());
208
209 Argv.push_back("-xcuda");
210 if (device)
211 Argv.push_back("--cuda-device-only");
212 else
213 Argv.push_back("--cuda-host-only");
214
215 std::string SDKPathArg = "--cuda-path=";
216 if (!CudaSDKPath.empty()) {
217 SDKPathArg += CudaSDKPath;
218 Argv.push_back(SDKPathArg.c_str());
219 }
220
221 std::string ArchArg = "--offload-arch=";
222 if (!OffloadArch.empty()) {
223 ArchArg += OffloadArch;
224 Argv.push_back(ArchArg.c_str());
225 }
226
227 Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
228
229 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
230 return IncrementalCompilerBuilder::create(TT, Argv);
231 }
232
233 llvm::Expected<std::unique_ptr<CompilerInstance>>
CreateCudaDevice()234 IncrementalCompilerBuilder::CreateCudaDevice() {
235 return IncrementalCompilerBuilder::createCuda(true);
236 }
237
238 llvm::Expected<std::unique_ptr<CompilerInstance>>
CreateCudaHost()239 IncrementalCompilerBuilder::CreateCudaHost() {
240 return IncrementalCompilerBuilder::createCuda(false);
241 }
242
Interpreter(std::unique_ptr<CompilerInstance> CI,llvm::Error & ErrOut,std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder)243 Interpreter::Interpreter(std::unique_ptr<CompilerInstance> CI,
244 llvm::Error &ErrOut,
245 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder)
246 : JITBuilder(std::move(JITBuilder)) {
247 llvm::ErrorAsOutParameter EAO(&ErrOut);
248 auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
249 TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(std::move(LLVMCtx));
250 IncrParser = std::make_unique<IncrementalParser>(
251 *this, std::move(CI), *TSCtx->getContext(), ErrOut);
252 if (ErrOut)
253 return;
254
255 // Not all frontends support code-generation, e.g. ast-dump actions don't
256 if (IncrParser->getCodeGen()) {
257 if (llvm::Error Err = CreateExecutor()) {
258 ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
259 return;
260 }
261
262 // Process the PTUs that came from initialization. For example -include will
263 // give us a header that's processed at initialization of the preprocessor.
264 for (PartialTranslationUnit &PTU : IncrParser->getPTUs())
265 if (llvm::Error Err = Execute(PTU)) {
266 ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
267 return;
268 }
269 }
270 }
271
~Interpreter()272 Interpreter::~Interpreter() {
273 if (IncrExecutor) {
274 if (llvm::Error Err = IncrExecutor->cleanUp())
275 llvm::report_fatal_error(
276 llvm::Twine("Failed to clean up IncrementalExecutor: ") +
277 toString(std::move(Err)));
278 }
279 }
280
281 // These better to put in a runtime header but we can't. This is because we
282 // can't find the precise resource directory in unittests so we have to hard
283 // code them.
284 const char *const Runtimes = R"(
285 #define __CLANG_REPL__ 1
286 #ifdef __cplusplus
287 #define EXTERN_C extern "C"
288 void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
289 struct __clang_Interpreter_NewTag{} __ci_newtag;
290 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
291 template <class T, class = T (*)() /*disable for arrays*/>
292 void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
293 for (auto Idx = 0; Idx < Size; ++Idx)
294 new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
295 }
296 template <class T, unsigned long N>
297 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
298 __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
299 }
300 #else
301 #define EXTERN_C extern
302 #endif // __cplusplus
303
304 EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
305 )";
306
307 llvm::Expected<std::unique_ptr<Interpreter>>
create(std::unique_ptr<CompilerInstance> CI)308 Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
309 llvm::Error Err = llvm::Error::success();
310 auto Interp =
311 std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err));
312 if (Err)
313 return std::move(Err);
314
315 // Add runtime code and set a marker to hide it from user code. Undo will not
316 // go through that.
317 auto PTU = Interp->Parse(Runtimes);
318 if (!PTU)
319 return PTU.takeError();
320 Interp->markUserCodeStart();
321
322 Interp->ValuePrintingInfo.resize(4);
323 return std::move(Interp);
324 }
325
326 llvm::Expected<std::unique_ptr<Interpreter>>
createWithCUDA(std::unique_ptr<CompilerInstance> CI,std::unique_ptr<CompilerInstance> DCI)327 Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
328 std::unique_ptr<CompilerInstance> DCI) {
329 // avoid writing fat binary to disk using an in-memory virtual file system
330 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
331 std::make_unique<llvm::vfs::InMemoryFileSystem>();
332 llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
333 std::make_unique<llvm::vfs::OverlayFileSystem>(
334 llvm::vfs::getRealFileSystem());
335 OverlayVFS->pushOverlay(IMVFS);
336 CI->createFileManager(OverlayVFS);
337
338 auto Interp = Interpreter::create(std::move(CI));
339 if (auto E = Interp.takeError())
340 return std::move(E);
341
342 llvm::Error Err = llvm::Error::success();
343 auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
344 **Interp, std::move(DCI), *(*Interp)->IncrParser.get(),
345 *(*Interp)->TSCtx->getContext(), IMVFS, Err);
346 if (Err)
347 return std::move(Err);
348
349 (*Interp)->DeviceParser = std::move(DeviceParser);
350
351 return Interp;
352 }
353
getCompilerInstance() const354 const CompilerInstance *Interpreter::getCompilerInstance() const {
355 return IncrParser->getCI();
356 }
357
getCompilerInstance()358 CompilerInstance *Interpreter::getCompilerInstance() {
359 return IncrParser->getCI();
360 }
361
getExecutionEngine()362 llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
363 if (!IncrExecutor) {
364 if (auto Err = CreateExecutor())
365 return std::move(Err);
366 }
367
368 return IncrExecutor->GetExecutionEngine();
369 }
370
getASTContext()371 ASTContext &Interpreter::getASTContext() {
372 return getCompilerInstance()->getASTContext();
373 }
374
getASTContext() const375 const ASTContext &Interpreter::getASTContext() const {
376 return getCompilerInstance()->getASTContext();
377 }
378
markUserCodeStart()379 void Interpreter::markUserCodeStart() {
380 assert(!InitPTUSize && "We only do this once");
381 InitPTUSize = IncrParser->getPTUs().size();
382 }
383
getEffectivePTUSize() const384 size_t Interpreter::getEffectivePTUSize() const {
385 std::list<PartialTranslationUnit> &PTUs = IncrParser->getPTUs();
386 assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
387 return PTUs.size() - InitPTUSize;
388 }
389
390 llvm::Expected<PartialTranslationUnit &>
Parse(llvm::StringRef Code)391 Interpreter::Parse(llvm::StringRef Code) {
392 // If we have a device parser, parse it first.
393 // The generated code will be included in the host compilation
394 if (DeviceParser) {
395 auto DevicePTU = DeviceParser->Parse(Code);
396 if (auto E = DevicePTU.takeError())
397 return std::move(E);
398 }
399
400 // Tell the interpreter sliently ignore unused expressions since value
401 // printing could cause it.
402 getCompilerInstance()->getDiagnostics().setSeverity(
403 clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation());
404 return IncrParser->Parse(Code);
405 }
406
407 static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
createJITTargetMachineBuilder(const std::string & TT)408 createJITTargetMachineBuilder(const std::string &TT) {
409 if (TT == llvm::sys::getProcessTriple())
410 // This fails immediately if the target backend is not registered
411 return llvm::orc::JITTargetMachineBuilder::detectHost();
412
413 // If the target backend is not registered, LLJITBuilder::create() will fail
414 return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
415 }
416
CreateExecutor()417 llvm::Error Interpreter::CreateExecutor() {
418 if (IncrExecutor)
419 return llvm::make_error<llvm::StringError>("Operation failed. "
420 "Execution engine exists",
421 std::error_code());
422 if (!IncrParser->getCodeGen())
423 return llvm::make_error<llvm::StringError>("Operation failed. "
424 "No code generator available",
425 std::error_code());
426 if (!JITBuilder) {
427 const std::string &TT = getCompilerInstance()->getTargetOpts().Triple;
428 auto JTMB = createJITTargetMachineBuilder(TT);
429 if (!JTMB)
430 return JTMB.takeError();
431 auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
432 if (!JB)
433 return JB.takeError();
434 JITBuilder = std::move(*JB);
435 }
436
437 llvm::Error Err = llvm::Error::success();
438 #ifdef __EMSCRIPTEN__
439 auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx);
440 #else
441 auto Executor =
442 std::make_unique<IncrementalExecutor>(*TSCtx, *JITBuilder, Err);
443 #endif
444 if (!Err)
445 IncrExecutor = std::move(Executor);
446
447 return Err;
448 }
449
ResetExecutor()450 void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
451
Execute(PartialTranslationUnit & T)452 llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
453 assert(T.TheModule);
454 if (!IncrExecutor) {
455 auto Err = CreateExecutor();
456 if (Err)
457 return Err;
458 }
459 // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
460 if (auto Err = IncrExecutor->addModule(T))
461 return Err;
462
463 if (auto Err = IncrExecutor->runCtors())
464 return Err;
465
466 return llvm::Error::success();
467 }
468
ParseAndExecute(llvm::StringRef Code,Value * V)469 llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
470
471 auto PTU = Parse(Code);
472 if (!PTU)
473 return PTU.takeError();
474 if (PTU->TheModule)
475 if (llvm::Error Err = Execute(*PTU))
476 return Err;
477
478 if (LastValue.isValid()) {
479 if (!V) {
480 LastValue.dump();
481 LastValue.clear();
482 } else
483 *V = std::move(LastValue);
484 }
485 return llvm::Error::success();
486 }
487
488 llvm::Expected<llvm::orc::ExecutorAddr>
getSymbolAddress(GlobalDecl GD) const489 Interpreter::getSymbolAddress(GlobalDecl GD) const {
490 if (!IncrExecutor)
491 return llvm::make_error<llvm::StringError>("Operation failed. "
492 "No execution engine",
493 std::error_code());
494 llvm::StringRef MangledName = IncrParser->GetMangledName(GD);
495 return getSymbolAddress(MangledName);
496 }
497
498 llvm::Expected<llvm::orc::ExecutorAddr>
getSymbolAddress(llvm::StringRef IRName) const499 Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
500 if (!IncrExecutor)
501 return llvm::make_error<llvm::StringError>("Operation failed. "
502 "No execution engine",
503 std::error_code());
504
505 return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName);
506 }
507
508 llvm::Expected<llvm::orc::ExecutorAddr>
getSymbolAddressFromLinkerName(llvm::StringRef Name) const509 Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
510 if (!IncrExecutor)
511 return llvm::make_error<llvm::StringError>("Operation failed. "
512 "No execution engine",
513 std::error_code());
514
515 return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName);
516 }
517
Undo(unsigned N)518 llvm::Error Interpreter::Undo(unsigned N) {
519
520 std::list<PartialTranslationUnit> &PTUs = IncrParser->getPTUs();
521 if (N > getEffectivePTUSize())
522 return llvm::make_error<llvm::StringError>("Operation failed. "
523 "Too many undos",
524 std::error_code());
525 for (unsigned I = 0; I < N; I++) {
526 if (IncrExecutor) {
527 if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back()))
528 return Err;
529 }
530
531 IncrParser->CleanUpPTU(PTUs.back());
532 PTUs.pop_back();
533 }
534 return llvm::Error::success();
535 }
536
LoadDynamicLibrary(const char * name)537 llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
538 auto EE = getExecutionEngine();
539 if (!EE)
540 return EE.takeError();
541
542 auto &DL = EE->getDataLayout();
543
544 if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load(
545 name, DL.getGlobalPrefix()))
546 EE->getMainJITDylib().addGenerator(std::move(*DLSG));
547 else
548 return DLSG.takeError();
549
550 return llvm::Error::success();
551 }
552
553 llvm::Expected<llvm::orc::ExecutorAddr>
CompileDtorCall(CXXRecordDecl * CXXRD)554 Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
555 assert(CXXRD && "Cannot compile a destructor for a nullptr");
556 if (auto Dtor = Dtors.find(CXXRD); Dtor != Dtors.end())
557 return Dtor->getSecond();
558
559 if (CXXRD->hasIrrelevantDestructor())
560 return llvm::orc::ExecutorAddr{};
561
562 CXXDestructorDecl *DtorRD =
563 getCompilerInstance()->getSema().LookupDestructor(CXXRD);
564
565 llvm::StringRef Name =
566 IncrParser->GetMangledName(GlobalDecl(DtorRD, Dtor_Base));
567 auto AddrOrErr = getSymbolAddress(Name);
568 if (!AddrOrErr)
569 return AddrOrErr.takeError();
570
571 Dtors[CXXRD] = *AddrOrErr;
572 return AddrOrErr;
573 }
574
575 static constexpr llvm::StringRef MagicRuntimeInterface[] = {
576 "__clang_Interpreter_SetValueNoAlloc",
577 "__clang_Interpreter_SetValueWithAlloc",
578 "__clang_Interpreter_SetValueCopyArr", "__ci_newtag"};
579
580 static std::unique_ptr<RuntimeInterfaceBuilder>
581 createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx,
582 Sema &S);
583
FindRuntimeInterface()584 std::unique_ptr<RuntimeInterfaceBuilder> Interpreter::FindRuntimeInterface() {
585 if (llvm::all_of(ValuePrintingInfo, [](Expr *E) { return E != nullptr; }))
586 return nullptr;
587
588 Sema &S = getCompilerInstance()->getSema();
589 ASTContext &Ctx = S.getASTContext();
590
591 auto LookupInterface = [&](Expr *&Interface, llvm::StringRef Name) {
592 LookupResult R(S, &Ctx.Idents.get(Name), SourceLocation(),
593 Sema::LookupOrdinaryName,
594 RedeclarationKind::ForVisibleRedeclaration);
595 S.LookupQualifiedName(R, Ctx.getTranslationUnitDecl());
596 if (R.empty())
597 return false;
598
599 CXXScopeSpec CSS;
600 Interface = S.BuildDeclarationNameExpr(CSS, R, /*ADL=*/false).get();
601 return true;
602 };
603
604 if (!LookupInterface(ValuePrintingInfo[NoAlloc],
605 MagicRuntimeInterface[NoAlloc]))
606 return nullptr;
607 if (Ctx.getLangOpts().CPlusPlus) {
608 if (!LookupInterface(ValuePrintingInfo[WithAlloc],
609 MagicRuntimeInterface[WithAlloc]))
610 return nullptr;
611 if (!LookupInterface(ValuePrintingInfo[CopyArray],
612 MagicRuntimeInterface[CopyArray]))
613 return nullptr;
614 if (!LookupInterface(ValuePrintingInfo[NewTag],
615 MagicRuntimeInterface[NewTag]))
616 return nullptr;
617 }
618
619 return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S);
620 }
621
622 namespace {
623
624 class InterfaceKindVisitor
625 : public TypeVisitor<InterfaceKindVisitor, Interpreter::InterfaceKind> {
626 friend class InProcessRuntimeInterfaceBuilder;
627
628 ASTContext &Ctx;
629 Sema &S;
630 Expr *E;
631 llvm::SmallVector<Expr *, 3> Args;
632
633 public:
InterfaceKindVisitor(ASTContext & Ctx,Sema & S,Expr * E)634 InterfaceKindVisitor(ASTContext &Ctx, Sema &S, Expr *E)
635 : Ctx(Ctx), S(S), E(E) {}
636
VisitRecordType(const RecordType * Ty)637 Interpreter::InterfaceKind VisitRecordType(const RecordType *Ty) {
638 return Interpreter::InterfaceKind::WithAlloc;
639 }
640
641 Interpreter::InterfaceKind
VisitMemberPointerType(const MemberPointerType * Ty)642 VisitMemberPointerType(const MemberPointerType *Ty) {
643 return Interpreter::InterfaceKind::WithAlloc;
644 }
645
646 Interpreter::InterfaceKind
VisitConstantArrayType(const ConstantArrayType * Ty)647 VisitConstantArrayType(const ConstantArrayType *Ty) {
648 return Interpreter::InterfaceKind::CopyArray;
649 }
650
651 Interpreter::InterfaceKind
VisitFunctionProtoType(const FunctionProtoType * Ty)652 VisitFunctionProtoType(const FunctionProtoType *Ty) {
653 HandlePtrType(Ty);
654 return Interpreter::InterfaceKind::NoAlloc;
655 }
656
VisitPointerType(const PointerType * Ty)657 Interpreter::InterfaceKind VisitPointerType(const PointerType *Ty) {
658 HandlePtrType(Ty);
659 return Interpreter::InterfaceKind::NoAlloc;
660 }
661
VisitReferenceType(const ReferenceType * Ty)662 Interpreter::InterfaceKind VisitReferenceType(const ReferenceType *Ty) {
663 ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, E);
664 assert(!AddrOfE.isInvalid() && "Can not create unary expression");
665 Args.push_back(AddrOfE.get());
666 return Interpreter::InterfaceKind::NoAlloc;
667 }
668
VisitBuiltinType(const BuiltinType * Ty)669 Interpreter::InterfaceKind VisitBuiltinType(const BuiltinType *Ty) {
670 if (Ty->isNullPtrType())
671 Args.push_back(E);
672 else if (Ty->isFloatingType())
673 Args.push_back(E);
674 else if (Ty->isIntegralOrEnumerationType())
675 HandleIntegralOrEnumType(Ty);
676 else if (Ty->isVoidType()) {
677 // Do we need to still run `E`?
678 }
679
680 return Interpreter::InterfaceKind::NoAlloc;
681 }
682
VisitEnumType(const EnumType * Ty)683 Interpreter::InterfaceKind VisitEnumType(const EnumType *Ty) {
684 HandleIntegralOrEnumType(Ty);
685 return Interpreter::InterfaceKind::NoAlloc;
686 }
687
688 private:
689 // Force cast these types to the uint that fits the register size. That way we
690 // reduce the number of overloads of `__clang_Interpreter_SetValueNoAlloc`.
HandleIntegralOrEnumType(const Type * Ty)691 void HandleIntegralOrEnumType(const Type *Ty) {
692 uint64_t PtrBits = Ctx.getTypeSize(Ctx.VoidPtrTy);
693 QualType UIntTy = Ctx.getBitIntType(/*Unsigned=*/true, PtrBits);
694 TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(UIntTy);
695 ExprResult CastedExpr =
696 S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
697 assert(!CastedExpr.isInvalid() && "Cannot create cstyle cast expr");
698 Args.push_back(CastedExpr.get());
699 }
700
HandlePtrType(const Type * Ty)701 void HandlePtrType(const Type *Ty) {
702 TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.VoidPtrTy);
703 ExprResult CastedExpr =
704 S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
705 assert(!CastedExpr.isInvalid() && "Can not create cstyle cast expression");
706 Args.push_back(CastedExpr.get());
707 }
708 };
709
710 class InProcessRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
711 Interpreter &Interp;
712 ASTContext &Ctx;
713 Sema &S;
714
715 public:
InProcessRuntimeInterfaceBuilder(Interpreter & Interp,ASTContext & C,Sema & S)716 InProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &C, Sema &S)
717 : Interp(Interp), Ctx(C), S(S) {}
718
getPrintValueTransformer()719 TransformExprFunction *getPrintValueTransformer() override {
720 return &transformForValuePrinting;
721 }
722
723 private:
transformForValuePrinting(RuntimeInterfaceBuilder * Builder,Expr * E,ArrayRef<Expr * > FixedArgs)724 static ExprResult transformForValuePrinting(RuntimeInterfaceBuilder *Builder,
725 Expr *E,
726 ArrayRef<Expr *> FixedArgs) {
727 auto *B = static_cast<InProcessRuntimeInterfaceBuilder *>(Builder);
728
729 // Get rid of ExprWithCleanups.
730 if (auto *EWC = llvm::dyn_cast_if_present<ExprWithCleanups>(E))
731 E = EWC->getSubExpr();
732
733 InterfaceKindVisitor Visitor(B->Ctx, B->S, E);
734
735 // The Interpreter* parameter and the out parameter `OutVal`.
736 for (Expr *E : FixedArgs)
737 Visitor.Args.push_back(E);
738
739 QualType Ty = E->getType();
740 QualType DesugaredTy = Ty.getDesugaredType(B->Ctx);
741
742 // For lvalue struct, we treat it as a reference.
743 if (DesugaredTy->isRecordType() && E->isLValue()) {
744 DesugaredTy = B->Ctx.getLValueReferenceType(DesugaredTy);
745 Ty = B->Ctx.getLValueReferenceType(Ty);
746 }
747
748 Expr *TypeArg = CStyleCastPtrExpr(B->S, B->Ctx.VoidPtrTy,
749 (uintptr_t)Ty.getAsOpaquePtr());
750 // The QualType parameter `OpaqueType`, represented as `void*`.
751 Visitor.Args.push_back(TypeArg);
752
753 // We push the last parameter based on the type of the Expr. Note we need
754 // special care for rvalue struct.
755 Interpreter::InterfaceKind Kind = Visitor.Visit(&*DesugaredTy);
756 switch (Kind) {
757 case Interpreter::InterfaceKind::WithAlloc:
758 case Interpreter::InterfaceKind::CopyArray: {
759 // __clang_Interpreter_SetValueWithAlloc.
760 ExprResult AllocCall = B->S.ActOnCallExpr(
761 /*Scope=*/nullptr,
762 B->Interp
763 .getValuePrintingInfo()[Interpreter::InterfaceKind::WithAlloc],
764 E->getBeginLoc(), Visitor.Args, E->getEndLoc());
765 assert(!AllocCall.isInvalid() && "Can't create runtime interface call!");
766
767 TypeSourceInfo *TSI =
768 B->Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation());
769
770 // Force CodeGen to emit destructor.
771 if (auto *RD = Ty->getAsCXXRecordDecl()) {
772 auto *Dtor = B->S.LookupDestructor(RD);
773 Dtor->addAttr(UsedAttr::CreateImplicit(B->Ctx));
774 B->Interp.getCompilerInstance()->getASTConsumer().HandleTopLevelDecl(
775 DeclGroupRef(Dtor));
776 }
777
778 // __clang_Interpreter_SetValueCopyArr.
779 if (Kind == Interpreter::InterfaceKind::CopyArray) {
780 const auto *ConstantArrTy =
781 cast<ConstantArrayType>(DesugaredTy.getTypePtr());
782 size_t ArrSize = B->Ctx.getConstantArrayElementCount(ConstantArrTy);
783 Expr *ArrSizeExpr = IntegerLiteralExpr(B->Ctx, ArrSize);
784 Expr *Args[] = {E, AllocCall.get(), ArrSizeExpr};
785 return B->S.ActOnCallExpr(
786 /*Scope *=*/nullptr,
787 B->Interp
788 .getValuePrintingInfo()[Interpreter::InterfaceKind::CopyArray],
789 SourceLocation(), Args, SourceLocation());
790 }
791 Expr *Args[] = {
792 AllocCall.get(),
793 B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NewTag]};
794 ExprResult CXXNewCall = B->S.BuildCXXNew(
795 E->getSourceRange(),
796 /*UseGlobal=*/true, /*PlacementLParen=*/SourceLocation(), Args,
797 /*PlacementRParen=*/SourceLocation(),
798 /*TypeIdParens=*/SourceRange(), TSI->getType(), TSI, std::nullopt,
799 E->getSourceRange(), E);
800
801 assert(!CXXNewCall.isInvalid() &&
802 "Can't create runtime placement new call!");
803
804 return B->S.ActOnFinishFullExpr(CXXNewCall.get(),
805 /*DiscardedValue=*/false);
806 }
807 // __clang_Interpreter_SetValueNoAlloc.
808 case Interpreter::InterfaceKind::NoAlloc: {
809 return B->S.ActOnCallExpr(
810 /*Scope=*/nullptr,
811 B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NoAlloc],
812 E->getBeginLoc(), Visitor.Args, E->getEndLoc());
813 }
814 default:
815 llvm_unreachable("Unhandled Interpreter::InterfaceKind");
816 }
817 }
818 };
819 } // namespace
820
821 static std::unique_ptr<RuntimeInterfaceBuilder>
createInProcessRuntimeInterfaceBuilder(Interpreter & Interp,ASTContext & Ctx,Sema & S)822 createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx,
823 Sema &S) {
824 return std::make_unique<InProcessRuntimeInterfaceBuilder>(Interp, Ctx, S);
825 }
826
827 // This synthesizes a call expression to a speciall
828 // function that is responsible for generating the Value.
829 // In general, we transform:
830 // clang-repl> x
831 // To:
832 // // 1. If x is a built-in type like int, float.
833 // __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, x);
834 // // 2. If x is a struct, and a lvalue.
835 // __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType,
836 // &x);
837 // // 3. If x is a struct, but a rvalue.
838 // new (__clang_Interpreter_SetValueWithAlloc(ThisInterp, OpaqueValue,
839 // xQualType)) (x);
840
SynthesizeExpr(Expr * E)841 Expr *Interpreter::SynthesizeExpr(Expr *E) {
842 Sema &S = getCompilerInstance()->getSema();
843 ASTContext &Ctx = S.getASTContext();
844
845 if (!RuntimeIB) {
846 RuntimeIB = FindRuntimeInterface();
847 AddPrintValueCall = RuntimeIB->getPrintValueTransformer();
848 }
849
850 assert(AddPrintValueCall &&
851 "We don't have a runtime interface for pretty print!");
852
853 // Create parameter `ThisInterp`.
854 auto *ThisInterp = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)this);
855
856 // Create parameter `OutVal`.
857 auto *OutValue = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)&LastValue);
858
859 // Build `__clang_Interpreter_SetValue*` call.
860 ExprResult Result =
861 AddPrintValueCall(RuntimeIB.get(), E, {ThisInterp, OutValue});
862
863 // It could fail, like printing an array type in C. (not supported)
864 if (Result.isInvalid())
865 return E;
866 return Result.get();
867 }
868
869 // Temporary rvalue struct that need special care.
870 REPL_EXTERNAL_VISIBILITY void *
__clang_Interpreter_SetValueWithAlloc(void * This,void * OutVal,void * OpaqueType)871 __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal,
872 void *OpaqueType) {
873 Value &VRef = *(Value *)OutVal;
874 VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
875 return VRef.getPtr();
876 }
877
__clang_Interpreter_SetValueNoAlloc(void * This,void * OutVal,void * OpaqueType,...)878 extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc(
879 void *This, void *OutVal, void *OpaqueType, ...) {
880 Value &VRef = *(Value *)OutVal;
881 Interpreter *I = static_cast<Interpreter *>(This);
882 VRef = Value(I, OpaqueType);
883 if (VRef.isVoid())
884 return;
885
886 va_list args;
887 va_start(args, /*last named param*/ OpaqueType);
888
889 QualType QT = VRef.getType();
890 if (VRef.getKind() == Value::K_PtrOrObj) {
891 VRef.setPtr(va_arg(args, void *));
892 } else {
893 if (const auto *ET = QT->getAs<EnumType>())
894 QT = ET->getDecl()->getIntegerType();
895 switch (QT->castAs<BuiltinType>()->getKind()) {
896 default:
897 llvm_unreachable("unknown type kind!");
898 break;
899 // Types shorter than int are resolved as int, else va_arg has UB.
900 case BuiltinType::Bool:
901 VRef.setBool(va_arg(args, int));
902 break;
903 case BuiltinType::Char_S:
904 VRef.setChar_S(va_arg(args, int));
905 break;
906 case BuiltinType::SChar:
907 VRef.setSChar(va_arg(args, int));
908 break;
909 case BuiltinType::Char_U:
910 VRef.setChar_U(va_arg(args, unsigned));
911 break;
912 case BuiltinType::UChar:
913 VRef.setUChar(va_arg(args, unsigned));
914 break;
915 case BuiltinType::Short:
916 VRef.setShort(va_arg(args, int));
917 break;
918 case BuiltinType::UShort:
919 VRef.setUShort(va_arg(args, unsigned));
920 break;
921 case BuiltinType::Int:
922 VRef.setInt(va_arg(args, int));
923 break;
924 case BuiltinType::UInt:
925 VRef.setUInt(va_arg(args, unsigned));
926 break;
927 case BuiltinType::Long:
928 VRef.setLong(va_arg(args, long));
929 break;
930 case BuiltinType::ULong:
931 VRef.setULong(va_arg(args, unsigned long));
932 break;
933 case BuiltinType::LongLong:
934 VRef.setLongLong(va_arg(args, long long));
935 break;
936 case BuiltinType::ULongLong:
937 VRef.setULongLong(va_arg(args, unsigned long long));
938 break;
939 // Types shorter than double are resolved as double, else va_arg has UB.
940 case BuiltinType::Float:
941 VRef.setFloat(va_arg(args, double));
942 break;
943 case BuiltinType::Double:
944 VRef.setDouble(va_arg(args, double));
945 break;
946 case BuiltinType::LongDouble:
947 VRef.setLongDouble(va_arg(args, long double));
948 break;
949 // See REPL_BUILTIN_TYPES.
950 }
951 }
952 va_end(args);
953 }
954
955 // A trampoline to work around the fact that operator placement new cannot
956 // really be forward declared due to libc++ and libstdc++ declaration mismatch.
957 // FIXME: __clang_Interpreter_NewTag is ODR violation because we get the same
958 // definition in the interpreter runtime. We should move it in a runtime header
959 // which gets included by the interpreter and here.
960 struct __clang_Interpreter_NewTag {};
961 REPL_EXTERNAL_VISIBILITY void *
operator new(size_t __sz,void * __p,__clang_Interpreter_NewTag)962 operator new(size_t __sz, void *__p, __clang_Interpreter_NewTag) noexcept {
963 // Just forward to the standard operator placement new.
964 return operator new(__sz, __p);
965 }
966