[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)

Vassil Vassilev via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 12 00:30:42 PDT 2024


https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/94166

>From d2d533d0962e4260f052179c199a2e5ebe44edb1 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev at gmail.com>
Date: Thu, 30 May 2024 05:05:41 +0000
Subject: [PATCH 1/2] [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 59b9840d02e08..f1b8229edd362 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -52,6 +52,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 a023d29cbd1d7..a4d737aa2e587 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 e87226e60297c..0ffc5119f19c5 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.
@@ -280,8 +278,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 d4e0ab0339a8b..1be9f286ab932 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 b7c809c45098c..831b99c814f32 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

>From 7d245bae4b80c7cf64793f7c9d560b76c7d6ec89 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev at gmail.com>
Date: Mon, 3 Jun 2024 16:03:44 +0000
Subject: [PATCH 2/2] Address comments

---
 clang/lib/CodeGen/ModuleBuilder.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index 1be9f286ab932..fd304969d20f3 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -288,7 +288,6 @@ namespace {
     }
 
     void HandleTranslationUnit(ASTContext &Ctx) override {
-      IRGenFinished = true;
 
       // Release the Builder when there is no error.
       if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
@@ -300,8 +299,9 @@ namespace {
         if (Builder)
           Builder->clear();
         M.reset();
-        return;
       }
+
+      IRGenFinished = true;
     }
 
     void AssignInheritanceModel(CXXRecordDecl *RD) override {



More information about the cfe-commits mailing list