[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-11-04 Thread Vassil Vassilev via cfe-commits


@@ -13,246 +13,40 @@
 #include "IncrementalParser.h"
 
 #include "clang/AST/DeclContextInternals.h"
-#include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/FrontendTool/Utils.h"
-#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/Timer.h"
 
 #include 
 
 namespace clang {
 
-class IncrementalASTConsumer final : public ASTConsumer {
-  Interpreter &Interp;
-  std::unique_ptr Consumer;
+// IncrementalParser::IncrementalParser() {}
 
-public:
-  IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr 
C)
-  : Interp(InterpRef), Consumer(std::move(C)) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-if (DGR.isNull())
-  return true;
-if (!Consumer)
-  return true;
-
-for (Decl *D : DGR)
-  if (auto *TSD = llvm::dyn_cast(D);
-  TSD && TSD->isSemiMissing())
-TSD->setStmt(Interp.SynthesizeExpr(cast(TSD->getStmt(;
-
-return Consumer->HandleTopLevelDecl(DGR);
-  }
-  void HandleTranslationUnit(ASTContext &Ctx) override final {
-Consumer->HandleTranslationUnit(Ctx);
-  }
-  void HandleInlineFunctionDefinition(FunctionDecl *D) override final {
-Consumer->HandleInlineFunctionDefinition(D);
-  }
-  void HandleInterestingDecl(DeclGroupRef D) override final {
-Consumer->HandleInterestingDecl(D);
-  }
-  void HandleTagDeclDefinition(TagDecl *D) override final {
-Consumer->HandleTagDeclDefinition(D);
-  }
-  void HandleTagDeclRequiredDefinition(const TagDecl *D) override final {
-Consumer->HandleTagDeclRequiredDefinition(D);
-  }
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final {
-Consumer->HandleCXXImplicitFunctionInstantiation(D);
-  }
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final {
-Consumer->HandleTopLevelDeclInObjCContainer(D);
-  }
-  void HandleImplicitImportDecl(ImportDecl *D) override final {
-Consumer->HandleImplicitImportDecl(D);
-  }
-  void CompleteTentativeDefinition(VarDecl *D) override final {
-Consumer->CompleteTentativeDefinition(D);
-  }
-  void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
-Consumer->CompleteExternalDeclaration(D);
-  }
-  void AssignInheritanceModel(CXXRecordDecl *RD) override final {
-Consumer->AssignInheritanceModel(RD);
-  }
-  void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final {
-Consumer->HandleCXXStaticMemberVarInstantiation(D);
-  }
-  void HandleVTable(CXXRecordDecl *RD) override final {
-Consumer->HandleVTable(RD);
-  }
-  ASTMutationListener *GetASTMutationListener() override final {
-return Consumer->GetASTMutationListener();
-  }
-  ASTDeserializationListener *GetASTDeserializationListener() override final {
-return Consumer->GetASTDeserializationListener();
-  }
-  void PrintStats() override final { Consumer->PrintStats(); }
-  bool shouldSkipFunctionBody(Decl *D) override final {
-return Consumer->shouldSkipFunctionBody(D);
-  }
-  static bool classof(const clang::ASTConsumer *) { return true; }
-};
-
-/// 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;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-llvm::Error &Err)
-  : WrapperFrontendAction([&]() {
-  llvm::ErrorAsOutParameter EAO(&Err);
-  std::unique_ptr 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:
-[[fallthrough]];
-  case frontend::ASTPrint:
-[[fallthrough]];
-  case frontend::ParseSyntaxOnly:
-Act = CreateFrontendAction(CI);
-break;
-  case frontend::PluginAction:
-[[fallthrough]];
-  case frontend::EmitAssembly:
-[[fallthro

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-11-04 Thread Aaron Ballman via cfe-commits


@@ -13,246 +13,40 @@
 #include "IncrementalParser.h"
 
 #include "clang/AST/DeclContextInternals.h"
-#include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/FrontendTool/Utils.h"
-#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/Timer.h"
 
 #include 
 
 namespace clang {
 
-class IncrementalASTConsumer final : public ASTConsumer {
-  Interpreter &Interp;
-  std::unique_ptr Consumer;
+// IncrementalParser::IncrementalParser() {}
 
-public:
-  IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr 
C)
-  : Interp(InterpRef), Consumer(std::move(C)) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-if (DGR.isNull())
-  return true;
-if (!Consumer)
-  return true;
-
-for (Decl *D : DGR)
-  if (auto *TSD = llvm::dyn_cast(D);
-  TSD && TSD->isSemiMissing())
-TSD->setStmt(Interp.SynthesizeExpr(cast(TSD->getStmt(;
-
-return Consumer->HandleTopLevelDecl(DGR);
-  }
-  void HandleTranslationUnit(ASTContext &Ctx) override final {
-Consumer->HandleTranslationUnit(Ctx);
-  }
-  void HandleInlineFunctionDefinition(FunctionDecl *D) override final {
-Consumer->HandleInlineFunctionDefinition(D);
-  }
-  void HandleInterestingDecl(DeclGroupRef D) override final {
-Consumer->HandleInterestingDecl(D);
-  }
-  void HandleTagDeclDefinition(TagDecl *D) override final {
-Consumer->HandleTagDeclDefinition(D);
-  }
-  void HandleTagDeclRequiredDefinition(const TagDecl *D) override final {
-Consumer->HandleTagDeclRequiredDefinition(D);
-  }
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final {
-Consumer->HandleCXXImplicitFunctionInstantiation(D);
-  }
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final {
-Consumer->HandleTopLevelDeclInObjCContainer(D);
-  }
-  void HandleImplicitImportDecl(ImportDecl *D) override final {
-Consumer->HandleImplicitImportDecl(D);
-  }
-  void CompleteTentativeDefinition(VarDecl *D) override final {
-Consumer->CompleteTentativeDefinition(D);
-  }
-  void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
-Consumer->CompleteExternalDeclaration(D);
-  }
-  void AssignInheritanceModel(CXXRecordDecl *RD) override final {
-Consumer->AssignInheritanceModel(RD);
-  }
-  void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final {
-Consumer->HandleCXXStaticMemberVarInstantiation(D);
-  }
-  void HandleVTable(CXXRecordDecl *RD) override final {
-Consumer->HandleVTable(RD);
-  }
-  ASTMutationListener *GetASTMutationListener() override final {
-return Consumer->GetASTMutationListener();
-  }
-  ASTDeserializationListener *GetASTDeserializationListener() override final {
-return Consumer->GetASTDeserializationListener();
-  }
-  void PrintStats() override final { Consumer->PrintStats(); }
-  bool shouldSkipFunctionBody(Decl *D) override final {
-return Consumer->shouldSkipFunctionBody(D);
-  }
-  static bool classof(const clang::ASTConsumer *) { return true; }
-};
-
-/// 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;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-llvm::Error &Err)
-  : WrapperFrontendAction([&]() {
-  llvm::ErrorAsOutParameter EAO(&Err);
-  std::unique_ptr 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:
-[[fallthrough]];
-  case frontend::ASTPrint:
-[[fallthrough]];
-  case frontend::ParseSyntaxOnly:
-Act = CreateFrontendAction(CI);
-break;
-  case frontend::PluginAction:
-[[fallthrough]];
-  case frontend::EmitAssembly:
-[[fallthro

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-10-23 Thread Vassil Vassilev via cfe-commits


@@ -13,246 +13,40 @@
 #include "IncrementalParser.h"
 
 #include "clang/AST/DeclContextInternals.h"
-#include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/FrontendTool/Utils.h"
-#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/Timer.h"
 
 #include 
 
 namespace clang {
 
-class IncrementalASTConsumer final : public ASTConsumer {
-  Interpreter &Interp;
-  std::unique_ptr Consumer;
+// IncrementalParser::IncrementalParser() {}
 
-public:
-  IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr 
C)
-  : Interp(InterpRef), Consumer(std::move(C)) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-if (DGR.isNull())
-  return true;
-if (!Consumer)
-  return true;
-
-for (Decl *D : DGR)
-  if (auto *TSD = llvm::dyn_cast(D);
-  TSD && TSD->isSemiMissing())
-TSD->setStmt(Interp.SynthesizeExpr(cast(TSD->getStmt(;
-
-return Consumer->HandleTopLevelDecl(DGR);
-  }
-  void HandleTranslationUnit(ASTContext &Ctx) override final {
-Consumer->HandleTranslationUnit(Ctx);
-  }
-  void HandleInlineFunctionDefinition(FunctionDecl *D) override final {
-Consumer->HandleInlineFunctionDefinition(D);
-  }
-  void HandleInterestingDecl(DeclGroupRef D) override final {
-Consumer->HandleInterestingDecl(D);
-  }
-  void HandleTagDeclDefinition(TagDecl *D) override final {
-Consumer->HandleTagDeclDefinition(D);
-  }
-  void HandleTagDeclRequiredDefinition(const TagDecl *D) override final {
-Consumer->HandleTagDeclRequiredDefinition(D);
-  }
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final {
-Consumer->HandleCXXImplicitFunctionInstantiation(D);
-  }
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final {
-Consumer->HandleTopLevelDeclInObjCContainer(D);
-  }
-  void HandleImplicitImportDecl(ImportDecl *D) override final {
-Consumer->HandleImplicitImportDecl(D);
-  }
-  void CompleteTentativeDefinition(VarDecl *D) override final {
-Consumer->CompleteTentativeDefinition(D);
-  }
-  void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
-Consumer->CompleteExternalDeclaration(D);
-  }
-  void AssignInheritanceModel(CXXRecordDecl *RD) override final {
-Consumer->AssignInheritanceModel(RD);
-  }
-  void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final {
-Consumer->HandleCXXStaticMemberVarInstantiation(D);
-  }
-  void HandleVTable(CXXRecordDecl *RD) override final {
-Consumer->HandleVTable(RD);
-  }
-  ASTMutationListener *GetASTMutationListener() override final {
-return Consumer->GetASTMutationListener();
-  }
-  ASTDeserializationListener *GetASTDeserializationListener() override final {
-return Consumer->GetASTDeserializationListener();
-  }
-  void PrintStats() override final { Consumer->PrintStats(); }
-  bool shouldSkipFunctionBody(Decl *D) override final {
-return Consumer->shouldSkipFunctionBody(D);
-  }
-  static bool classof(const clang::ASTConsumer *) { return true; }
-};
-
-/// 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;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-llvm::Error &Err)
-  : WrapperFrontendAction([&]() {
-  llvm::ErrorAsOutParameter EAO(&Err);
-  std::unique_ptr 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:
-[[fallthrough]];
-  case frontend::ASTPrint:
-[[fallthrough]];
-  case frontend::ParseSyntaxOnly:
-Act = CreateFrontendAction(CI);
-break;
-  case frontend::PluginAction:
-[[fallthrough]];
-  case frontend::EmitAssembly:
-[[fallthro

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-10-22 Thread Aaron Ballman via cfe-commits


@@ -13,246 +13,40 @@
 #include "IncrementalParser.h"
 
 #include "clang/AST/DeclContextInternals.h"
-#include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/FrontendTool/Utils.h"
-#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/Timer.h"
 
 #include 
 
 namespace clang {
 
-class IncrementalASTConsumer final : public ASTConsumer {
-  Interpreter &Interp;
-  std::unique_ptr Consumer;
+// IncrementalParser::IncrementalParser() {}
 
-public:
-  IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr 
C)
-  : Interp(InterpRef), Consumer(std::move(C)) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-if (DGR.isNull())
-  return true;
-if (!Consumer)
-  return true;
-
-for (Decl *D : DGR)
-  if (auto *TSD = llvm::dyn_cast(D);
-  TSD && TSD->isSemiMissing())
-TSD->setStmt(Interp.SynthesizeExpr(cast(TSD->getStmt(;
-
-return Consumer->HandleTopLevelDecl(DGR);
-  }
-  void HandleTranslationUnit(ASTContext &Ctx) override final {
-Consumer->HandleTranslationUnit(Ctx);
-  }
-  void HandleInlineFunctionDefinition(FunctionDecl *D) override final {
-Consumer->HandleInlineFunctionDefinition(D);
-  }
-  void HandleInterestingDecl(DeclGroupRef D) override final {
-Consumer->HandleInterestingDecl(D);
-  }
-  void HandleTagDeclDefinition(TagDecl *D) override final {
-Consumer->HandleTagDeclDefinition(D);
-  }
-  void HandleTagDeclRequiredDefinition(const TagDecl *D) override final {
-Consumer->HandleTagDeclRequiredDefinition(D);
-  }
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final {
-Consumer->HandleCXXImplicitFunctionInstantiation(D);
-  }
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final {
-Consumer->HandleTopLevelDeclInObjCContainer(D);
-  }
-  void HandleImplicitImportDecl(ImportDecl *D) override final {
-Consumer->HandleImplicitImportDecl(D);
-  }
-  void CompleteTentativeDefinition(VarDecl *D) override final {
-Consumer->CompleteTentativeDefinition(D);
-  }
-  void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
-Consumer->CompleteExternalDeclaration(D);
-  }
-  void AssignInheritanceModel(CXXRecordDecl *RD) override final {
-Consumer->AssignInheritanceModel(RD);
-  }
-  void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final {
-Consumer->HandleCXXStaticMemberVarInstantiation(D);
-  }
-  void HandleVTable(CXXRecordDecl *RD) override final {
-Consumer->HandleVTable(RD);
-  }
-  ASTMutationListener *GetASTMutationListener() override final {
-return Consumer->GetASTMutationListener();
-  }
-  ASTDeserializationListener *GetASTDeserializationListener() override final {
-return Consumer->GetASTDeserializationListener();
-  }
-  void PrintStats() override final { Consumer->PrintStats(); }
-  bool shouldSkipFunctionBody(Decl *D) override final {
-return Consumer->shouldSkipFunctionBody(D);
-  }
-  static bool classof(const clang::ASTConsumer *) { return true; }
-};
-
-/// 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;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-llvm::Error &Err)
-  : WrapperFrontendAction([&]() {
-  llvm::ErrorAsOutParameter EAO(&Err);
-  std::unique_ptr 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:
-[[fallthrough]];
-  case frontend::ASTPrint:
-[[fallthrough]];
-  case frontend::ParseSyntaxOnly:
-Act = CreateFrontendAction(CI);
-break;
-  case frontend::PluginAction:
-[[fallthrough]];
-  case frontend::EmitAssembly:
-[[fallthro

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-10-18 Thread Vassil Vassilev via cfe-commits


@@ -13,246 +13,40 @@
 #include "IncrementalParser.h"
 
 #include "clang/AST/DeclContextInternals.h"
-#include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/FrontendTool/Utils.h"
-#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/Timer.h"
 
 #include 
 
 namespace clang {
 
-class IncrementalASTConsumer final : public ASTConsumer {
-  Interpreter &Interp;
-  std::unique_ptr Consumer;
+// IncrementalParser::IncrementalParser() {}
 
-public:
-  IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr 
C)
-  : Interp(InterpRef), Consumer(std::move(C)) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-if (DGR.isNull())
-  return true;
-if (!Consumer)
-  return true;
-
-for (Decl *D : DGR)
-  if (auto *TSD = llvm::dyn_cast(D);
-  TSD && TSD->isSemiMissing())
-TSD->setStmt(Interp.SynthesizeExpr(cast(TSD->getStmt(;
-
-return Consumer->HandleTopLevelDecl(DGR);
-  }
-  void HandleTranslationUnit(ASTContext &Ctx) override final {
-Consumer->HandleTranslationUnit(Ctx);
-  }
-  void HandleInlineFunctionDefinition(FunctionDecl *D) override final {
-Consumer->HandleInlineFunctionDefinition(D);
-  }
-  void HandleInterestingDecl(DeclGroupRef D) override final {
-Consumer->HandleInterestingDecl(D);
-  }
-  void HandleTagDeclDefinition(TagDecl *D) override final {
-Consumer->HandleTagDeclDefinition(D);
-  }
-  void HandleTagDeclRequiredDefinition(const TagDecl *D) override final {
-Consumer->HandleTagDeclRequiredDefinition(D);
-  }
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final {
-Consumer->HandleCXXImplicitFunctionInstantiation(D);
-  }
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final {
-Consumer->HandleTopLevelDeclInObjCContainer(D);
-  }
-  void HandleImplicitImportDecl(ImportDecl *D) override final {
-Consumer->HandleImplicitImportDecl(D);
-  }
-  void CompleteTentativeDefinition(VarDecl *D) override final {
-Consumer->CompleteTentativeDefinition(D);
-  }
-  void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
-Consumer->CompleteExternalDeclaration(D);
-  }
-  void AssignInheritanceModel(CXXRecordDecl *RD) override final {
-Consumer->AssignInheritanceModel(RD);
-  }
-  void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final {
-Consumer->HandleCXXStaticMemberVarInstantiation(D);
-  }
-  void HandleVTable(CXXRecordDecl *RD) override final {
-Consumer->HandleVTable(RD);
-  }
-  ASTMutationListener *GetASTMutationListener() override final {
-return Consumer->GetASTMutationListener();
-  }
-  ASTDeserializationListener *GetASTDeserializationListener() override final {
-return Consumer->GetASTDeserializationListener();
-  }
-  void PrintStats() override final { Consumer->PrintStats(); }
-  bool shouldSkipFunctionBody(Decl *D) override final {
-return Consumer->shouldSkipFunctionBody(D);
-  }
-  static bool classof(const clang::ASTConsumer *) { return true; }
-};
-
-/// 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;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-llvm::Error &Err)
-  : WrapperFrontendAction([&]() {
-  llvm::ErrorAsOutParameter EAO(&Err);
-  std::unique_ptr 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:
-[[fallthrough]];
-  case frontend::ASTPrint:
-[[fallthrough]];
-  case frontend::ParseSyntaxOnly:
-Act = CreateFrontendAction(CI);
-break;
-  case frontend::PluginAction:
-[[fallthrough]];
-  case frontend::EmitAssembly:
-[[fallthro

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-10-18 Thread Aaron Ballman via cfe-commits


@@ -13,246 +13,40 @@
 #include "IncrementalParser.h"
 
 #include "clang/AST/DeclContextInternals.h"
-#include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/FrontendTool/Utils.h"
-#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/Timer.h"
 
 #include 
 
 namespace clang {
 
-class IncrementalASTConsumer final : public ASTConsumer {
-  Interpreter &Interp;
-  std::unique_ptr Consumer;
+// IncrementalParser::IncrementalParser() {}
 
-public:
-  IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr 
C)
-  : Interp(InterpRef), Consumer(std::move(C)) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
-if (DGR.isNull())
-  return true;
-if (!Consumer)
-  return true;
-
-for (Decl *D : DGR)
-  if (auto *TSD = llvm::dyn_cast(D);
-  TSD && TSD->isSemiMissing())
-TSD->setStmt(Interp.SynthesizeExpr(cast(TSD->getStmt(;
-
-return Consumer->HandleTopLevelDecl(DGR);
-  }
-  void HandleTranslationUnit(ASTContext &Ctx) override final {
-Consumer->HandleTranslationUnit(Ctx);
-  }
-  void HandleInlineFunctionDefinition(FunctionDecl *D) override final {
-Consumer->HandleInlineFunctionDefinition(D);
-  }
-  void HandleInterestingDecl(DeclGroupRef D) override final {
-Consumer->HandleInterestingDecl(D);
-  }
-  void HandleTagDeclDefinition(TagDecl *D) override final {
-Consumer->HandleTagDeclDefinition(D);
-  }
-  void HandleTagDeclRequiredDefinition(const TagDecl *D) override final {
-Consumer->HandleTagDeclRequiredDefinition(D);
-  }
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final {
-Consumer->HandleCXXImplicitFunctionInstantiation(D);
-  }
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final {
-Consumer->HandleTopLevelDeclInObjCContainer(D);
-  }
-  void HandleImplicitImportDecl(ImportDecl *D) override final {
-Consumer->HandleImplicitImportDecl(D);
-  }
-  void CompleteTentativeDefinition(VarDecl *D) override final {
-Consumer->CompleteTentativeDefinition(D);
-  }
-  void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
-Consumer->CompleteExternalDeclaration(D);
-  }
-  void AssignInheritanceModel(CXXRecordDecl *RD) override final {
-Consumer->AssignInheritanceModel(RD);
-  }
-  void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final {
-Consumer->HandleCXXStaticMemberVarInstantiation(D);
-  }
-  void HandleVTable(CXXRecordDecl *RD) override final {
-Consumer->HandleVTable(RD);
-  }
-  ASTMutationListener *GetASTMutationListener() override final {
-return Consumer->GetASTMutationListener();
-  }
-  ASTDeserializationListener *GetASTDeserializationListener() override final {
-return Consumer->GetASTDeserializationListener();
-  }
-  void PrintStats() override final { Consumer->PrintStats(); }
-  bool shouldSkipFunctionBody(Decl *D) override final {
-return Consumer->shouldSkipFunctionBody(D);
-  }
-  static bool classof(const clang::ASTConsumer *) { return true; }
-};
-
-/// 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;
-
-public:
-  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
-llvm::Error &Err)
-  : WrapperFrontendAction([&]() {
-  llvm::ErrorAsOutParameter EAO(&Err);
-  std::unique_ptr 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:
-[[fallthrough]];
-  case frontend::ASTPrint:
-[[fallthrough]];
-  case frontend::ParseSyntaxOnly:
-Act = CreateFrontendAction(CI);
-break;
-  case frontend::PluginAction:
-[[fallthrough]];
-  case frontend::EmitAssembly:
-[[fallthro

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-23 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev closed 
https://github.com/llvm/llvm-project/pull/107737
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-23 Thread Vassil Vassilev via cfe-commits

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

>From d2096a6445b803a74bd8cb56653f4ca1791d1d9f Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH 1/5] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-23 Thread Vassil Vassilev via cfe-commits

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

>From 2aa7527b52656d064c39aec94c9f1001ed10f7d8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH 1/5] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-23 Thread Vassil Vassilev via cfe-commits


@@ -39,11 +44,13 @@ class IncrementalCUDADeviceParser : public 
IncrementalParser {
   ~IncrementalCUDADeviceParser();
 
 protected:
-  IncrementalParser &HostParser;
+  std::unique_ptr DeviceCI;
   int SMVersion;
   llvm::SmallString<1024> PTXCode;
   llvm::SmallVector FatbinContent;
   llvm::IntrusiveRefCntPtr VFS;
+  CodeGenOptions &CodeGenOpts; // intentionally a reference.

vgvassilev wrote:

I think that's important as we are forcibly updating codegen options for the 
incremental use case.

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Vassil Vassilev via cfe-commits


@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);

vgvassilev wrote:

Surprisingly we can’t do this unfortunately https://godbolt.org/z/1e5oKjdhh

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/107737
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits


@@ -39,11 +44,13 @@ class IncrementalCUDADeviceParser : public 
IncrementalParser {
   ~IncrementalCUDADeviceParser();
 
 protected:
-  IncrementalParser &HostParser;
+  std::unique_ptr DeviceCI;
   int SMVersion;
   llvm::SmallString<1024> PTXCode;
   llvm::SmallVector FatbinContent;
   llvm::IntrusiveRefCntPtr VFS;
+  CodeGenOptions &CodeGenOpts; // intentionally a reference.

AaronBallman wrote:

```suggestion
  CodeGenOptions &CodeGenOpts; // Intentionally a reference.
```
Not certain the comment adds much -- we usually don't add reference members 
accidentally.

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits


@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);

AaronBallman wrote:

This feels unnecessary because you should be able to do `MultiplexConsumer 
M({std::move(ptr)});` right?

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits


@@ -241,28 +244,180 @@ IncrementalCompilerBuilder::CreateCudaHost() {
   return IncrementalCompilerBuilder::createCuda(false);
 }
 
-Interpreter::Interpreter(std::unique_ptr CI,
+class InProcessPrintingASTConsumer final : public MultiplexConsumer {
+  Interpreter &Interp;
+
+public:
+  InProcessPrintingASTConsumer(std::unique_ptr 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(D))
+if (TLSD && TLSD->isSemiMissing()) {
+  auto ExprOrErr =
+  Interp.ExtractValueFromExpr(cast(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 Consumer;
+
+public:
+  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
+llvm::Error &Err, Interpreter &I,
+std::unique_ptr Consumer = nullptr)
+  : WrapperFrontendAction([&]() {
+  llvm::ErrorAsOutParameter EAO(&Err);
+  std::unique_ptr 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:
+[[fallthrough]];
+  case frontend::ASTPrint:
+[[fallthrough]];

AaronBallman wrote:

```suggestion
  case frontend::ASTDump:
  case frontend::ASTPrint:
```

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits


@@ -241,28 +244,180 @@ IncrementalCompilerBuilder::CreateCudaHost() {
   return IncrementalCompilerBuilder::createCuda(false);
 }
 
-Interpreter::Interpreter(std::unique_ptr CI,
+class InProcessPrintingASTConsumer final : public MultiplexConsumer {
+  Interpreter &Interp;
+
+public:
+  InProcessPrintingASTConsumer(std::unique_ptr 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(D))
+if (TLSD && TLSD->isSemiMissing()) {
+  auto ExprOrErr =
+  Interp.ExtractValueFromExpr(cast(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 Consumer;
+
+public:
+  IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
+llvm::Error &Err, Interpreter &I,
+std::unique_ptr Consumer = nullptr)
+  : WrapperFrontendAction([&]() {
+  llvm::ErrorAsOutParameter EAO(&Err);
+  std::unique_ptr 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:
+[[fallthrough]];
+  case frontend::ASTPrint:
+[[fallthrough]];
+  case frontend::ParseSyntaxOnly:
+Act = CreateFrontendAction(CI);
+break;
+  case frontend::PluginAction:
+[[fallthrough]];
+  case frontend::EmitAssembly:
+[[fallthrough]];
+  case frontend::EmitBC:
+[[fallthrough]];
+  case frontend::EmitObj:
+[[fallthrough]];
+  case frontend::PrintPreprocessedInput:
+[[fallthrough]];

AaronBallman wrote:

```suggestion
  case frontend::PluginAction:
  case frontend::EmitAssembly:
  case frontend::EmitBC:
  case frontend::EmitObj:
  case frontend::PrintPreprocessedInput:
```
You only need the `fallthrough` attribute when the cases are not immediately 
adjacent to one another (basically, one of the cases has to do something, 
otherwise fallthrough is very much expected).

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

In general, I like the direction this is heading! I found a few nits, but 
nothing significant jumped out at me.

Approving because I'm going to be out the next few weeks and I didn't want you 
to feel held up on my sign-off.

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-20 Thread Aaron Ballman via cfe-commits


@@ -77,42 +78,46 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece

AaronBallman wrote:

```suggestion
  /// List containing information about every incrementally parsed piece
```

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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-10 Thread Vassil Vassilev via cfe-commits

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

>From 2aa7527b52656d064c39aec94c9f1001ed10f7d8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH 1/4] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-10 Thread Vassil Vassilev via cfe-commits

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

>From 2aa7527b52656d064c39aec94c9f1001ed10f7d8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH 1/3] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-10 Thread Jun Zhang via cfe-commits


@@ -0,0 +1,400 @@
+//===--- InterpreterValuePrinter.cpp - Value printing utils -*- 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
+//
+//===--===//
+//
+// This file implements routines for in-process value printing in clang-repl.
+//
+//===--===//
+
+#include "IncrementalParser.h"
+#include "InterpreterUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/Value.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include 
+#include 
+
+#include 
+
+namespace clang {
+
+llvm::Expected
+Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
+  assert(CXXRD && "Cannot compile a destructor for a nullptr");
+  if (auto Dtor = Dtors.find(CXXRD); Dtor != Dtors.end())
+return Dtor->getSecond();
+
+  if (CXXRD->hasIrrelevantDestructor())
+return llvm::orc::ExecutorAddr{};
+
+  CXXDestructorDecl *DtorRD =
+  getCompilerInstance()->getSema().LookupDestructor(CXXRD);
+
+  llvm::StringRef Name =
+  getCodeGen()->GetMangledName(GlobalDecl(DtorRD, Dtor_Base));
+  auto AddrOrErr = getSymbolAddress(Name);
+  if (!AddrOrErr)
+return AddrOrErr.takeError();
+
+  Dtors[CXXRD] = *AddrOrErr;
+  return AddrOrErr;
+}
+
+enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
+
+class InterfaceKindVisitor
+: public TypeVisitor {
+
+  Sema &S;
+  Expr *E;
+  llvm::SmallVectorImpl &Args;
+
+public:
+  InterfaceKindVisitor(Sema &S, Expr *E, llvm::SmallVectorImpl &Args)
+  : S(S), E(E), Args(Args) {}
+
+  InterfaceKind computeInterfaceKind(QualType Ty) {
+return Visit(Ty.getTypePtr());
+  }
+
+  InterfaceKind VisitRecordType(const RecordType *Ty) {
+return InterfaceKind::WithAlloc;
+  }
+
+  InterfaceKind VisitMemberPointerType(const MemberPointerType *Ty) {
+return InterfaceKind::WithAlloc;
+  }
+
+  InterfaceKind VisitConstantArrayType(const ConstantArrayType *Ty) {
+return InterfaceKind::CopyArray;
+  }
+
+  InterfaceKind VisitFunctionProtoType(const FunctionProtoType *Ty) {
+HandlePtrType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitPointerType(const PointerType *Ty) {
+HandlePtrType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitReferenceType(const ReferenceType *Ty) {
+ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, 
E);
+assert(!AddrOfE.isInvalid() && "Can not create unary expression");
+Args.push_back(AddrOfE.get());
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitBuiltinType(const BuiltinType *Ty) {
+if (Ty->isNullPtrType())
+  Args.push_back(E);
+else if (Ty->isFloatingType())
+  Args.push_back(E);
+else if (Ty->isIntegralOrEnumerationType())
+  HandleIntegralOrEnumType(Ty);
+else if (Ty->isVoidType()) {
+  // Do we need to still run `E`?
+}
+
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitEnumType(const EnumType *Ty) {
+HandleIntegralOrEnumType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+private:
+  // Force cast these types to the uint that fits the register size. That way 
we
+  // reduce the number of overloads of `__clang_Interpreter_SetValueNoAlloc`.
+  void HandleIntegralOrEnumType(const Type *Ty) {
+ASTContext &Ctx = S.getASTContext();
+uint64_t PtrBits = Ctx.getTypeSize(Ctx.VoidPtrTy);
+QualType UIntTy = Ctx.getBitIntType(/*Unsigned=*/true, PtrBits);
+TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(UIntTy);
+ExprResult CastedExpr =
+S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
+assert(!CastedExpr.isInvalid() && "Cannot create cstyle cast expr");
+Args.push_back(CastedExpr.get());
+  }
+
+  void HandlePtrType(const Type *Ty) {
+ASTContext &Ctx = S.getASTContext();
+TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.VoidPtrTy);
+ExprResult CastedExpr =
+S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
+assert(!CastedExpr.isInvalid() && "Can not create cstyle cast expression");
+Args.push_back(CastedExpr.get());
+  }
+};
+
+// This synthesizes a call expression to a speciall
+// function that is responsible for generating the Value.
+// In general, we transform:
+//   clang-repl> x
+// To:
+//   // 1. If x is a built-in type like int, float.
+//   __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, 
x);
+//   // 2. If x is a struct, and a lvalue.
+/

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-09 Thread Vassil Vassilev via cfe-commits


@@ -0,0 +1,400 @@
+//===--- InterpreterValuePrinter.cpp - Value printing utils -*- 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
+//
+//===--===//
+//
+// This file implements routines for in-process value printing in clang-repl.
+//
+//===--===//
+
+#include "IncrementalParser.h"
+#include "InterpreterUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/Value.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include 
+#include 
+
+#include 
+
+namespace clang {
+
+llvm::Expected
+Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
+  assert(CXXRD && "Cannot compile a destructor for a nullptr");
+  if (auto Dtor = Dtors.find(CXXRD); Dtor != Dtors.end())
+return Dtor->getSecond();
+
+  if (CXXRD->hasIrrelevantDestructor())
+return llvm::orc::ExecutorAddr{};
+
+  CXXDestructorDecl *DtorRD =
+  getCompilerInstance()->getSema().LookupDestructor(CXXRD);
+
+  llvm::StringRef Name =
+  getCodeGen()->GetMangledName(GlobalDecl(DtorRD, Dtor_Base));
+  auto AddrOrErr = getSymbolAddress(Name);
+  if (!AddrOrErr)
+return AddrOrErr.takeError();
+
+  Dtors[CXXRD] = *AddrOrErr;
+  return AddrOrErr;
+}
+
+enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
+
+class InterfaceKindVisitor
+: public TypeVisitor {
+
+  Sema &S;
+  Expr *E;
+  llvm::SmallVectorImpl &Args;
+
+public:
+  InterfaceKindVisitor(Sema &S, Expr *E, llvm::SmallVectorImpl &Args)
+  : S(S), E(E), Args(Args) {}
+
+  InterfaceKind computeInterfaceKind(QualType Ty) {
+return Visit(Ty.getTypePtr());
+  }
+
+  InterfaceKind VisitRecordType(const RecordType *Ty) {
+return InterfaceKind::WithAlloc;
+  }
+
+  InterfaceKind VisitMemberPointerType(const MemberPointerType *Ty) {
+return InterfaceKind::WithAlloc;
+  }
+
+  InterfaceKind VisitConstantArrayType(const ConstantArrayType *Ty) {
+return InterfaceKind::CopyArray;
+  }
+
+  InterfaceKind VisitFunctionProtoType(const FunctionProtoType *Ty) {
+HandlePtrType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitPointerType(const PointerType *Ty) {
+HandlePtrType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitReferenceType(const ReferenceType *Ty) {
+ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, 
E);
+assert(!AddrOfE.isInvalid() && "Can not create unary expression");
+Args.push_back(AddrOfE.get());
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitBuiltinType(const BuiltinType *Ty) {
+if (Ty->isNullPtrType())
+  Args.push_back(E);
+else if (Ty->isFloatingType())
+  Args.push_back(E);
+else if (Ty->isIntegralOrEnumerationType())
+  HandleIntegralOrEnumType(Ty);
+else if (Ty->isVoidType()) {
+  // Do we need to still run `E`?
+}
+
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitEnumType(const EnumType *Ty) {
+HandleIntegralOrEnumType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+private:
+  // Force cast these types to the uint that fits the register size. That way 
we
+  // reduce the number of overloads of `__clang_Interpreter_SetValueNoAlloc`.
+  void HandleIntegralOrEnumType(const Type *Ty) {
+ASTContext &Ctx = S.getASTContext();
+uint64_t PtrBits = Ctx.getTypeSize(Ctx.VoidPtrTy);
+QualType UIntTy = Ctx.getBitIntType(/*Unsigned=*/true, PtrBits);
+TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(UIntTy);
+ExprResult CastedExpr =
+S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
+assert(!CastedExpr.isInvalid() && "Cannot create cstyle cast expr");
+Args.push_back(CastedExpr.get());
+  }
+
+  void HandlePtrType(const Type *Ty) {
+ASTContext &Ctx = S.getASTContext();
+TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.VoidPtrTy);
+ExprResult CastedExpr =
+S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
+assert(!CastedExpr.isInvalid() && "Can not create cstyle cast expression");
+Args.push_back(CastedExpr.get());
+  }
+};
+
+// This synthesizes a call expression to a speciall
+// function that is responsible for generating the Value.
+// In general, we transform:
+//   clang-repl> x
+// To:
+//   // 1. If x is a built-in type like int, float.
+//   __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, 
x);
+//   // 2. If x is a struct, and a lvalue.
+/

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-09 Thread Jun Zhang via cfe-commits


@@ -0,0 +1,400 @@
+//===--- InterpreterValuePrinter.cpp - Value printing utils -*- 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
+//
+//===--===//
+//
+// This file implements routines for in-process value printing in clang-repl.
+//
+//===--===//
+
+#include "IncrementalParser.h"
+#include "InterpreterUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/Value.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include 
+#include 
+
+#include 
+
+namespace clang {
+
+llvm::Expected
+Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
+  assert(CXXRD && "Cannot compile a destructor for a nullptr");
+  if (auto Dtor = Dtors.find(CXXRD); Dtor != Dtors.end())
+return Dtor->getSecond();
+
+  if (CXXRD->hasIrrelevantDestructor())
+return llvm::orc::ExecutorAddr{};
+
+  CXXDestructorDecl *DtorRD =
+  getCompilerInstance()->getSema().LookupDestructor(CXXRD);
+
+  llvm::StringRef Name =
+  getCodeGen()->GetMangledName(GlobalDecl(DtorRD, Dtor_Base));
+  auto AddrOrErr = getSymbolAddress(Name);
+  if (!AddrOrErr)
+return AddrOrErr.takeError();
+
+  Dtors[CXXRD] = *AddrOrErr;
+  return AddrOrErr;
+}
+
+enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
+
+class InterfaceKindVisitor
+: public TypeVisitor {
+
+  Sema &S;
+  Expr *E;
+  llvm::SmallVectorImpl &Args;
+
+public:
+  InterfaceKindVisitor(Sema &S, Expr *E, llvm::SmallVectorImpl &Args)
+  : S(S), E(E), Args(Args) {}
+
+  InterfaceKind computeInterfaceKind(QualType Ty) {
+return Visit(Ty.getTypePtr());
+  }
+
+  InterfaceKind VisitRecordType(const RecordType *Ty) {
+return InterfaceKind::WithAlloc;
+  }
+
+  InterfaceKind VisitMemberPointerType(const MemberPointerType *Ty) {
+return InterfaceKind::WithAlloc;
+  }
+
+  InterfaceKind VisitConstantArrayType(const ConstantArrayType *Ty) {
+return InterfaceKind::CopyArray;
+  }
+
+  InterfaceKind VisitFunctionProtoType(const FunctionProtoType *Ty) {
+HandlePtrType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitPointerType(const PointerType *Ty) {
+HandlePtrType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitReferenceType(const ReferenceType *Ty) {
+ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, 
E);
+assert(!AddrOfE.isInvalid() && "Can not create unary expression");
+Args.push_back(AddrOfE.get());
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitBuiltinType(const BuiltinType *Ty) {
+if (Ty->isNullPtrType())
+  Args.push_back(E);
+else if (Ty->isFloatingType())
+  Args.push_back(E);
+else if (Ty->isIntegralOrEnumerationType())
+  HandleIntegralOrEnumType(Ty);
+else if (Ty->isVoidType()) {
+  // Do we need to still run `E`?
+}
+
+return InterfaceKind::NoAlloc;
+  }
+
+  InterfaceKind VisitEnumType(const EnumType *Ty) {
+HandleIntegralOrEnumType(Ty);
+return InterfaceKind::NoAlloc;
+  }
+
+private:
+  // Force cast these types to the uint that fits the register size. That way 
we
+  // reduce the number of overloads of `__clang_Interpreter_SetValueNoAlloc`.
+  void HandleIntegralOrEnumType(const Type *Ty) {
+ASTContext &Ctx = S.getASTContext();
+uint64_t PtrBits = Ctx.getTypeSize(Ctx.VoidPtrTy);
+QualType UIntTy = Ctx.getBitIntType(/*Unsigned=*/true, PtrBits);
+TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(UIntTy);
+ExprResult CastedExpr =
+S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
+assert(!CastedExpr.isInvalid() && "Cannot create cstyle cast expr");
+Args.push_back(CastedExpr.get());
+  }
+
+  void HandlePtrType(const Type *Ty) {
+ASTContext &Ctx = S.getASTContext();
+TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.VoidPtrTy);
+ExprResult CastedExpr =
+S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
+assert(!CastedExpr.isInvalid() && "Can not create cstyle cast expression");
+Args.push_back(CastedExpr.get());
+  }
+};
+
+// This synthesizes a call expression to a speciall
+// function that is responsible for generating the Value.
+// In general, we transform:
+//   clang-repl> x
+// To:
+//   // 1. If x is a built-in type like int, float.
+//   __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, 
x);
+//   // 2. If x is a struct, and a lvalue.
+/

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-09 Thread Vassil Vassilev via cfe-commits

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

>From 2aa7527b52656d064c39aec94c9f1001ed10f7d8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH 1/2] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-09 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff b4feb26606de84ff53d9b65a3b79c00a2b4d7c22 
9dab439803727470ce07e92a3dc5c46d9bb056b2 --extensions cpp,h -- 
clang/lib/Interpreter/InterpreterValuePrinter.cpp 
clang/include/clang/Frontend/MultiplexConsumer.h 
clang/include/clang/Interpreter/Interpreter.h 
clang/lib/Frontend/MultiplexConsumer.cpp 
clang/lib/Interpreter/DeviceOffload.cpp clang/lib/Interpreter/DeviceOffload.h 
clang/lib/Interpreter/IncrementalExecutor.cpp 
clang/lib/Interpreter/IncrementalParser.cpp 
clang/lib/Interpreter/IncrementalParser.h clang/lib/Interpreter/Interpreter.cpp 
clang/unittests/Interpreter/CodeCompletionTest.cpp 
clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 9758141715..55e60d28a1 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -175,7 +175,7 @@ private:
 
   CodeGenerator *getCodeGen() const;
   std::unique_ptr GenModule();
-  PartialTranslationUnit & RegisterPTU(TranslationUnitDecl *TU);
+  PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU);
 
   // A cache for the compiled destructors used to for de-allocation of managed
   // clang::Values.
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index e00cab0d20..808fc9b952 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -542,7 +542,7 @@ size_t Interpreter::getEffectivePTUSize() const {
   return PTUs.size() - InitPTUSize;
 }
 
-PartialTranslationUnit & Interpreter::RegisterPTU(TranslationUnitDecl *TU) {
+PartialTranslationUnit &Interpreter::RegisterPTU(TranslationUnitDecl *TU) {
   PTUs.emplace_back(PartialTranslationUnit());
   PartialTranslationUnit &LastPTU = PTUs.back();
   LastPTU.TUPart = TU;

``




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


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-09 Thread Vassil Vassilev via cfe-commits

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

>From 2aa7527b52656d064c39aec94c9f1001ed10f7d8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH 1/2] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-08 Thread Vassil Vassilev via cfe-commits

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

>From 2aa7527b52656d064c39aec94c9f1001ed10f7d8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm/llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 648 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 400 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 707 insertions(+), 795 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add a c

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-08 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Vassil Vassilev (vgvassilev)


Changes

This patch improves the design of the IncrementalParser and Interpreter 
classes. Now the incremental parser is only responsible for building the 
partial translation unit declaration and the AST, while the Interpreter fills 
in the lower level llvm::Module and other JIT-related infrastructure. Finally 
the Interpreter class now orchestrates the AST and the LLVM IR with the 
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an 
interpreter value into the clang::Value object. The new implementation 
simplifies use-cases which are used for out-of-process execution by allowing 
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in 
llvm/llvm-project#84769

---

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


13 Files Affected:

- (modified) clang/include/clang/Frontend/MultiplexConsumer.h (+2-1) 
- (modified) clang/include/clang/Interpreter/Interpreter.h (+26-27) 
- (modified) clang/lib/Frontend/MultiplexConsumer.cpp (+7) 
- (modified) clang/lib/Interpreter/CMakeLists.txt (+1) 
- (modified) clang/lib/Interpreter/DeviceOffload.cpp (+5-5) 
- (modified) clang/lib/Interpreter/DeviceOffload.h (+7-7) 
- (modified) clang/lib/Interpreter/IncrementalExecutor.cpp (+1-1) 
- (modified) clang/lib/Interpreter/IncrementalParser.cpp (+8-245) 
- (modified) clang/lib/Interpreter/IncrementalParser.h (+8-37) 
- (modified) clang/lib/Interpreter/Interpreter.cpp (+218-428) 
- (added) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+398) 
- (modified) clang/unittests/Interpreter/CodeCompletionTest.cpp (+1-1) 
- (modified) clang/unittests/Interpreter/InterpreterExtensionsTest.cpp (+23-41) 


``diff
diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class InProcessPrintingASTConsumer;
 
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
+  friend class Value;
+  friend InProcessPrintingASTConsumer;
+
   std::unique_ptr TSCtx;
+  /// Long-lived, incremental parsing action.
+  std::unique_ptr Act;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
-  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
+  /// List containing every information about every incrementally parsed piece
+  /// of code.
+  std::list PTUs;
+
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -104,15 +106,15 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
-  // Add a call to an Expr to report its result. We query the function from
-  // Runt

[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-08 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev edited 
https://github.com/llvm/llvm-project/pull/107737
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-repl] Simplify the value printing logic to enable out-of-process. (PR #107737)

2024-09-08 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev created 
https://github.com/llvm/llvm-project/pull/107737

This patch improves the design of the IncrementalParser and Interpreter 
classes. Now the incremental parser is only responsible for building the 
partial translation unit declaration and the AST, while the Interpreter fills 
in the lower level llvm::Module and other JIT-related infrastructure. Finally 
the Interpreter class now orchestrates the AST and the LLVM IR with the 
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an 
interpreter value into the clang::Value object. The new implementation 
simplifies use-cases which are used for out-of-process execution by allowing 
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in 
llvm-project#84769

>From d4aa06a9118f92b4a2410794d56ee6cb530bbece Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Fri, 6 Sep 2024 09:52:36 +
Subject: [PATCH] [clang-repl] Simplify the value printing logic to enable
 out-of-process.

This patch improves the design of the IncrementalParser and Interpreter classes.
Now the incremental parser is only responsible for building the partial
translation unit declaration and the AST, while the Interpreter fills in the
lower level llvm::Module and other JIT-related infrastructure. Finally the
Interpreter class now orchestrates the AST and the LLVM IR with the
IncrementalParser and IncrementalExecutor classes.

The design improvement allows us to rework some of the logic that extracts an
interpreter value into the clang::Value object. The new implementation
simplifies use-cases which are used for out-of-process execution by allowing
interpreter to be inherited or customized with an clang::ASTConsumer.

This change will enable completing the pretty printing work which is in
llvm-project#84769
---
 .../clang/Frontend/MultiplexConsumer.h|   3 +-
 clang/include/clang/Interpreter/Interpreter.h |  53 +-
 clang/lib/Frontend/MultiplexConsumer.cpp  |   7 +
 clang/lib/Interpreter/CMakeLists.txt  |   1 +
 clang/lib/Interpreter/DeviceOffload.cpp   |  10 +-
 clang/lib/Interpreter/DeviceOffload.h |  14 +-
 clang/lib/Interpreter/IncrementalExecutor.cpp |   2 +-
 clang/lib/Interpreter/IncrementalParser.cpp   | 253 +--
 clang/lib/Interpreter/IncrementalParser.h |  45 +-
 clang/lib/Interpreter/Interpreter.cpp | 646 ++
 .../Interpreter/InterpreterValuePrinter.cpp   | 398 +++
 .../Interpreter/CodeCompletionTest.cpp|   2 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  64 +-
 13 files changed, 705 insertions(+), 793 deletions(-)
 create mode 100644 clang/lib/Interpreter/InterpreterValuePrinter.cpp

diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h 
b/clang/include/clang/Frontend/MultiplexConsumer.h
index 3a7670d7a51aa6..b190750bb29fb8 100644
--- a/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -53,6 +53,7 @@ class MultiplexConsumer : public SemaConsumer {
 public:
   // Takes ownership of the pointers in C.
   MultiplexConsumer(std::vector> C);
+  MultiplexConsumer(std::unique_ptr C);
   ~MultiplexConsumer() override;
 
   // ASTConsumer
@@ -80,7 +81,7 @@ class MultiplexConsumer : public SemaConsumer {
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1234608bb58647..cbb1cfd4ab02a8 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -14,11 +14,9 @@
 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
 
-#include "clang/AST/Decl.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
-#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
 namespace clang {
 
 class CompilerInstance;
+class CodeGenerator;
+class CXXRecordDecl;
+class Decl;
 class IncrementalExecutor;
 class IncrementalParser;
 
@@ -77,26 +78,27 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
-/// Generate glue code between the Interpreter's built-in runtime and user 
code.
-class RuntimeInterfaceBuilder {
-public:
-  virtual ~RuntimeInterfaceBuilder() = default;
-
-  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
-   Expr *, ArrayRef);
-  virtual TransformExprFunction *getPrintValueTransformer() = 0;
-};
+class IncrementalAction;
+class In