llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Anutosh Bhat (anutosh491)

<details>
<summary>Changes</summary>

Read discussion 
https://github.com/llvm/llvm-project/pull/136404#discussion_r2059149768 and the 
following comments for context

---

Patch is 28.83 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/137458.diff


10 Files Affected:

- (modified) clang/include/clang/Interpreter/Interpreter.h (-11) 
- (modified) clang/lib/Interpreter/CMakeLists.txt (+1) 
- (modified) clang/lib/Interpreter/DeviceOffload.cpp (+3-3) 
- (modified) clang/lib/Interpreter/DeviceOffload.h (+3-3) 
- (added) clang/lib/Interpreter/IncrementalAction.cpp (+110) 
- (added) clang/lib/Interpreter/IncrementalAction.h (+68) 
- (modified) clang/lib/Interpreter/IncrementalParser.cpp (+65-3) 
- (modified) clang/lib/Interpreter/IncrementalParser.h (+29-2) 
- (modified) clang/lib/Interpreter/Interpreter.cpp (+14-184) 
- (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+1-1) 


``````````diff
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 56213f88b9e30..145ed409b7807 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -36,7 +36,6 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
-class CodeGenerator;
 class CXXRecordDecl;
 class Decl;
 class IncrementalExecutor;
@@ -109,10 +108,6 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  /// When CodeGen is created the first llvm::Module gets cached in many places
-  /// and we must keep it alive.
-  std::unique_ptr<llvm::Module> CachedInCodeGenModule;
-
   /// Compiler instance performing the incremental compilation.
   std::unique_ptr<CompilerInstance> CI;
 
@@ -179,12 +174,6 @@ class Interpreter {
   llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E);
   llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl 
*CXXRD);
 
-  CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const;
-  std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr);
-  PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
-                                      std::unique_ptr<llvm::Module> M = {},
-                                      IncrementalAction *Action = nullptr);
-
   // A cache for the compiled destructors used to for de-allocation of managed
   // clang::Values.
   llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
