https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/94166
None >From 896f3090ca2eadf650459caee9a4106fc7dd381d Mon Sep 17 00:00:00 2001 From: Vassil Vassilev <v.g.vassi...@gmail.com> Date: Thu, 30 May 2024 05:05:41 +0000 Subject: [PATCH] [clang-repl] Teach clang-repl how to load PCHs. --- clang/include/clang/CodeGen/ModuleBuilder.h | 6 ++++++ clang/lib/CodeGen/BackendConsumer.h | 5 ----- clang/lib/CodeGen/CodeGenAction.cpp | 6 +----- clang/lib/CodeGen/ModuleBuilder.cpp | 8 ++++++++ clang/lib/Interpreter/IncrementalParser.cpp | 4 ++++ clang/test/Interpreter/execute-pch.cpp | 14 ++++++++++++++ 6 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 clang/test/Interpreter/execute-pch.cpp diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h index edacd82bf899d..cb5919d1c8af5 100644 --- a/clang/include/clang/CodeGen/ModuleBuilder.h +++ b/clang/include/clang/CodeGen/ModuleBuilder.h @@ -48,6 +48,12 @@ namespace CodeGen { class CodeGenerator : public ASTConsumer { virtual void anchor(); +protected: + /// True if we've finished generating IR. This prevents us from generating + /// additional LLVM IR after emitting output in HandleTranslationUnit. This + /// can happen when Clang plugins trigger additional AST deserialization. + bool IRGenFinished = false; + public: /// Return an opaque reference to the CodeGenModule object, which can /// be used in various secondary APIs. It is valid as long as the diff --git a/clang/lib/CodeGen/BackendConsumer.h b/clang/lib/CodeGen/BackendConsumer.h index 0fe9929dca2b3..76ab5add603b7 100644 --- a/clang/lib/CodeGen/BackendConsumer.h +++ b/clang/lib/CodeGen/BackendConsumer.h @@ -41,11 +41,6 @@ class BackendConsumer : public ASTConsumer { llvm::Timer LLVMIRGeneration; unsigned LLVMIRGenerationRefCount; - /// True if we've finished generating IR. This prevents us from generating - /// additional LLVM IR after emitting output in HandleTranslationUnit. This - /// can happen when Clang plugins trigger additional AST deserialization. - bool IRGenFinished = false; - bool TimerIsEnabled = false; std::unique_ptr<CodeGenerator> Gen; diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 6d3efdb5ffe34..6e2204d2dba0c 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -221,9 +221,7 @@ void BackendConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { } void BackendConsumer::HandleInterestingDecl(DeclGroupRef D) { - // Ignore interesting decls from the AST reader after IRGen is finished. - if (!IRGenFinished) - HandleTopLevelDecl(D); + HandleTopLevelDecl(D); } // Links each entry in LinkModules into our module. Returns true on error. @@ -285,8 +283,6 @@ void BackendConsumer::HandleTranslationUnit(ASTContext &C) { if (LLVMIRGenerationRefCount == 0) LLVMIRGeneration.stopTimer(); } - - IRGenFinished = true; } // Silently ignore if we weren't initialized for some reason. diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index df85295cfb2e2..768d2ffd2d8d9 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -138,6 +138,8 @@ namespace { assert(!M && "Replacing existing Module?"); M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); + IRGenFinished = false; + std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder); Initialize(*Ctx); @@ -179,6 +181,10 @@ namespace { } bool HandleTopLevelDecl(DeclGroupRef DG) override { + // Ignore interesting decls from the AST reader after IRGen is finished. + if (IRGenFinished) + return true; // We can't CodeGen more but pass to other consumers. + // FIXME: Why not return false and abort parsing? if (Diags.hasUnrecoverableErrorOccurred()) return true; @@ -282,6 +288,8 @@ namespace { } void HandleTranslationUnit(ASTContext &Ctx) override { + IRGenFinished = true; + // Release the Builder when there is no error. if (!Diags.hasUnrecoverableErrorOccurred() && Builder) Builder->Release(); diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..eddd4f356c5af 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -219,6 +219,10 @@ IncrementalParser::IncrementalParser(Interpreter &Interp, Consumer = &CI->getASTConsumer(); P.reset( new Parser(CI->getPreprocessor(), CI->getSema(), /*SkipBodies=*/false)); + + if (ExternalASTSource *External = CI->getASTContext().getExternalSource()) + External->StartTranslationUnit(Consumer); + P->Initialize(); // An initial PTU is needed as CUDA includes some headers automatically diff --git a/clang/test/Interpreter/execute-pch.cpp b/clang/test/Interpreter/execute-pch.cpp new file mode 100644 index 0000000000000..30390d02f8c5c --- /dev/null +++ b/clang/test/Interpreter/execute-pch.cpp @@ -0,0 +1,14 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: rm -f %t.pch +// RUN: %clang_cc1 -fmax-type-align=16 -pic-level 2 -fdeprecated-macro -stack-protector 1 -fblocks -fskip-odr-check-in-gmf -fexceptions -fcxx-exceptions -fgnuc-version=0 -triple=%target_triple -DPCH -fincremental-extensions -emit-pch -x c++-header -o %t.pch %s +// RUN: clang-repl -Xcc -fgnuc-version=0 -Xcc -triple=%target_triple -Xcc -include-pch -Xcc %t.pch '#include "%s"' | FileCheck %s + +#ifdef PCH +int f_pch() { return 5; } +#endif // PCH + +extern "C" int printf(const char *, ...); +auto r1 = printf("f_pch = %d\n", f_pch()); +// CHECK: f_pch = 5 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits