1 //===------ Interpreter.cpp - Incremental Compilation and Execution -------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the component which performs incremental code
10 // compilation and execution.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Interpreter/Interpreter.h"
16 #include "DeviceOffload.h"
17 #include "IncrementalExecutor.h"
18 #include "IncrementalParser.h"
20 #include "InterpreterUtils.h"
21 #include "clang/AST/ASTContext.h"
22 #include "clang/AST/Mangle.h"
23 #include "clang/AST/TypeVisitor.h"
24 #include "clang/Basic/DiagnosticSema.h"
25 #include "clang/Basic/TargetInfo.h"
26 #include "clang/CodeGen/CodeGenAction.h"
27 #include "clang/CodeGen/ModuleBuilder.h"
28 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
29 #include "clang/Driver/Compilation.h"
30 #include "clang/Driver/Driver.h"
31 #include "clang/Driver/Job.h"
32 #include "clang/Driver/Options.h"
33 #include "clang/Driver/Tool.h"
34 #include "clang/Frontend/CompilerInstance.h"
35 #include "clang/Frontend/TextDiagnosticBuffer.h"
36 #include "clang/Interpreter/Value.h"
37 #include "clang/Lex/PreprocessorOptions.h"
38 #include "clang/Sema/Lookup.h"
39 #include "llvm/ExecutionEngine/JITSymbol.h"
40 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
41 #include "llvm/IR/Module.h"
42 #include "llvm/Support/Errc.h"
43 #include "llvm/Support/ErrorHandling.h"
44 #include "llvm/Support/raw_ostream.h"
45 #include "llvm/TargetParser/Host.h"
46 using namespace clang
;
48 // FIXME: Figure out how to unify with namespace init_convenience from
49 // tools/clang-import-test/clang-import-test.cpp
51 /// Retrieves the clang CC1 specific flags out of the compilation's jobs.
52 /// \returns NULL on error.
53 static llvm::Expected
<const llvm::opt::ArgStringList
*>
54 GetCC1Arguments(DiagnosticsEngine
*Diagnostics
,
55 driver::Compilation
*Compilation
) {
56 // We expect to get back exactly one Command job, if we didn't something
57 // failed. Extract that job from the Compilation.
58 const driver::JobList
&Jobs
= Compilation
->getJobs();
59 if (!Jobs
.size() || !isa
<driver::Command
>(*Jobs
.begin()))
60 return llvm::createStringError(llvm::errc::not_supported
,
61 "Driver initialization failed. "
62 "Unable to create a driver job");
64 // The one job we find should be to invoke clang again.
65 const driver::Command
*Cmd
= cast
<driver::Command
>(&(*Jobs
.begin()));
66 if (llvm::StringRef(Cmd
->getCreator().getName()) != "clang")
67 return llvm::createStringError(llvm::errc::not_supported
,
68 "Driver initialization failed");
70 return &Cmd
->getArguments();
73 static llvm::Expected
<std::unique_ptr
<CompilerInstance
>>
74 CreateCI(const llvm::opt::ArgStringList
&Argv
) {
75 std::unique_ptr
<CompilerInstance
> Clang(new CompilerInstance());
76 IntrusiveRefCntPtr
<DiagnosticIDs
> DiagID(new DiagnosticIDs());
78 // Register the support for object-file-wrapped Clang modules.
79 // FIXME: Clang should register these container operations automatically.
80 auto PCHOps
= Clang
->getPCHContainerOperations();
81 PCHOps
->registerWriter(std::make_unique
<ObjectFilePCHContainerWriter
>());
82 PCHOps
->registerReader(std::make_unique
<ObjectFilePCHContainerReader
>());
84 // Buffer diagnostics from argument parsing so that we can output them using
85 // a well formed diagnostic object.
86 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
= new DiagnosticOptions();
87 TextDiagnosticBuffer
*DiagsBuffer
= new TextDiagnosticBuffer
;
88 DiagnosticsEngine
Diags(DiagID
, &*DiagOpts
, DiagsBuffer
);
89 bool Success
= CompilerInvocation::CreateFromArgs(
90 Clang
->getInvocation(), llvm::ArrayRef(Argv
.begin(), Argv
.size()), Diags
);
92 // Infer the builtin include path if unspecified.
93 if (Clang
->getHeaderSearchOpts().UseBuiltinIncludes
&&
94 Clang
->getHeaderSearchOpts().ResourceDir
.empty())
95 Clang
->getHeaderSearchOpts().ResourceDir
=
96 CompilerInvocation::GetResourcesPath(Argv
[0], nullptr);
98 // Create the actual diagnostics engine.
99 Clang
->createDiagnostics();
100 if (!Clang
->hasDiagnostics())
101 return llvm::createStringError(llvm::errc::not_supported
,
102 "Initialization failed. "
103 "Unable to create diagnostics engine");
105 DiagsBuffer
->FlushDiagnostics(Clang
->getDiagnostics());
107 return llvm::createStringError(llvm::errc::not_supported
,
108 "Initialization failed. "
109 "Unable to flush diagnostics");
111 // FIXME: Merge with CompilerInstance::ExecuteAction.
112 llvm::MemoryBuffer
*MB
= llvm::MemoryBuffer::getMemBuffer("").release();
113 Clang
->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB
);
115 Clang
->setTarget(TargetInfo::CreateTargetInfo(
116 Clang
->getDiagnostics(), Clang
->getInvocation().TargetOpts
));
117 if (!Clang
->hasTarget())
118 return llvm::createStringError(llvm::errc::not_supported
,
119 "Initialization failed. "
120 "Target is missing");
122 Clang
->getTarget().adjust(Clang
->getDiagnostics(), Clang
->getLangOpts());
124 // Don't clear the AST before backend codegen since we do codegen multiple
125 // times, reusing the same AST.
126 Clang
->getCodeGenOpts().ClearASTBeforeBackend
= false;
128 Clang
->getFrontendOpts().DisableFree
= false;
129 Clang
->getCodeGenOpts().DisableFree
= false;
131 return std::move(Clang
);
134 } // anonymous namespace
136 llvm::Expected
<std::unique_ptr
<CompilerInstance
>>
137 IncrementalCompilerBuilder::create(std::vector
<const char *> &ClangArgv
) {
139 // If we don't know ClangArgv0 or the address of main() at this point, try
140 // to guess it anyway (it's possible on some platforms).
141 std::string MainExecutableName
=
142 llvm::sys::fs::getMainExecutable(nullptr, nullptr);
144 ClangArgv
.insert(ClangArgv
.begin(), MainExecutableName
.c_str());
146 // Prepending -c to force the driver to do something if no action was
147 // specified. By prepending we allow users to override the default
148 // action and use other actions in incremental mode.
149 // FIXME: Print proper driver diagnostics if the driver flags are wrong.
150 // We do C++ by default; append right after argv[0] if no "-x" given
151 ClangArgv
.insert(ClangArgv
.end(), "-Xclang");
152 ClangArgv
.insert(ClangArgv
.end(), "-fincremental-extensions");
153 ClangArgv
.insert(ClangArgv
.end(), "-c");
155 // Put a dummy C++ file on to ensure there's at least one compile job for the
156 // driver to construct.
157 ClangArgv
.push_back("<<< inputs >>>");
159 // Buffer diagnostics from argument parsing so that we can output them using a
160 // well formed diagnostic object.
161 IntrusiveRefCntPtr
<DiagnosticIDs
> DiagID(new DiagnosticIDs());
162 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
=
163 CreateAndPopulateDiagOpts(ClangArgv
);
164 TextDiagnosticBuffer
*DiagsBuffer
= new TextDiagnosticBuffer
;
165 DiagnosticsEngine
Diags(DiagID
, &*DiagOpts
, DiagsBuffer
);
167 driver::Driver
Driver(/*MainBinaryName=*/ClangArgv
[0],
168 llvm::sys::getProcessTriple(), Diags
);
169 Driver
.setCheckInputsExist(false); // the input comes from mem buffers
170 llvm::ArrayRef
<const char *> RF
= llvm::ArrayRef(ClangArgv
);
171 std::unique_ptr
<driver::Compilation
> Compilation(Driver
.BuildCompilation(RF
));
173 if (Compilation
->getArgs().hasArg(driver::options::OPT_v
))
174 Compilation
->getJobs().Print(llvm::errs(), "\n", /*Quote=*/false);
176 auto ErrOrCC1Args
= GetCC1Arguments(&Diags
, Compilation
.get());
177 if (auto Err
= ErrOrCC1Args
.takeError())
178 return std::move(Err
);
180 return CreateCI(**ErrOrCC1Args
);
183 llvm::Expected
<std::unique_ptr
<CompilerInstance
>>
184 IncrementalCompilerBuilder::CreateCpp() {
185 std::vector
<const char *> Argv
;
186 Argv
.reserve(5 + 1 + UserArgs
.size());
187 Argv
.push_back("-xc++");
188 Argv
.insert(Argv
.end(), UserArgs
.begin(), UserArgs
.end());
190 return IncrementalCompilerBuilder::create(Argv
);
193 llvm::Expected
<std::unique_ptr
<CompilerInstance
>>
194 IncrementalCompilerBuilder::createCuda(bool device
) {
195 std::vector
<const char *> Argv
;
196 Argv
.reserve(5 + 4 + UserArgs
.size());
198 Argv
.push_back("-xcuda");
200 Argv
.push_back("--cuda-device-only");
202 Argv
.push_back("--cuda-host-only");
204 std::string SDKPathArg
= "--cuda-path=";
205 if (!CudaSDKPath
.empty()) {
206 SDKPathArg
+= CudaSDKPath
;
207 Argv
.push_back(SDKPathArg
.c_str());
210 std::string ArchArg
= "--offload-arch=";
211 if (!OffloadArch
.empty()) {
212 ArchArg
+= OffloadArch
;
213 Argv
.push_back(ArchArg
.c_str());
216 Argv
.insert(Argv
.end(), UserArgs
.begin(), UserArgs
.end());
218 return IncrementalCompilerBuilder::create(Argv
);
221 llvm::Expected
<std::unique_ptr
<CompilerInstance
>>
222 IncrementalCompilerBuilder::CreateCudaDevice() {
223 return IncrementalCompilerBuilder::createCuda(true);
226 llvm::Expected
<std::unique_ptr
<CompilerInstance
>>
227 IncrementalCompilerBuilder::CreateCudaHost() {
228 return IncrementalCompilerBuilder::createCuda(false);
231 Interpreter::Interpreter(std::unique_ptr
<CompilerInstance
> CI
,
233 llvm::ErrorAsOutParameter
EAO(&Err
);
234 auto LLVMCtx
= std::make_unique
<llvm::LLVMContext
>();
235 TSCtx
= std::make_unique
<llvm::orc::ThreadSafeContext
>(std::move(LLVMCtx
));
236 IncrParser
= std::make_unique
<IncrementalParser
>(*this, std::move(CI
),
237 *TSCtx
->getContext(), Err
);
240 Interpreter::~Interpreter() {
242 if (llvm::Error Err
= IncrExecutor
->cleanUp())
243 llvm::report_fatal_error(
244 llvm::Twine("Failed to clean up IncrementalExecutor: ") +
245 toString(std::move(Err
)));
249 // These better to put in a runtime header but we can't. This is because we
250 // can't find the precise resource directory in unittests so we have to hard
252 const char *const Runtimes
= R
"(
253 void* operator new(__SIZE_TYPE__, void* __p) noexcept;
254 void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
255 void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
256 void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
257 void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
258 void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
259 void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
260 void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long);
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)) T(Src[Idx]);
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);
272 llvm::Expected
<std::unique_ptr
<Interpreter
>>
273 Interpreter::create(std::unique_ptr
<CompilerInstance
> CI
) {
274 llvm::Error Err
= llvm::Error::success();
276 std::unique_ptr
<Interpreter
>(new Interpreter(std::move(CI
), Err
));
278 return std::move(Err
);
279 auto PTU
= Interp
->Parse(Runtimes
);
281 return PTU
.takeError();
283 Interp
->ValuePrintingInfo
.resize(3);
284 // FIXME: This is a ugly hack. Undo command checks its availability by looking
285 // at the size of the PTU list. However we have parsed something in the
286 // beginning of the REPL so we have to mark them as 'Irrevocable'.
287 Interp
->InitPTUSize
= Interp
->IncrParser
->getPTUs().size();
288 return std::move(Interp
);
291 llvm::Expected
<std::unique_ptr
<Interpreter
>>
292 Interpreter::createWithCUDA(std::unique_ptr
<CompilerInstance
> CI
,
293 std::unique_ptr
<CompilerInstance
> DCI
) {
294 // avoid writing fat binary to disk using an in-memory virtual file system
295 llvm::IntrusiveRefCntPtr
<llvm::vfs::InMemoryFileSystem
> IMVFS
=
296 std::make_unique
<llvm::vfs::InMemoryFileSystem
>();
297 llvm::IntrusiveRefCntPtr
<llvm::vfs::OverlayFileSystem
> OverlayVFS
=
298 std::make_unique
<llvm::vfs::OverlayFileSystem
>(
299 llvm::vfs::getRealFileSystem());
300 OverlayVFS
->pushOverlay(IMVFS
);
301 CI
->createFileManager(OverlayVFS
);
303 auto Interp
= Interpreter::create(std::move(CI
));
304 if (auto E
= Interp
.takeError())
307 llvm::Error Err
= llvm::Error::success();
308 auto DeviceParser
= std::make_unique
<IncrementalCUDADeviceParser
>(
309 **Interp
, std::move(DCI
), *(*Interp
)->IncrParser
.get(),
310 *(*Interp
)->TSCtx
->getContext(), IMVFS
, Err
);
312 return std::move(Err
);
314 (*Interp
)->DeviceParser
= std::move(DeviceParser
);
319 const CompilerInstance
*Interpreter::getCompilerInstance() const {
320 return IncrParser
->getCI();
323 llvm::Expected
<llvm::orc::LLJIT
&> Interpreter::getExecutionEngine() {
325 if (auto Err
= CreateExecutor())
326 return std::move(Err
);
329 return IncrExecutor
->GetExecutionEngine();
332 ASTContext
&Interpreter::getASTContext() {
333 return getCompilerInstance()->getASTContext();
336 const ASTContext
&Interpreter::getASTContext() const {
337 return getCompilerInstance()->getASTContext();
340 size_t Interpreter::getEffectivePTUSize() const {
341 std::list
<PartialTranslationUnit
> &PTUs
= IncrParser
->getPTUs();
342 assert(PTUs
.size() >= InitPTUSize
&& "empty PTU list?");
343 return PTUs
.size() - InitPTUSize
;
346 llvm::Expected
<PartialTranslationUnit
&>
347 Interpreter::Parse(llvm::StringRef Code
) {
348 // If we have a device parser, parse it first.
349 // The generated code will be included in the host compilation
351 auto DevicePTU
= DeviceParser
->Parse(Code
);
352 if (auto E
= DevicePTU
.takeError())
356 // Tell the interpreter sliently ignore unused expressions since value
357 // printing could cause it.
358 getCompilerInstance()->getDiagnostics().setSeverity(
359 clang::diag::warn_unused_expr
, diag::Severity::Ignored
, SourceLocation());
360 return IncrParser
->Parse(Code
);
363 llvm::Error
Interpreter::CreateExecutor() {
364 const clang::TargetInfo
&TI
=
365 getCompilerInstance()->getASTContext().getTargetInfo();
366 llvm::Error Err
= llvm::Error::success();
367 auto Executor
= std::make_unique
<IncrementalExecutor
>(*TSCtx
, Err
, TI
);
369 IncrExecutor
= std::move(Executor
);
374 llvm::Error
Interpreter::Execute(PartialTranslationUnit
&T
) {
377 auto Err
= CreateExecutor();
381 // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
382 if (auto Err
= IncrExecutor
->addModule(T
))
385 if (auto Err
= IncrExecutor
->runCtors())
388 return llvm::Error::success();
391 llvm::Error
Interpreter::ParseAndExecute(llvm::StringRef Code
, Value
*V
) {
393 auto PTU
= Parse(Code
);
395 return PTU
.takeError();
397 if (llvm::Error Err
= Execute(*PTU
))
400 if (LastValue
.isValid()) {
405 *V
= std::move(LastValue
);
407 return llvm::Error::success();
410 llvm::Expected
<llvm::orc::ExecutorAddr
>
411 Interpreter::getSymbolAddress(GlobalDecl GD
) const {
413 return llvm::make_error
<llvm::StringError
>("Operation failed. "
414 "No execution engine",
416 llvm::StringRef MangledName
= IncrParser
->GetMangledName(GD
);
417 return getSymbolAddress(MangledName
);
420 llvm::Expected
<llvm::orc::ExecutorAddr
>
421 Interpreter::getSymbolAddress(llvm::StringRef IRName
) const {
423 return llvm::make_error
<llvm::StringError
>("Operation failed. "
424 "No execution engine",
427 return IncrExecutor
->getSymbolAddress(IRName
, IncrementalExecutor::IRName
);
430 llvm::Expected
<llvm::orc::ExecutorAddr
>
431 Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name
) const {
433 return llvm::make_error
<llvm::StringError
>("Operation failed. "
434 "No execution engine",
437 return IncrExecutor
->getSymbolAddress(Name
, IncrementalExecutor::LinkerName
);
440 llvm::Error
Interpreter::Undo(unsigned N
) {
442 std::list
<PartialTranslationUnit
> &PTUs
= IncrParser
->getPTUs();
443 if (N
> getEffectivePTUSize())
444 return llvm::make_error
<llvm::StringError
>("Operation failed. "
447 for (unsigned I
= 0; I
< N
; I
++) {
449 if (llvm::Error Err
= IncrExecutor
->removeModule(PTUs
.back()))
453 IncrParser
->CleanUpPTU(PTUs
.back());
456 return llvm::Error::success();
459 llvm::Error
Interpreter::LoadDynamicLibrary(const char *name
) {
460 auto EE
= getExecutionEngine();
462 return EE
.takeError();
464 auto &DL
= EE
->getDataLayout();
466 if (auto DLSG
= llvm::orc::DynamicLibrarySearchGenerator::Load(
467 name
, DL
.getGlobalPrefix()))
468 EE
->getMainJITDylib().addGenerator(std::move(*DLSG
));
470 return DLSG
.takeError();
472 return llvm::Error::success();
475 llvm::Expected
<llvm::orc::ExecutorAddr
>
476 Interpreter::CompileDtorCall(CXXRecordDecl
*CXXRD
) {
477 assert(CXXRD
&& "Cannot compile a destructor for a nullptr");
478 if (auto Dtor
= Dtors
.find(CXXRD
); Dtor
!= Dtors
.end())
479 return Dtor
->getSecond();
481 if (CXXRD
->hasIrrelevantDestructor())
482 return llvm::orc::ExecutorAddr
{};
484 CXXDestructorDecl
*DtorRD
=
485 getCompilerInstance()->getSema().LookupDestructor(CXXRD
);
487 llvm::StringRef Name
=
488 IncrParser
->GetMangledName(GlobalDecl(DtorRD
, Dtor_Base
));
489 auto AddrOrErr
= getSymbolAddress(Name
);
491 return AddrOrErr
.takeError();
493 Dtors
[CXXRD
] = *AddrOrErr
;
497 static constexpr llvm::StringRef MagicRuntimeInterface
[] = {
498 "__clang_Interpreter_SetValueNoAlloc",
499 "__clang_Interpreter_SetValueWithAlloc",
500 "__clang_Interpreter_SetValueCopyArr"};
502 bool Interpreter::FindRuntimeInterface() {
503 if (llvm::all_of(ValuePrintingInfo
, [](Expr
*E
) { return E
!= nullptr; }))
506 Sema
&S
= getCompilerInstance()->getSema();
507 ASTContext
&Ctx
= S
.getASTContext();
509 auto LookupInterface
= [&](Expr
*&Interface
, llvm::StringRef Name
) {
510 LookupResult
R(S
, &Ctx
.Idents
.get(Name
), SourceLocation(),
511 Sema::LookupOrdinaryName
, Sema::ForVisibleRedeclaration
);
512 S
.LookupQualifiedName(R
, Ctx
.getTranslationUnitDecl());
517 Interface
= S
.BuildDeclarationNameExpr(CSS
, R
, /*ADL=*/false).get();
521 if (!LookupInterface(ValuePrintingInfo
[NoAlloc
],
522 MagicRuntimeInterface
[NoAlloc
]))
524 if (!LookupInterface(ValuePrintingInfo
[WithAlloc
],
525 MagicRuntimeInterface
[WithAlloc
]))
527 if (!LookupInterface(ValuePrintingInfo
[CopyArray
],
528 MagicRuntimeInterface
[CopyArray
]))
535 class RuntimeInterfaceBuilder
536 : public TypeVisitor
<RuntimeInterfaceBuilder
, Interpreter::InterfaceKind
> {
537 clang::Interpreter
&Interp
;
541 llvm::SmallVector
<Expr
*, 3> Args
;
544 RuntimeInterfaceBuilder(clang::Interpreter
&In
, ASTContext
&C
, Sema
&SemaRef
,
545 Expr
*VE
, ArrayRef
<Expr
*> FixedArgs
)
546 : Interp(In
), Ctx(C
), S(SemaRef
), E(VE
) {
547 // The Interpreter* parameter and the out parameter `OutVal`.
548 for (Expr
*E
: FixedArgs
)
551 // Get rid of ExprWithCleanups.
552 if (auto *EWC
= llvm::dyn_cast_if_present
<ExprWithCleanups
>(E
))
553 E
= EWC
->getSubExpr();
556 ExprResult
getCall() {
557 QualType Ty
= E
->getType();
558 QualType DesugaredTy
= Ty
.getDesugaredType(Ctx
);
560 // For lvalue struct, we treat it as a reference.
561 if (DesugaredTy
->isRecordType() && E
->isLValue()) {
562 DesugaredTy
= Ctx
.getLValueReferenceType(DesugaredTy
);
563 Ty
= Ctx
.getLValueReferenceType(Ty
);
567 CStyleCastPtrExpr(S
, Ctx
.VoidPtrTy
, (uintptr_t)Ty
.getAsOpaquePtr());
568 // The QualType parameter `OpaqueType`, represented as `void*`.
569 Args
.push_back(TypeArg
);
571 // We push the last parameter based on the type of the Expr. Note we need
572 // special care for rvalue struct.
573 Interpreter::InterfaceKind Kind
= Visit(&*DesugaredTy
);
575 case Interpreter::InterfaceKind::WithAlloc
:
576 case Interpreter::InterfaceKind::CopyArray
: {
577 // __clang_Interpreter_SetValueWithAlloc.
578 ExprResult AllocCall
= S
.ActOnCallExpr(
580 Interp
.getValuePrintingInfo()[Interpreter::InterfaceKind::WithAlloc
],
581 E
->getBeginLoc(), Args
, E
->getEndLoc());
582 assert(!AllocCall
.isInvalid() && "Can't create runtime interface call!");
584 TypeSourceInfo
*TSI
= Ctx
.getTrivialTypeSourceInfo(Ty
, SourceLocation());
586 // Force CodeGen to emit destructor.
587 if (auto *RD
= Ty
->getAsCXXRecordDecl()) {
588 auto *Dtor
= S
.LookupDestructor(RD
);
589 Dtor
->addAttr(UsedAttr::CreateImplicit(Ctx
));
590 Interp
.getCompilerInstance()->getASTConsumer().HandleTopLevelDecl(
594 // __clang_Interpreter_SetValueCopyArr.
595 if (Kind
== Interpreter::InterfaceKind::CopyArray
) {
596 const auto *ConstantArrTy
=
597 cast
<ConstantArrayType
>(DesugaredTy
.getTypePtr());
598 size_t ArrSize
= Ctx
.getConstantArrayElementCount(ConstantArrTy
);
599 Expr
*ArrSizeExpr
= IntegerLiteralExpr(Ctx
, ArrSize
);
600 Expr
*Args
[] = {E
, AllocCall
.get(), ArrSizeExpr
};
601 return S
.ActOnCallExpr(
604 .getValuePrintingInfo()[Interpreter::InterfaceKind::CopyArray
],
605 SourceLocation(), Args
, SourceLocation());
607 Expr
*Args
[] = {AllocCall
.get()};
608 ExprResult CXXNewCall
= S
.BuildCXXNew(
610 /*UseGlobal=*/true, /*PlacementLParen=*/SourceLocation(), Args
,
611 /*PlacementRParen=*/SourceLocation(),
612 /*TypeIdParens=*/SourceRange(), TSI
->getType(), TSI
, std::nullopt
,
613 E
->getSourceRange(), E
);
615 assert(!CXXNewCall
.isInvalid() &&
616 "Can't create runtime placement new call!");
618 return S
.ActOnFinishFullExpr(CXXNewCall
.get(),
619 /*DiscardedValue=*/false);
621 // __clang_Interpreter_SetValueNoAlloc.
622 case Interpreter::InterfaceKind::NoAlloc
: {
623 return S
.ActOnCallExpr(
625 Interp
.getValuePrintingInfo()[Interpreter::InterfaceKind::NoAlloc
],
626 E
->getBeginLoc(), Args
, E
->getEndLoc());
629 llvm_unreachable("Unhandled Interpreter::InterfaceKind");
632 Interpreter::InterfaceKind
VisitRecordType(const RecordType
*Ty
) {
633 return Interpreter::InterfaceKind::WithAlloc
;
636 Interpreter::InterfaceKind
637 VisitMemberPointerType(const MemberPointerType
*Ty
) {
638 return Interpreter::InterfaceKind::WithAlloc
;
641 Interpreter::InterfaceKind
642 VisitConstantArrayType(const ConstantArrayType
*Ty
) {
643 return Interpreter::InterfaceKind::CopyArray
;
646 Interpreter::InterfaceKind
647 VisitFunctionProtoType(const FunctionProtoType
*Ty
) {
649 return Interpreter::InterfaceKind::NoAlloc
;
652 Interpreter::InterfaceKind
VisitPointerType(const PointerType
*Ty
) {
654 return Interpreter::InterfaceKind::NoAlloc
;
657 Interpreter::InterfaceKind
VisitReferenceType(const ReferenceType
*Ty
) {
658 ExprResult AddrOfE
= S
.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf
, E
);
659 assert(!AddrOfE
.isInvalid() && "Can not create unary expression");
660 Args
.push_back(AddrOfE
.get());
661 return Interpreter::InterfaceKind::NoAlloc
;
664 Interpreter::InterfaceKind
VisitBuiltinType(const BuiltinType
*Ty
) {
665 if (Ty
->isNullPtrType())
667 else if (Ty
->isFloatingType())
669 else if (Ty
->isIntegralOrEnumerationType())
670 HandleIntegralOrEnumType(Ty
);
671 else if (Ty
->isVoidType()) {
672 // Do we need to still run `E`?
675 return Interpreter::InterfaceKind::NoAlloc
;
678 Interpreter::InterfaceKind
VisitEnumType(const EnumType
*Ty
) {
679 HandleIntegralOrEnumType(Ty
);
680 return Interpreter::InterfaceKind::NoAlloc
;
684 // Force cast these types to uint64 to reduce the number of overloads of
685 // `__clang_Interpreter_SetValueNoAlloc`.
686 void HandleIntegralOrEnumType(const Type
*Ty
) {
687 TypeSourceInfo
*TSI
= Ctx
.getTrivialTypeSourceInfo(Ctx
.UnsignedLongLongTy
);
688 ExprResult CastedExpr
=
689 S
.BuildCStyleCastExpr(SourceLocation(), TSI
, SourceLocation(), E
);
690 assert(!CastedExpr
.isInvalid() && "Cannot create cstyle cast expr");
691 Args
.push_back(CastedExpr
.get());
694 void HandlePtrType(const Type
*Ty
) {
695 TypeSourceInfo
*TSI
= Ctx
.getTrivialTypeSourceInfo(Ctx
.VoidPtrTy
);
696 ExprResult CastedExpr
=
697 S
.BuildCStyleCastExpr(SourceLocation(), TSI
, SourceLocation(), E
);
698 assert(!CastedExpr
.isInvalid() && "Can not create cstyle cast expression");
699 Args
.push_back(CastedExpr
.get());
704 // This synthesizes a call expression to a speciall
705 // function that is responsible for generating the Value.
706 // In general, we transform:
709 // // 1. If x is a built-in type like int, float.
710 // __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, x);
711 // // 2. If x is a struct, and a lvalue.
712 // __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType,
714 // // 3. If x is a struct, but a rvalue.
715 // new (__clang_Interpreter_SetValueWithAlloc(ThisInterp, OpaqueValue,
718 Expr
*Interpreter::SynthesizeExpr(Expr
*E
) {
719 Sema
&S
= getCompilerInstance()->getSema();
720 ASTContext
&Ctx
= S
.getASTContext();
722 if (!FindRuntimeInterface())
723 llvm_unreachable("We can't find the runtime iterface for pretty print!");
725 // Create parameter `ThisInterp`.
726 auto *ThisInterp
= CStyleCastPtrExpr(S
, Ctx
.VoidPtrTy
, (uintptr_t)this);
728 // Create parameter `OutVal`.
729 auto *OutValue
= CStyleCastPtrExpr(S
, Ctx
.VoidPtrTy
, (uintptr_t)&LastValue
);
731 // Build `__clang_Interpreter_SetValue*` call.
732 RuntimeInterfaceBuilder
Builder(*this, Ctx
, S
, E
, {ThisInterp
, OutValue
});
734 ExprResult Result
= Builder
.getCall();
735 // It could fail, like printing an array type in C. (not supported)
736 if (Result
.isInvalid())
741 // Temporary rvalue struct that need special care.
742 REPL_EXTERNAL_VISIBILITY
void *
743 __clang_Interpreter_SetValueWithAlloc(void *This
, void *OutVal
,
745 Value
&VRef
= *(Value
*)OutVal
;
746 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
747 return VRef
.getPtr();
750 // Pointers, lvalue struct that can take as a reference.
751 REPL_EXTERNAL_VISIBILITY
void
752 __clang_Interpreter_SetValueNoAlloc(void *This
, void *OutVal
, void *OpaqueType
,
754 Value
&VRef
= *(Value
*)OutVal
;
755 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
759 REPL_EXTERNAL_VISIBILITY
void
760 __clang_Interpreter_SetValueNoAlloc(void *This
, void *OutVal
,
762 Value
&VRef
= *(Value
*)OutVal
;
763 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
766 static void SetValueDataBasedOnQualType(Value
&V
, unsigned long long Data
) {
767 QualType QT
= V
.getType();
768 if (const auto *ET
= QT
->getAs
<EnumType
>())
769 QT
= ET
->getDecl()->getIntegerType();
771 switch (QT
->castAs
<BuiltinType
>()->getKind()) {
773 llvm_unreachable("unknown type kind!");
774 #define X(type, name) \
775 case BuiltinType::name: \
783 REPL_EXTERNAL_VISIBILITY
void
784 __clang_Interpreter_SetValueNoAlloc(void *This
, void *OutVal
, void *OpaqueType
,
785 unsigned long long Val
) {
786 Value
&VRef
= *(Value
*)OutVal
;
787 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
788 SetValueDataBasedOnQualType(VRef
, Val
);
791 REPL_EXTERNAL_VISIBILITY
void
792 __clang_Interpreter_SetValueNoAlloc(void *This
, void *OutVal
, void *OpaqueType
,
794 Value
&VRef
= *(Value
*)OutVal
;
795 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
799 REPL_EXTERNAL_VISIBILITY
void
800 __clang_Interpreter_SetValueNoAlloc(void *This
, void *OutVal
, void *OpaqueType
,
802 Value
&VRef
= *(Value
*)OutVal
;
803 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
807 REPL_EXTERNAL_VISIBILITY
void
808 __clang_Interpreter_SetValueNoAlloc(void *This
, void *OutVal
, void *OpaqueType
,
810 Value
&VRef
= *(Value
*)OutVal
;
811 VRef
= Value(static_cast<Interpreter
*>(This
), OpaqueType
);
812 VRef
.setLongDouble(Val
);