diff --git a/clang/lib/Interpreter/CMakeLists.txt 
b/clang/lib/Interpreter/CMakeLists.txt
index bf70cdfbee01e..79b8369371db6 100644
--- a/clang/lib/Interpreter/CMakeLists.txt
+++ b/clang/lib/Interpreter/CMakeLists.txt
@@ -22,6 +22,7 @@ endif()
 add_clang_library(clangInterpreter
   DeviceOffload.cpp
   CodeCompletion.cpp
+  IncrementalAction.cpp
   IncrementalExecutor.cpp
   IncrementalParser.cpp
   Interpreter.cpp
diff --git a/clang/lib/Interpreter/DeviceOffload.cpp 
b/clang/lib/Interpreter/DeviceOffload.cpp
index 7d0125403ea52..5415697d24daf 100644
--- a/clang/lib/Interpreter/DeviceOffload.cpp
+++ b/clang/lib/Interpreter/DeviceOffload.cpp
@@ -26,10 +26,10 @@ namespace clang {
 
 IncrementalCUDADeviceParser::IncrementalCUDADeviceParser(
     std::unique_ptr<CompilerInstance> DeviceInstance,
-    CompilerInstance &HostInstance,
+    CompilerInstance &HostInstance, IncrementalAction *DeviceAct,
     llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS,
-    llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs)
-    : IncrementalParser(*DeviceInstance, Err), PTUs(PTUs), VFS(FS),
+    llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs)
+    : IncrementalParser(*DeviceInstance, DeviceAct, Err, PTUs), VFS(FS),
       CodeGenOpts(HostInstance.getCodeGenOpts()),
       TargetOpts(DeviceInstance->getTargetOpts()) {
   if (Err)
diff --git a/clang/lib/Interpreter/DeviceOffload.h 
b/clang/lib/Interpreter/DeviceOffload.h
index 43645033c4840..e4cfd26aa4871 100644
--- a/clang/lib/Interpreter/DeviceOffload.h
+++ b/clang/lib/Interpreter/DeviceOffload.h
@@ -22,16 +22,16 @@ struct PartialTranslationUnit;
 class CompilerInstance;
 class CodeGenOptions;
 class TargetOptions;
+class IncrementalAction;
 
 class IncrementalCUDADeviceParser : public IncrementalParser {
-  const std::list<PartialTranslationUnit> &PTUs;
 
 public:
   IncrementalCUDADeviceParser(
       std::unique_ptr<CompilerInstance> DeviceInstance,
-      CompilerInstance &HostInstance,
+      CompilerInstance &HostInstance, IncrementalAction *DeviceAct,
       llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS,
-      llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs);
+      llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs);
 
   // Generate PTX for the last PTU.
   llvm::Expected<llvm::StringRef> GeneratePTX();
diff --git a/clang/lib/Interpreter/IncrementalAction.cpp 
b/clang/lib/Interpreter/IncrementalAction.cpp
new file mode 100644
index 0000000000000..683925859c645
--- /dev/null
+++ b/clang/lib/Interpreter/IncrementalAction.cpp
@@ -0,0 +1,110 @@
+//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "IncrementalAction.h"
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/CodeGen/CodeGenAction.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/FrontendTool/Utils.h"
+#include "clang/Interpreter/Interpreter.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+IncrementalAction::IncrementalAction(CompilerInstance &CI,
+                                     llvm::LLVMContext &LLVMCtx,
+                                     llvm::Error &Err, Interpreter &I,
+                                     std::unique_ptr<ASTConsumer> Consumer)
+    : WrapperFrontendAction([&]() {
+        llvm::ErrorAsOutParameter EAO(&Err);
+        std::unique_ptr<FrontendAction> Act;
+        switch (CI.getFrontendOpts().ProgramAction) {
+        default:
+          Err = llvm::createStringError(
+              std::errc::state_not_recoverable,
+              "Driver initialization failed. "
+              "Incremental mode for action %d is not supported",
+              CI.getFrontendOpts().ProgramAction);
+          return Act;
+        case frontend::ASTDump:
+        case frontend::ASTPrint:
+        case frontend::ParseSyntaxOnly:
+          Act = CreateFrontendAction(CI);
+          break;
+        case frontend::PluginAction:
+        case frontend::EmitAssembly:
+        case frontend::EmitBC:
+        case frontend::EmitObj:
+        case frontend::PrintPreprocessedInput:
+        case frontend::EmitLLVMOnly:
+          Act.reset(new EmitLLVMOnlyAction(&LLVMCtx));
+          break;
+        }
+        return Act;
+      }()),
+      Interp(I), Consumer(std::move(Consumer)) {}
+
+std::unique_ptr<ASTConsumer>
+IncrementalAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  std::unique_ptr<ASTConsumer> C =
+      WrapperFrontendAction::CreateASTConsumer(CI, InFile);
+
+  if (Consumer) {
+    std::vector<std::unique_ptr<ASTConsumer>> Cs;
+    Cs.push_back(std::move(Consumer));
+    Cs.push_back(std::move(C));
+    return std::make_unique<MultiplexConsumer>(std::move(Cs));
+  }
+
+  return std::make_unique<InProcessPrintingASTConsumer>(std::move(C), Interp);
+}
+
+void IncrementalAction::ExecuteAction() {
+  WrapperFrontendAction::ExecuteAction();
+  getCompilerInstance().getSema().CurContext = nullptr;
+}
+
+void IncrementalAction::EndSourceFile() {
+  if (IsTerminating && getWrapped())
+    WrapperFrontendAction::EndSourceFile();
+}
+
+void IncrementalAction::FinalizeAction() {
+  assert(!IsTerminating && "Already finalized!");
+  IsTerminating = true;
+  EndSourceFile();
+}
+
+InProcessPrintingASTConsumer::InProcessPrintingASTConsumer(
+    std::unique_ptr<ASTConsumer> C, Interpreter &I)
+    : MultiplexConsumer(std::move(C)), Interp(I) {}
+
+bool InProcessPrintingASTConsumer::HandleTopLevelDecl(DeclGroupRef DGR) {
+  if (DGR.isNull())
+    return true;
+
+  for (Decl *D : DGR)
+    if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(D))
+      if (TLSD && TLSD->isSemiMissing()) {
+        auto ExprOrErr =
+            Interp.ExtractValueFromExpr(cast<Expr>(TLSD->getStmt()));
+        if (llvm::Error E = ExprOrErr.takeError()) {
+          llvm::logAllUnhandledErrors(std::move(E), llvm::errs(),
+                                      "Value printing failed: ");
+          return false; // abort parsing
+        }
+        TLSD->setStmt(*ExprOrErr);
+      }
+
+  return MultiplexConsumer::HandleTopLevelDecl(DGR);
+}
+
+} // namespace clang
\ No newline at end of file
diff --git a/clang/lib/Interpreter/IncrementalAction.h 
b/clang/lib/Interpreter/IncrementalAction.h
new file mode 100644
index 0000000000000..08d090a0513fe
--- /dev/null
+++ b/clang/lib/Interpreter/IncrementalAction.h
@@ -0,0 +1,68 @@
+//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
+#define LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
+
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/MultiplexConsumer.h"
+
+namespace clang {
+
+class Interpreter;
+
+/// A custom action enabling the incremental processing functionality.
+///
+/// The usual \p FrontendAction expects one call to ExecuteAction and once it
+/// sees a call to \p EndSourceFile it deletes some of the important objects
+/// such as \p Preprocessor and \p Sema assuming no further input will come.
+///
+/// \p IncrementalAction ensures it keep its underlying action's objects alive
+/// as long as the \p IncrementalParser needs them.
+///
+class IncrementalAction : public WrapperFrontendAction {
+private:
+  bool IsTerminating = false;
+  Interpreter &Interp;
+  std::unique_ptr<ASTConsumer> Consumer;
+
+public:
+  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
+                    llvm::Error &Err, Interpreter &I,
+                    std::unique_ptr<ASTConsumer> Consumer = nullptr);
+
+  FrontendAction *getWrapped() const { return WrappedAction.get(); }
+
+  TranslationUnitKind getTranslationUnitKind() override {
+    return TU_Incremental;
+  }
+
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override;
+
+  void ExecuteAction() override;
+
+  // Do not terminate after processing the input. This allows us to keep 
various
+  // clang objects alive and to incrementally grow the current TU.
+  void EndSourceFile() override;
+
+  void FinalizeAction();
+};
+
+class InProcessPrintingASTConsumer final : public MultiplexConsumer {
+  Interpreter &Interp;
+
+public:
+  InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I);
+
+  bool HandleTopLevelDecl(DeclGroupRef DGR) override;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index 41d6304bd5f65..9691673be06dd 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -11,27 +11,36 @@
 
