|
50 | 50 | #include "llvm/Support/ErrorHandling.h"
|
51 | 51 | #include "llvm/Support/raw_ostream.h"
|
52 | 52 | #include "llvm/TargetParser/Host.h"
|
| 53 | +#include "llvm/Transforms/Utils/Cloning.h" // for CloneModule |
| 54 | + |
| 55 | +#define DEBUG_TYPE "clang-repl" |
53 | 56 |
|
54 | 57 | using namespace clang;
|
55 | 58 | // FIXME: Figure out how to unify with namespace init_convenience from
|
@@ -338,19 +341,8 @@ class IncrementalAction : public WrapperFrontendAction {
|
338 | 341 | }
|
339 | 342 |
|
340 | 343 | void ExecuteAction() override {
|
341 |
| - CompilerInstance &CI = getCompilerInstance(); |
342 |
| - assert(CI.hasPreprocessor() && "No PP!"); |
343 |
| - |
344 |
| - // Use a code completion consumer? |
345 |
| - CodeCompleteConsumer *CompletionConsumer = nullptr; |
346 |
| - if (CI.hasCodeCompletionConsumer()) |
347 |
| - CompletionConsumer = &CI.getCodeCompletionConsumer(); |
348 |
| - |
349 |
| - Preprocessor &PP = CI.getPreprocessor(); |
350 |
| - PP.EnterMainSourceFile(); |
351 |
| - |
352 |
| - if (!CI.hasSema()) |
353 |
| - CI.createSema(getTranslationUnitKind(), CompletionConsumer); |
| 344 | + WrapperFrontendAction::ExecuteAction(); |
| 345 | + getCompilerInstance().getSema().CurContext = nullptr; |
354 | 346 | }
|
355 | 347 |
|
356 | 348 | // Do not terminate after processing the input. This allows us to keep various
|
@@ -384,27 +376,29 @@ Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
|
384 | 376 | return;
|
385 | 377 | CI->ExecuteAction(*Act);
|
386 | 378 |
|
387 |
| - ASTContext &C = CI->getASTContext(); |
388 |
| - |
389 | 379 | IncrParser = std::make_unique<IncrementalParser>(*CI, ErrOut);
|
390 | 380 |
|
391 | 381 | if (ErrOut)
|
392 | 382 | return;
|
393 | 383 |
|
394 | 384 | if (getCodeGen()) {
|
395 | 385 | CachedInCodeGenModule = GenModule();
|
| 386 | + // The initial PTU is filled by `-include` or by CUDA includes |
| 387 | + // automatically. |
| 388 | + if (!CI->getPreprocessorOpts().Includes.empty()) { |
| 389 | + // We can't really directly pass the CachedInCodeGenModule to the Jit |
| 390 | + // because it will steal it, causing dangling references as explained in |
| 391 | + // Interpreter::Execute |
| 392 | + auto M = llvm::CloneModule(*CachedInCodeGenModule); |
| 393 | + ASTContext &C = CI->getASTContext(); |
| 394 | + RegisterPTU(C.getTranslationUnitDecl(), std::move(M)); |
| 395 | + } |
396 | 396 | if (llvm::Error Err = CreateExecutor()) {
|
397 | 397 | ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
|
398 | 398 | return;
|
399 | 399 | }
|
400 | 400 | }
|
401 | 401 |
|
402 |
| - // The initial PTU is filled by `-include` or by CUDA includes automatically. |
403 |
| - RegisterPTU(C.getTranslationUnitDecl()); |
404 |
| - |
405 |
| - // Prepare the IncrParser for input. |
406 |
| - llvm::cantFail(Parse("")); |
407 |
| - |
408 | 402 | // Not all frontends support code-generation, e.g. ast-dump actions don't
|
409 | 403 | if (getCodeGen()) {
|
410 | 404 | // Process the PTUs that came from initialization. For example -include will
|
@@ -534,14 +528,25 @@ size_t Interpreter::getEffectivePTUSize() const {
|
534 | 528 | return PTUs.size() - InitPTUSize;
|
535 | 529 | }
|
536 | 530 |
|
537 |
| -PartialTranslationUnit &Interpreter::RegisterPTU(TranslationUnitDecl *TU) { |
| 531 | +PartialTranslationUnit & |
| 532 | +Interpreter::RegisterPTU(TranslationUnitDecl *TU, |
| 533 | + std::unique_ptr<llvm::Module> M /*={}*/) { |
538 | 534 | PTUs.emplace_back(PartialTranslationUnit());
|
539 | 535 | PartialTranslationUnit &LastPTU = PTUs.back();
|
540 | 536 | LastPTU.TUPart = TU;
|
541 | 537 |
|
542 |
| - if (std::unique_ptr<llvm::Module> M = GenModule()) |
543 |
| - LastPTU.TheModule = std::move(M); |
| 538 | + if (!M) |
| 539 | + M = GenModule(); |
| 540 | + |
| 541 | + assert((!getCodeGen() || M) && "Must have a llvm::Module at this point"); |
544 | 542 |
|
| 543 | + LastPTU.TheModule = std::move(M); |
| 544 | + LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1 |
| 545 | + << ": [TU=" << LastPTU.TUPart); |
| 546 | + if (LastPTU.TheModule) |
| 547 | + LLVM_DEBUG(llvm::dbgs() << ", M=" << LastPTU.TheModule.get() << " (" |
| 548 | + << LastPTU.TheModule->getName() << ")"); |
| 549 | + LLVM_DEBUG(llvm::dbgs() << "]\n"); |
545 | 550 | return LastPTU;
|
546 | 551 | }
|
547 | 552 |
|
@@ -614,6 +619,14 @@ void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
|
614 | 619 |
|
615 | 620 | llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
|
616 | 621 | assert(T.TheModule);
|
| 622 | + LLVM_DEBUG(llvm::dbgs() |
| 623 | + << "execute-ptu " |
| 624 | + << ((std::find(PTUs.begin(), PTUs.end(), T) != PTUs.end()) |
| 625 | + ? std::distance(PTUs.begin(), |
| 626 | + std::find(PTUs.begin(), PTUs.end(), T)) |
| 627 | + : -1) |
| 628 | + << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get() << " (" |
| 629 | + << T.TheModule->getName() << ")]\n"); |
617 | 630 | if (!IncrExecutor) {
|
618 | 631 | auto Err = CreateExecutor();
|
619 | 632 | if (Err)
|
@@ -722,10 +735,12 @@ std::unique_ptr<llvm::Module> Interpreter::GenModule() {
|
722 | 735 | // of the module which does not map well to CodeGen's design. To work this
|
723 | 736 | // around we created an empty module to make CodeGen happy. We should make
|
724 | 737 | // sure it always stays empty.
|
725 |
| - assert((!CachedInCodeGenModule || (CachedInCodeGenModule->empty() && |
726 |
| - CachedInCodeGenModule->global_empty() && |
727 |
| - CachedInCodeGenModule->alias_empty() && |
728 |
| - CachedInCodeGenModule->ifunc_empty())) && |
| 738 | + assert(((!CachedInCodeGenModule || |
| 739 | + !getCompilerInstance()->getPreprocessorOpts().Includes.empty()) || |
| 740 | + (CachedInCodeGenModule->empty() && |
| 741 | + CachedInCodeGenModule->global_empty() && |
| 742 | + CachedInCodeGenModule->alias_empty() && |
| 743 | + CachedInCodeGenModule->ifunc_empty())) && |
729 | 744 | "CodeGen wrote to a readonly module");
|
730 | 745 | std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
|
731 | 746 | CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
|
|
0 commit comments