From 3e1aa3ac9a4c9e6c96c04d37730d2ee03ae1444f Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Fri, 16 Nov 2018 10:30:57 +0100 Subject: [PATCH] [cling] Handle the case if the plugin is passed as a shared object. When cling is embedded and the plugins are linked statically we can rely on the initialization of the Preprocessor to register the pragmas. Currently, due to the current implementation deficiency we cannot rely on the same mechanism when loading the plugins as shared objects. This patch fixes the failing cling test. --- .../cling/lib/Interpreter/IncrementalParser.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp index 2593c21fb28b8..2a1724ffc31f7 100644 --- a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp +++ b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp @@ -193,12 +193,25 @@ static void HandlePlugins(CompilerInstance& CI, // plugins if cling is in a single shared library which is dlopen-ed with // RTLD_LOCAL. In that situation plugins can still find the cling, clang and // llvm symbols opened with local visibility. - if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end()) + if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end()) { for (const std::string& Path : CI.getFrontendOpts().Plugins) { std::string Err; if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Err)) CI.getDiagnostics().Report(clang::diag::err_fe_unable_to_load_plugin) << Path << Err; + } + // If we are not statically linked, we should register the pragmas ourselves + // because the dlopen happens after creating the clang::Preprocessor which + // calls RegisterBuiltinPragmas. + // FIXME: This can be avoided by refactoring our routine and moving it to + // the CIFactory. This requires an abstraction which allows us to + // conditionally create MultiplexingConsumers. + + // Copied from Lex/Pragma.cpp + // Pragmas added by plugins + for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(), + ie = PragmaHandlerRegistry::end(); it != ie; ++it) + CI.getPreprocessor().AddPragmaHandler(it->instantiate().release()); } for (auto it = clang::FrontendPluginRegistry::begin(),