//===----------------------------------------------------------------------===//
 
 #include "IncrementalParser.h"
+#include "IncrementalAction.h"
 
 #include "clang/AST/DeclContextInternals.h"
+#include "clang/CodeGen/CodeGenAction.h"
+#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendAction.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
+#include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
 
 #include <sstream>
 
+#define DEBUG_TYPE "clang-repl"
+
 namespace clang {
 
 // IncrementalParser::IncrementalParser() {}
 
 IncrementalParser::IncrementalParser(CompilerInstance &Instance,
-                                     llvm::Error &Err)
-    : S(Instance.getSema()) {
+                                     IncrementalAction *Act, llvm::Error &Err,
+                                     std::list<PartialTranslationUnit> &PTUs)
+    : S(Instance.getSema()), CI(Instance), Act(Act), PTUs(PTUs) {
   llvm::ErrorAsOutParameter EAO(&Err);
   Consumer = &S.getASTConsumer();
-  P.reset(new Parser(S.getPreprocessor(), S, /*SkipBodies=*/false));
+  P = std::make_unique<Parser>(S.getPreprocessor(), S, /*SkipBodies=*/false);
   P->Initialize();
 }
 
@@ -185,4 +194,57 @@ void IncrementalParser::CleanUpPTU(TranslationUnitDecl 
*MostRecentTU) {
   }
 }
 
