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 *> 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>> 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>> 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>> 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>> 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>> 220 IncrementalCompilerBuilder::CreateCudaDevice() { 221 return IncrementalCompilerBuilder::createCuda(true); 222 } 223 224 llvm::Expected<std::unique_ptr<CompilerInstance>> 225 IncrementalCompilerBuilder::CreateCudaHost() { 226 return IncrementalCompilerBuilder::createCuda(false); 227 } 228 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 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>> 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>> 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 321 const CompilerInstance *Interpreter::getCompilerInstance() const { 322 return IncrParser->getCI(); 323 } 324 325 CompilerInstance *Interpreter::getCompilerInstance() { 326 return IncrParser->getCI(); 327 } 328 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 338 ASTContext &Interpreter::getASTContext() { 339 return getCompilerInstance()->getASTContext(); 340 } 341 342 const ASTContext &Interpreter::getASTContext() const { 343 return getCompilerInstance()->getASTContext(); 344 } 345 346 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 &> 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 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 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 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> 417 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> 427 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> 437 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 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 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> 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 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: 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 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 644 Interpreter::InterfaceKind VisitRecordType(const RecordType *Ty) { 645 return Interpreter::InterfaceKind::WithAlloc; 646 } 647 648 Interpreter::InterfaceKind 649 VisitMemberPointerType(const MemberPointerType *Ty) { 650 return Interpreter::InterfaceKind::WithAlloc; 651 } 652 653 Interpreter::InterfaceKind 654 VisitConstantArrayType(const ConstantArrayType *Ty) { 655 return Interpreter::InterfaceKind::CopyArray; 656 } 657 658 Interpreter::InterfaceKind 659 VisitFunctionProtoType(const FunctionProtoType *Ty) { 660 HandlePtrType(Ty); 661 return Interpreter::InterfaceKind::NoAlloc; 662 } 663 664 Interpreter::InterfaceKind VisitPointerType(const PointerType *Ty) { 665 HandlePtrType(Ty); 666 return Interpreter::InterfaceKind::NoAlloc; 667 } 668 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 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 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`. 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 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 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 * 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 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 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 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 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 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 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 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 * 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