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