+PartialTranslationUnit &
+IncrementalParser::RegisterPTU(TranslationUnitDecl *TU,
+                               std::unique_ptr<llvm::Module> M /*={}*/) {
+  PTUs.emplace_back(PartialTranslationUnit());
+  PartialTranslationUnit &LastPTU = PTUs.back();
+  LastPTU.TUPart = TU;
+
+  if (!M)
+    M = GenModule();
+
+  assert((!getCodeGen() || M) && "Must have a llvm::Module at this point");
+
+  LastPTU.TheModule = std::move(M);
+  LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1
+                          << ": [TU=" << LastPTU.TUPart);
+  if (LastPTU.TheModule)
+    LLVM_DEBUG(llvm::dbgs() << ", M=" << LastPTU.TheModule.get() << " ("
+                            << LastPTU.TheModule->getName() << ")");
+  LLVM_DEBUG(llvm::dbgs() << "]\n");
+  return LastPTU;
+}
+
+std::unique_ptr<llvm::Module> IncrementalParser::GenModule() {
+  static unsigned ID = 0;
+  if (CodeGenerator *CG = getCodeGen()) {
+    // Clang's CodeGen is designed to work with a single llvm::Module. In many
+    // cases for convenience various CodeGen parts have a reference to the
+    // llvm::Module (TheModule or Module) which does not change when a new
+    // module is pushed. However, the execution engine wants to take ownership
+    // of the module which does not map well to CodeGen's design. To work this
+    // around we created an empty module to make CodeGen happy. We should make
+    // sure it always stays empty.
+    assert(((!CachedInCodeGenModule ||
+             !CI.getPreprocessorOpts().Includes.empty()) ||
+            (CachedInCodeGenModule->empty() &&
+             CachedInCodeGenModule->global_empty() &&
+             CachedInCodeGenModule->alias_empty() &&
+             CachedInCodeGenModule->ifunc_empty())) &&
+           "CodeGen wrote to a readonly module");
+    std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
+    CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
+    return M;
+  }
+  return nullptr;
+}
+
+CodeGenerator *IncrementalParser::getCodeGen() const {
+  FrontendAction *WrappedAct = Act->getWrapped();
+  if (!WrappedAct->hasIRSupport())
+    return nullptr;
+  return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
+}
+
 } // end namespace clang
diff --git a/clang/lib/Interpreter/IncrementalParser.h 
b/clang/lib/Interpreter/IncrementalParser.h
index 4fdde749a2e75..c3d7cd615d9b0 100644
--- a/clang/lib/Interpreter/IncrementalParser.h
+++ b/clang/lib/Interpreter/IncrementalParser.h
@@ -19,6 +19,10 @@
 #include <list>
 #include <memory>
 
