Reland "[clang-repl] Allow loading of plugins in clang-repl."
authorVassil Vassilev <v.g.vassilev@gmail.com>
Tue, 5 Oct 2021 06:11:42 +0000 (06:11 +0000)
committerVassil Vassilev <v.g.vassilev@gmail.com>
Tue, 5 Oct 2021 13:04:01 +0000 (13:04 +0000)
Differential revision: https://reviews.llvm.org/D110484

clang/include/clang/Frontend/CompilerInstance.h
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
clang/lib/Interpreter/IncrementalParser.cpp
clang/test/Interpreter/plugins.cpp [new file with mode: 0644]
clang/tools/clang-repl/CMakeLists.txt
clang/tools/clang-repl/ClangRepl.cpp

index 861b150..74e152e 100644 (file)
@@ -219,6 +219,9 @@ public:
   // of the context or else not CompilerInstance specific.
   bool ExecuteAction(FrontendAction &Act);
 
+  /// Load the list of plugins requested in the \c FrontendOptions.
+  void LoadRequestedPlugins();
+
   /// }
   /// @name Compiler Invocation and Options
   /// {
index 8de2e75..a9c7566 100644 (file)
@@ -23,6 +23,7 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Frontend/LogDiagnosticPrinter.h"
 #include "clang/Frontend/SerializedDiagnosticPrinter.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
@@ -1029,6 +1030,27 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
   return !getDiagnostics().getClient()->getNumErrors();
 }
 
+void CompilerInstance::LoadRequestedPlugins() {
+  // Load any requested plugins.
+  for (const std::string &Path : getFrontendOpts().Plugins) {
+    std::string Error;
+    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
+      getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
+          << Path << Error;
+  }
+
+  // Check if any of the loaded plugins replaces the main AST action
+  for (const FrontendPluginRegistry::entry &Plugin :
+       FrontendPluginRegistry::entries()) {
+    std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
+    if (P->getActionType() == PluginASTAction::ReplaceAction) {
+      getFrontendOpts().ProgramAction = clang::frontend::PluginAction;
+      getFrontendOpts().ActionName = Plugin.getName().str();
+      break;
+    }
+  }
+}
+
 /// Determine the appropriate source input kind based on language
 /// options.
 static Language getLanguageFromOptions(const LangOptions &LangOpts) {
index b95851e..dc8409f 100644 (file)
@@ -203,24 +203,7 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
     return true;
   }
 
-  // Load any requested plugins.
-  for (const std::string &Path : Clang->getFrontendOpts().Plugins) {
-    std::string Error;
-    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
-      Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
-        << Path << Error;
-  }
-
-  // Check if any of the loaded plugins replaces the main AST action
-  for (const FrontendPluginRegistry::entry &Plugin :
-       FrontendPluginRegistry::entries()) {
-    std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
-    if (P->getActionType() == PluginASTAction::ReplaceAction) {
-      Clang->getFrontendOpts().ProgramAction = clang::frontend::PluginAction;
-      Clang->getFrontendOpts().ActionName = Plugin.getName().str();
-      break;
-    }
-  }
+  Clang->LoadRequestedPlugins();
 
   // Honor -mllvm.
   //
index 897e2cd..6c5a26e 100644 (file)
@@ -65,6 +65,8 @@ public:
           case frontend::ParseSyntaxOnly:
             Act = CreateFrontendAction(CI);
             break;
+          case frontend::PluginAction:
+            LLVM_FALLTHROUGH;
           case frontend::EmitAssembly:
             LLVM_FALLTHROUGH;
           case frontend::EmitObj:
diff --git a/clang/test/Interpreter/plugins.cpp b/clang/test/Interpreter/plugins.cpp
new file mode 100644 (file)
index 0000000..032f704
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: cat %s | clang-repl -Xcc -Xclang -Xcc -load -Xcc -Xclang \
+// RUN:            -Xcc %llvmshlibdir/PrintFunctionNames%pluginext -Xcc -Xclang\
+// RUN:            -Xcc -add-plugin -Xcc -Xclang -Xcc print-fns 2>&1 | FileCheck %s
+// REQUIRES: host-supports-jit, plugins, examples
+
+int i = 10;
+extern "C" int printf(const char*,...);
+auto r1 = printf("i = %d\n", i);
+quit
+
+
+// CHECK: top-level-decl: "i"
+// CHECK-NEXT: top-level-decl: "r1"
+// CHECK-NEXT: i = 10
index 060c62a..30e3b2b 100644 (file)
@@ -13,6 +13,12 @@ add_clang_tool(clang-repl
 
 clang_target_link_libraries(clang-repl PUBLIC
   clangBasic
+  clangFrontend
   clangInterpreter
   clangTooling
   )
+
+# Support plugins.
+if(CLANG_PLUGIN_SUPPORT)
+  export_executable_symbols_for_plugins(clang-repl)
+endif()
index 8e50418..4240b9d 100644 (file)
@@ -80,6 +80,9 @@ int main(int argc, const char **argv) {
   llvm::install_fatal_error_handler(LLVMErrorHandler,
                                     static_cast<void *>(&CI->getDiagnostics()));
 
+  // Load any requested plugins.
+  CI->LoadRequestedPlugins();
+
   auto Interp = ExitOnErr(clang::Interpreter::create(std::move(CI)));
   for (const std::string &input : OptInputs) {
     if (auto Err = Interp->ParseAndExecute(input))