diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -219,6 +219,9 @@ // 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 /// { diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -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 @@ 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 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) { diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -203,24 +203,7 @@ 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 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. // diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -65,6 +65,8 @@ 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 --- /dev/null +++ b/clang/test/Interpreter/plugins.cpp @@ -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 diff --git a/clang/tools/clang-repl/CMakeLists.txt b/clang/tools/clang-repl/CMakeLists.txt --- a/clang/tools/clang-repl/CMakeLists.txt +++ b/clang/tools/clang-repl/CMakeLists.txt @@ -16,3 +16,8 @@ clangInterpreter clangTooling ) + +# Support plugins. +if(CLANG_PLUGIN_SUPPORT) + export_executable_symbols_for_plugins(clang-repl) +endif() diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -80,6 +80,9 @@ llvm::install_fatal_error_handler(LLVMErrorHandler, static_cast(&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))