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