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::string TT, 136 std::vector<const char *> &ClangArgv) { 137 138 // If we don't know ClangArgv0 or the address of main() at this point, try 139 // to guess it anyway (it's possible on some platforms). 140 std::string MainExecutableName = 141 llvm::sys::fs::getMainExecutable(nullptr, nullptr); 142 143 ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str()); 144 145 // Prepending -c to force the driver to do something if no action was 146 // specified. By prepending we allow users to override the default 147 // action and use other actions in incremental mode. 148 // FIXME: Print proper driver diagnostics if the driver flags are wrong. 149 // We do C++ by default; append right after argv[0] if no "-x" given 150 ClangArgv.insert(ClangArgv.end(), "-Xclang"); 151 ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions"); 152 ClangArgv.insert(ClangArgv.end(), "-c"); 153 154 // Put a dummy C++ file on to ensure there's at least one compile job for the 155 // driver to construct. 156 ClangArgv.push_back("<<< inputs >>>"); 157 158 // Buffer diagnostics from argument parsing so that we can output them using a 159 // well formed diagnostic object. 160 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 161 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = 162 CreateAndPopulateDiagOpts(ClangArgv); 163 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 164 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); 165 166 driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, 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 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple(); 189 return IncrementalCompilerBuilder::create(TT, Argv); 190 } 191 192 llvm::Expected<std::unique_ptr<CompilerInstance>> 193 IncrementalCompilerBuilder::createCuda(bool device) { 194 std::vector<const char *> Argv; 195 Argv.reserve(5 + 4 + UserArgs.size()); 196 197 Argv.push_back("-xcuda"); 198 if (device) 199 Argv.push_back("--cuda-device-only"); 200 else 201 Argv.push_back("--cuda-host-only"); 202 203 std::string SDKPathArg = "--cuda-path="; 204 if (!CudaSDKPath.empty()) { 205 SDKPathArg += CudaSDKPath; 206 Argv.push_back(SDKPathArg.c_str()); 207 } 208 209 std::string ArchArg = "--offload-arch="; 210 if (!OffloadArch.empty()) { 211 ArchArg += OffloadArch; 212 Argv.push_back(ArchArg.c_str()); 213 } 214 215 Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); 216 217 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple(); 218 return IncrementalCompilerBuilder::create(TT, Argv); 219 } 220 221 llvm::Expected<std::unique_ptr<CompilerInstance>> 222 IncrementalCompilerBuilder::CreateCudaDevice() { 223 return IncrementalCompilerBuilder::createCuda(true); 224 } 225 226 llvm::Expected<std::unique_ptr<CompilerInstance>> 227 IncrementalCompilerBuilder::CreateCudaHost() { 228 return IncrementalCompilerBuilder::createCuda(false); 229 } 230 231 Interpreter::Interpreter(std::unique_ptr<CompilerInstance> CI, 232 llvm::Error &Err) { 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); 238 } 239 240 Interpreter::~Interpreter() { 241 if (IncrExecutor) { 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))); 246 } 247 } 248 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 251 // code them. 252 const char *const Runtimes = R"( 253 #ifdef __cplusplus 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 struct __clang_Interpreter_NewTag{} __ci_newtag; 262 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; 263 template <class T, class = T (*)() /*disable for arrays*/> 264 void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) { 265 for (auto Idx = 0; Idx < Size; ++Idx) 266 new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]); 267 } 268 template <class T, unsigned long N> 269 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { 270 __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); 271 } 272 #endif // __cplusplus 273 )"; 274 275 llvm::Expected<std::unique_ptr<Interpreter>> 276 Interpreter::create(std::unique_ptr<CompilerInstance> CI) { 277 llvm::Error Err = llvm::Error::success(); 278 auto Interp = 279 std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err)); 280 if (Err) 281 return std::move(Err); 282 283 // Add runtime code and set a marker to hide it from user code. Undo will not 284 // go through that. 285 auto PTU = Interp->Parse(Runtimes); 286 if (!PTU) 287 return PTU.takeError(); 288 Interp->markUserCodeStart(); 289 290 Interp->ValuePrintingInfo.resize(4); 291 return std::move(Interp); 292 } 293 294 llvm::Expected<std::unique_ptr<Interpreter>> 295 Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI, 296 std::unique_ptr<CompilerInstance> DCI) { 297 // avoid writing fat binary to disk using an in-memory virtual file system 298 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS = 299 std::make_unique<llvm::vfs::InMemoryFileSystem>(); 300 llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS = 301 std::make_unique<llvm::vfs::OverlayFileSystem>( 302 llvm::vfs::getRealFileSystem()); 303 OverlayVFS->pushOverlay(IMVFS); 304 CI->createFileManager(OverlayVFS); 305 306 auto Interp = Interpreter::create(std::move(CI)); 307 if (auto E = Interp.takeError()) 308 return std::move(E); 309 310 llvm::Error Err = llvm::Error::success(); 311 auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>( 312 **Interp, std::move(DCI), *(*Interp)->IncrParser.get(), 313 *(*Interp)->TSCtx->getContext(), IMVFS, Err); 314 if (Err) 315 return std::move(Err); 316 317 (*Interp)->DeviceParser = std::move(DeviceParser); 318 319 return Interp; 320 } 321 322 const CompilerInstance *Interpreter::getCompilerInstance() const { 323 return IncrParser->getCI(); 324 } 325 326 CompilerInstance *Interpreter::getCompilerInstance() { 327 return IncrParser->getCI(); 328 } 329 330 llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() { 331 if (!IncrExecutor) { 332 if (auto Err = CreateExecutor()) 333 return std::move(Err); 334 } 335 336 return IncrExecutor->GetExecutionEngine(); 337 } 338 339 ASTContext &Interpreter::getASTContext() { 340 return getCompilerInstance()->getASTContext(); 341 } 342 343 const ASTContext &Interpreter::getASTContext() const { 344 return getCompilerInstance()->getASTContext(); 345 } 346 347 void Interpreter::markUserCodeStart() { 348 assert(!InitPTUSize && "We only do this once"); 349 InitPTUSize = IncrParser->getPTUs().size(); 350 } 351 352 size_t Interpreter::getEffectivePTUSize() const { 353 std::list<PartialTranslationUnit> &PTUs = IncrParser->getPTUs(); 354 assert(PTUs.size() >= InitPTUSize && "empty PTU list?"); 355 return PTUs.size() - InitPTUSize; 356 } 357 358 llvm::Expected<PartialTranslationUnit &> 359 Interpreter::Parse(llvm::StringRef Code) { 360 // If we have a device parser, parse it first. 361 // The generated code will be included in the host compilation 362 if (DeviceParser) { 363 auto DevicePTU = DeviceParser->Parse(Code); 364 if (auto E = DevicePTU.takeError()) 365 return std::move(E); 366 } 367 368 // Tell the interpreter sliently ignore unused expressions since value 369 // printing could cause it. 370 getCompilerInstance()->getDiagnostics().setSeverity( 371 clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation()); 372 return IncrParser->Parse(Code); 373 } 374 375 llvm::Error Interpreter::CreateExecutor() { 376 const clang::TargetInfo &TI = 377 getCompilerInstance()->getASTContext().getTargetInfo(); 378 if (IncrExecutor) 379 return llvm::make_error<llvm::StringError>("Operation failed. " 380 "Execution engine exists", 381 std::error_code()); 382 llvm::Error Err = llvm::Error::success(); 383 auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, Err, TI); 384 if (!Err) 385 IncrExecutor = std::move(Executor); 386 387 return Err; 388 } 389 390 void Interpreter::ResetExecutor() { IncrExecutor.reset(); } 391 392 llvm::Error Interpreter::Execute(PartialTranslationUnit &T) { 393 assert(T.TheModule); 394 if (!IncrExecutor) { 395 auto Err = CreateExecutor(); 396 if (Err) 397 return Err; 398 } 399 // FIXME: Add a callback to retain the llvm::Module once the JIT is done. 400 if (auto Err = IncrExecutor->addModule(T)) 401 return Err; 402 403 if (auto Err = IncrExecutor->runCtors()) 404 return Err; 405 406 return llvm::Error::success(); 407 } 408 409 llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) { 410 411 auto PTU = Parse(Code); 412 if (!PTU) 413 return PTU.takeError(); 414 if (PTU->TheModule) 415 if (llvm::Error Err = Execute(*PTU)) 416 return Err; 417 418 if (LastValue.isValid()) { 419 if (!V) { 420 LastValue.dump(); 421 LastValue.clear(); 422 } else 423 *V = std::move(LastValue); 424 } 425 return llvm::Error::success(); 426 } 427 428 llvm::Expected<llvm::orc::ExecutorAddr> 429 Interpreter::getSymbolAddress(GlobalDecl GD) const { 430 if (!IncrExecutor) 431 return llvm::make_error<llvm::StringError>("Operation failed. " 432 "No execution engine", 433 std::error_code()); 434 llvm::StringRef MangledName = IncrParser->GetMangledName(GD); 435 return getSymbolAddress(MangledName); 436 } 437 438 llvm::Expected<llvm::orc::ExecutorAddr> 439 Interpreter::getSymbolAddress(llvm::StringRef IRName) const { 440 if (!IncrExecutor) 441 return llvm::make_error<llvm::StringError>("Operation failed. " 442 "No execution engine", 443 std::error_code()); 444 445 return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName); 446 } 447 448 llvm::Expected<llvm::orc::ExecutorAddr> 449 Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const { 450 if (!IncrExecutor) 451 return llvm::make_error<llvm::StringError>("Operation failed. " 452 "No execution engine", 453 std::error_code()); 454 455 return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName); 456 } 457 458 llvm::Error Interpreter::Undo(unsigned N) { 459 460 std::list<PartialTranslationUnit> &PTUs = IncrParser->getPTUs(); 461 if (N > getEffectivePTUSize()) 462 return llvm::make_error<llvm::StringError>("Operation failed. " 463 "Too many undos", 464 std::error_code()); 465 for (unsigned I = 0; I < N; I++) { 466 if (IncrExecutor) { 467 if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back())) 468 return Err; 469 } 470 471 IncrParser->CleanUpPTU(PTUs.back()); 472 PTUs.pop_back(); 473 } 474 return llvm::Error::success(); 475 } 476 477 llvm::Error Interpreter::LoadDynamicLibrary(const char *name) { 478 auto EE = getExecutionEngine(); 479 if (!EE) 480 return EE.takeError(); 481 482 auto &DL = EE->getDataLayout(); 483 484 if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load( 485 name, DL.getGlobalPrefix())) 486 EE->getMainJITDylib().addGenerator(std::move(*DLSG)); 487 else 488 return DLSG.takeError(); 489 490 return llvm::Error::success(); 491 } 492 493 llvm::Expected<llvm::orc::ExecutorAddr> 494 Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) { 495 assert(CXXRD && "Cannot compile a destructor for a nullptr"); 496 if (auto Dtor = Dtors.find(CXXRD); Dtor != Dtors.end()) 497 return Dtor->getSecond(); 498 499 if (CXXRD->hasIrrelevantDestructor()) 500 return llvm::orc::ExecutorAddr{}; 501 502 CXXDestructorDecl *DtorRD = 503 getCompilerInstance()->getSema().LookupDestructor(CXXRD); 504 505 llvm::StringRef Name = 506 IncrParser->GetMangledName(GlobalDecl(DtorRD, Dtor_Base)); 507 auto AddrOrErr = getSymbolAddress(Name); 508 if (!AddrOrErr) 509 return AddrOrErr.takeError(); 510 511 Dtors[CXXRD] = *AddrOrErr; 512 return AddrOrErr; 513 } 514 515 static constexpr llvm::StringRef MagicRuntimeInterface[] = { 516 "__clang_Interpreter_SetValueNoAlloc", 517 "__clang_Interpreter_SetValueWithAlloc", 518 "__clang_Interpreter_SetValueCopyArr", "__ci_newtag"}; 519 520 static std::unique_ptr<RuntimeInterfaceBuilder> 521 createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx, 522 Sema &S); 523 524 std::unique_ptr<RuntimeInterfaceBuilder> Interpreter::FindRuntimeInterface() { 525 if (llvm::all_of(ValuePrintingInfo, [](Expr *E) { return E != nullptr; })) 526 return nullptr; 527 528 Sema &S = getCompilerInstance()->getSema(); 529 ASTContext &Ctx = S.getASTContext(); 530 531 auto LookupInterface = [&](Expr *&Interface, llvm::StringRef Name) { 532 LookupResult R(S, &Ctx.Idents.get(Name), SourceLocation(), 533 Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration); 534 S.LookupQualifiedName(R, Ctx.getTranslationUnitDecl()); 535 if (R.empty()) 536 return false; 537 538 CXXScopeSpec CSS; 539 Interface = S.BuildDeclarationNameExpr(CSS, R, /*ADL=*/false).get(); 540 return true; 541 }; 542 543 if (!LookupInterface(ValuePrintingInfo[NoAlloc], 544 MagicRuntimeInterface[NoAlloc])) 545 return nullptr; 546 if (!LookupInterface(ValuePrintingInfo[WithAlloc], 547 MagicRuntimeInterface[WithAlloc])) 548 return nullptr; 549 if (!LookupInterface(ValuePrintingInfo[CopyArray], 550 MagicRuntimeInterface[CopyArray])) 551 return nullptr; 552 if (!LookupInterface(ValuePrintingInfo[NewTag], 553 MagicRuntimeInterface[NewTag])) 554 return nullptr; 555 556 return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); 557 } 558 559 namespace { 560 561 class InterfaceKindVisitor 562 : public TypeVisitor<InterfaceKindVisitor, Interpreter::InterfaceKind> { 563 friend class InProcessRuntimeInterfaceBuilder; 564 565 ASTContext &Ctx; 566 Sema &S; 567 Expr *E; 568 llvm::SmallVector<Expr *, 3> Args; 569 570 public: 571 InterfaceKindVisitor(ASTContext &Ctx, Sema &S, Expr *E) 572 : Ctx(Ctx), S(S), E(E) {} 573 574 Interpreter::InterfaceKind VisitRecordType(const RecordType *Ty) { 575 return Interpreter::InterfaceKind::WithAlloc; 576 } 577 578 Interpreter::InterfaceKind 579 VisitMemberPointerType(const MemberPointerType *Ty) { 580 return Interpreter::InterfaceKind::WithAlloc; 581 } 582 583 Interpreter::InterfaceKind 584 VisitConstantArrayType(const ConstantArrayType *Ty) { 585 return Interpreter::InterfaceKind::CopyArray; 586 } 587 588 Interpreter::InterfaceKind 589 VisitFunctionProtoType(const FunctionProtoType *Ty) { 590 HandlePtrType(Ty); 591 return Interpreter::InterfaceKind::NoAlloc; 592 } 593 594 Interpreter::InterfaceKind VisitPointerType(const PointerType *Ty) { 595 HandlePtrType(Ty); 596 return Interpreter::InterfaceKind::NoAlloc; 597 } 598 599 Interpreter::InterfaceKind VisitReferenceType(const ReferenceType *Ty) { 600 ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, E); 601 assert(!AddrOfE.isInvalid() && "Can not create unary expression"); 602 Args.push_back(AddrOfE.get()); 603 return Interpreter::InterfaceKind::NoAlloc; 604 } 605 606 Interpreter::InterfaceKind VisitBuiltinType(const BuiltinType *Ty) { 607 if (Ty->isNullPtrType()) 608 Args.push_back(E); 609 else if (Ty->isFloatingType()) 610 Args.push_back(E); 611 else if (Ty->isIntegralOrEnumerationType()) 612 HandleIntegralOrEnumType(Ty); 613 else if (Ty->isVoidType()) { 614 // Do we need to still run `E`? 615 } 616 617 return Interpreter::InterfaceKind::NoAlloc; 618 } 619 620 Interpreter::InterfaceKind VisitEnumType(const EnumType *Ty) { 621 HandleIntegralOrEnumType(Ty); 622 return Interpreter::InterfaceKind::NoAlloc; 623 } 624 625 private: 626 // Force cast these types to uint64 to reduce the number of overloads of 627 // `__clang_Interpreter_SetValueNoAlloc`. 628 void HandleIntegralOrEnumType(const Type *Ty) { 629 TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.UnsignedLongLongTy); 630 ExprResult CastedExpr = 631 S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E); 632 assert(!CastedExpr.isInvalid() && "Cannot create cstyle cast expr"); 633 Args.push_back(CastedExpr.get()); 634 } 635 636 void HandlePtrType(const Type *Ty) { 637 TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.VoidPtrTy); 638 ExprResult CastedExpr = 639 S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E); 640 assert(!CastedExpr.isInvalid() && "Can not create cstyle cast expression"); 641 Args.push_back(CastedExpr.get()); 642 } 643 }; 644 645 class InProcessRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder { 646 Interpreter &Interp; 647 ASTContext &Ctx; 648 Sema &S; 649 650 public: 651 InProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &C, Sema &S) 652 : Interp(Interp), Ctx(C), S(S) {} 653 654 TransformExprFunction *getPrintValueTransformer() override { 655 return &transformForValuePrinting; 656 } 657 658 private: 659 static ExprResult transformForValuePrinting(RuntimeInterfaceBuilder *Builder, 660 Expr *E, 661 ArrayRef<Expr *> FixedArgs) { 662 auto *B = static_cast<InProcessRuntimeInterfaceBuilder *>(Builder); 663 664 // Get rid of ExprWithCleanups. 665 if (auto *EWC = llvm::dyn_cast_if_present<ExprWithCleanups>(E)) 666 E = EWC->getSubExpr(); 667 668 InterfaceKindVisitor Visitor(B->Ctx, B->S, E); 669 670 // The Interpreter* parameter and the out parameter `OutVal`. 671 for (Expr *E : FixedArgs) 672 Visitor.Args.push_back(E); 673 674 QualType Ty = E->getType(); 675 QualType DesugaredTy = Ty.getDesugaredType(B->Ctx); 676 677 // For lvalue struct, we treat it as a reference. 678 if (DesugaredTy->isRecordType() && E->isLValue()) { 679 DesugaredTy = B->Ctx.getLValueReferenceType(DesugaredTy); 680 Ty = B->Ctx.getLValueReferenceType(Ty); 681 } 682 683 Expr *TypeArg = CStyleCastPtrExpr(B->S, B->Ctx.VoidPtrTy, 684 (uintptr_t)Ty.getAsOpaquePtr()); 685 // The QualType parameter `OpaqueType`, represented as `void*`. 686 Visitor.Args.push_back(TypeArg); 687 688 // We push the last parameter based on the type of the Expr. Note we need 689 // special care for rvalue struct. 690 Interpreter::InterfaceKind Kind = Visitor.Visit(&*DesugaredTy); 691 switch (Kind) { 692 case Interpreter::InterfaceKind::WithAlloc: 693 case Interpreter::InterfaceKind::CopyArray: { 694 // __clang_Interpreter_SetValueWithAlloc. 695 ExprResult AllocCall = B->S.ActOnCallExpr( 696 /*Scope=*/nullptr, 697 B->Interp 698 .getValuePrintingInfo()[Interpreter::InterfaceKind::WithAlloc], 699 E->getBeginLoc(), Visitor.Args, E->getEndLoc()); 700 assert(!AllocCall.isInvalid() && "Can't create runtime interface call!"); 701 702 TypeSourceInfo *TSI = 703 B->Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation()); 704 705 // Force CodeGen to emit destructor. 706 if (auto *RD = Ty->getAsCXXRecordDecl()) { 707 auto *Dtor = B->S.LookupDestructor(RD); 708 Dtor->addAttr(UsedAttr::CreateImplicit(B->Ctx)); 709 B->Interp.getCompilerInstance()->getASTConsumer().HandleTopLevelDecl( 710 DeclGroupRef(Dtor)); 711 } 712 713 // __clang_Interpreter_SetValueCopyArr. 714 if (Kind == Interpreter::InterfaceKind::CopyArray) { 715 const auto *ConstantArrTy = 716 cast<ConstantArrayType>(DesugaredTy.getTypePtr()); 717 size_t ArrSize = B->Ctx.getConstantArrayElementCount(ConstantArrTy); 718 Expr *ArrSizeExpr = IntegerLiteralExpr(B->Ctx, ArrSize); 719 Expr *Args[] = {E, AllocCall.get(), ArrSizeExpr}; 720 return B->S.ActOnCallExpr( 721 /*Scope *=*/nullptr, 722 B->Interp 723 .getValuePrintingInfo()[Interpreter::InterfaceKind::CopyArray], 724 SourceLocation(), Args, SourceLocation()); 725 } 726 Expr *Args[] = { 727 AllocCall.get(), 728 B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NewTag]}; 729 ExprResult CXXNewCall = B->S.BuildCXXNew( 730 E->getSourceRange(), 731 /*UseGlobal=*/true, /*PlacementLParen=*/SourceLocation(), Args, 732 /*PlacementRParen=*/SourceLocation(), 733 /*TypeIdParens=*/SourceRange(), TSI->getType(), TSI, std::nullopt, 734 E->getSourceRange(), E); 735 736 assert(!CXXNewCall.isInvalid() && 737 "Can't create runtime placement new call!"); 738 739 return B->S.ActOnFinishFullExpr(CXXNewCall.get(), 740 /*DiscardedValue=*/false); 741 } 742 // __clang_Interpreter_SetValueNoAlloc. 743 case Interpreter::InterfaceKind::NoAlloc: { 744 return B->S.ActOnCallExpr( 745 /*Scope=*/nullptr, 746 B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NoAlloc], 747 E->getBeginLoc(), Visitor.Args, E->getEndLoc()); 748 } 749 default: 750 llvm_unreachable("Unhandled Interpreter::InterfaceKind"); 751 } 752 } 753 }; 754 } // namespace 755 756 static std::unique_ptr<RuntimeInterfaceBuilder> 757 createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx, 758 Sema &S) { 759 return std::make_unique<InProcessRuntimeInterfaceBuilder>(Interp, Ctx, S); 760 } 761 762 // This synthesizes a call expression to a speciall 763 // function that is responsible for generating the Value. 764 // In general, we transform: 765 // clang-repl> x 766 // To: 767 // // 1. If x is a built-in type like int, float. 768 // __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, x); 769 // // 2. If x is a struct, and a lvalue. 770 // __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, 771 // &x); 772 // // 3. If x is a struct, but a rvalue. 773 // new (__clang_Interpreter_SetValueWithAlloc(ThisInterp, OpaqueValue, 774 // xQualType)) (x); 775 776 Expr *Interpreter::SynthesizeExpr(Expr *E) { 777 Sema &S = getCompilerInstance()->getSema(); 778 ASTContext &Ctx = S.getASTContext(); 779 780 if (!RuntimeIB) { 781 RuntimeIB = FindRuntimeInterface(); 782 AddPrintValueCall = RuntimeIB->getPrintValueTransformer(); 783 } 784 785 assert(AddPrintValueCall && 786 "We don't have a runtime interface for pretty print!"); 787 788 // Create parameter `ThisInterp`. 789 auto *ThisInterp = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)this); 790 791 // Create parameter `OutVal`. 792 auto *OutValue = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)&LastValue); 793 794 // Build `__clang_Interpreter_SetValue*` call. 795 ExprResult Result = 796 AddPrintValueCall(RuntimeIB.get(), E, {ThisInterp, OutValue}); 797 798 // It could fail, like printing an array type in C. (not supported) 799 if (Result.isInvalid()) 800 return E; 801 return Result.get(); 802 } 803 804 // Temporary rvalue struct that need special care. 805 REPL_EXTERNAL_VISIBILITY void * 806 __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, 807 void *OpaqueType) { 808 Value &VRef = *(Value *)OutVal; 809 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 810 return VRef.getPtr(); 811 } 812 813 // Pointers, lvalue struct that can take as a reference. 814 REPL_EXTERNAL_VISIBILITY void 815 __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, 816 void *Val) { 817 Value &VRef = *(Value *)OutVal; 818 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 819 VRef.setPtr(Val); 820 } 821 822 REPL_EXTERNAL_VISIBILITY void 823 __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, 824 void *OpaqueType) { 825 Value &VRef = *(Value *)OutVal; 826 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 827 } 828 829 static void SetValueDataBasedOnQualType(Value &V, unsigned long long Data) { 830 QualType QT = V.getType(); 831 if (const auto *ET = QT->getAs<EnumType>()) 832 QT = ET->getDecl()->getIntegerType(); 833 834 switch (QT->castAs<BuiltinType>()->getKind()) { 835 default: 836 llvm_unreachable("unknown type kind!"); 837 #define X(type, name) \ 838 case BuiltinType::name: \ 839 V.set##name(Data); \ 840 break; 841 REPL_BUILTIN_TYPES 842 #undef X 843 } 844 } 845 846 REPL_EXTERNAL_VISIBILITY void 847 __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, 848 unsigned long long Val) { 849 Value &VRef = *(Value *)OutVal; 850 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 851 SetValueDataBasedOnQualType(VRef, Val); 852 } 853 854 REPL_EXTERNAL_VISIBILITY void 855 __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, 856 float Val) { 857 Value &VRef = *(Value *)OutVal; 858 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 859 VRef.setFloat(Val); 860 } 861 862 REPL_EXTERNAL_VISIBILITY void 863 __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, 864 double Val) { 865 Value &VRef = *(Value *)OutVal; 866 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 867 VRef.setDouble(Val); 868 } 869 870 REPL_EXTERNAL_VISIBILITY void 871 __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, 872 long double Val) { 873 Value &VRef = *(Value *)OutVal; 874 VRef = Value(static_cast<Interpreter *>(This), OpaqueType); 875 VRef.setLongDouble(Val); 876 } 877 878 // A trampoline to work around the fact that operator placement new cannot 879 // really be forward declared due to libc++ and libstdc++ declaration mismatch. 880 // FIXME: __clang_Interpreter_NewTag is ODR violation because we get the same 881 // definition in the interpreter runtime. We should move it in a runtime header 882 // which gets included by the interpreter and here. 883 struct __clang_Interpreter_NewTag {}; 884 REPL_EXTERNAL_VISIBILITY void * 885 operator new(size_t __sz, void *__p, __clang_Interpreter_NewTag) noexcept { 886 // Just forward to the standard operator placement new. 887 return operator new(__sz, __p); 888 } 889