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