+namespace llvm {
+class Module;
+}
+
 namespace clang {
 class ASTConsumer;
 class CodeGenerator;
@@ -26,6 +30,8 @@ class CompilerInstance;
 class Parser;
 class Sema;
 class TranslationUnitDecl;
+class IncrementalAction;
+struct PartialTranslationUnit;
 
 /// Provides support for incremental compilation. Keeps track of the state
 /// changes between the subsequent incremental input.
@@ -44,12 +50,23 @@ class IncrementalParser {
   /// Counts the number of direct user input lines that have been parsed.
   unsigned InputCount = 0;
 
-  // IncrementalParser();
+  /// The CompilerInstance used during parsing.
+  CompilerInstance &CI;
+
+  /// The FrontendAction used during incremental parsing.
+  IncrementalAction *Act = nullptr;
+
+  std::list<PartialTranslationUnit> &PTUs;
 
 public:
-  IncrementalParser(CompilerInstance &Instance, llvm::Error &Err);
+  IncrementalParser(CompilerInstance &Instance, IncrementalAction *Act,
+                    llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs);
   virtual ~IncrementalParser();
 
+  /// When CodeGen is created the first llvm::Module gets cached in many places
+  /// and we must keep it alive.
+  std::unique_ptr<llvm::Module> CachedInCodeGenModule;
+
   /// Parses incremental input by creating an in-memory file.
   ///\returns a \c PartialTranslationUnit which holds information about the
   /// \c TranslationUnitDecl.
@@ -57,6 +74,16 @@ class IncrementalParser {
 
   void CleanUpPTU(TranslationUnitDecl *MostRecentTU);
 
+  /// Access the current code generator.
+  CodeGenerator *getCodeGen() const;
+
+  /// Generate an LLVM module for the most recent parsed input.
+  std::unique_ptr<llvm::Module> GenModule();
+
+  /// Register a PTU produced by Parse.
+  PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
+                                      std::unique_ptr<llvm::Module> M = {});
+
 private:
   llvm::Expected<TranslationUnitDecl *> ParseOrWrapTopLevelDecl();
 };
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index e2950e171a77e..deb3b7655eb27 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -12,6 +12,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "DeviceOffload.h"
+#include "IncrementalAction.h"
 #include "IncrementalExecutor.h"
 #include "IncrementalParser.h"
 #include "InterpreterUtils.h"
@@ -28,7 +29,6 @@
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/CodeGen/ObjectFilePCHContainerWriter.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
@@ -248,120 +248,6 @@ IncrementalCompilerBuilder::CreateCudaHost() {
   return IncrementalCompilerBuilder::createCuda(false);
 }
 
-class InProcessPrintingASTConsumer final : public MultiplexConsumer {
-  Interpreter &Interp;
-
-public:
-  InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I)
-      : MultiplexConsumer(std::move(C)), Interp(I) {}
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-    if (DGR.isNull())
-      return true;
-
-    for (Decl *D : DGR)
-      if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(D))
-        if (TLSD && TLSD->isSemiMissing()) {
-          auto ExprOrErr =
-              Interp.ExtractValueFromExpr(cast<Expr>(TLSD->getStmt()));
-          if (llvm::Error E = ExprOrErr.takeError()) {
-            llvm::logAllUnhandledErrors(std::move(E), llvm::errs(),
-                                        "Value printing failed: ");
-            return false; // abort parsing
-          }
-          TLSD->setStmt(*ExprOrErr);
-        }
-
-    return MultiplexConsumer::HandleTopLevelDecl(DGR);
-  }
-};
-
-/// A custom action enabling the incremental processing functionality.
-///
-/// The usual \p FrontendAction expects one call to ExecuteAction and once it
-/// sees a call to \p EndSourceFile it deletes some of the important objects
-/// such as \p Preprocessor and \p Sema assuming no further input will come.
-///
-/// \p IncrementalAction ensures it keep its underlying action's objects alive
-/// as long as the \p IncrementalParser needs them.
-///
-class IncrementalAction : public WrapperFrontendAction {
-private:
-  bool IsTerminating = false;
-  Interpreter &Interp;
-  std::unique_ptr<ASTConsumer> Consumer;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-                    llvm::Error &Err, Interpreter &I,
-                    std::unique_ptr<ASTConsumer> Consumer = nullptr)
-      : WrapperFrontendAction([&]() {
-          llvm::ErrorAsOutParameter EAO(&Err);
-          std::unique_ptr<FrontendAction> Act;
-          switch (CI.getFrontendOpts().ProgramAction) {
-          default:
-            Err = llvm::createStringError(
-                std::errc::state_not_recoverable,
-                "Driver initialization failed. "
-                "Incremental mode for action %d is not supported",
-                CI.getFrontendOpts().ProgramAction);
-            return Act;
-          case frontend::ASTDump:
-          case frontend::ASTPrint:
-          case frontend::ParseSyntaxOnly:
-            Act = CreateFrontendAction(CI);
-            break;
-          case frontend::PluginAction:
-          case frontend::EmitAssembly:
-          case frontend::EmitBC:
-          case frontend::EmitObj:
-          case fr...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/137458
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to