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