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