ehsan created this revision. ehsan added a reviewer: rnk. ehsan added a subscriber: cfe-commits.
This builds on the support being added to LLVM to import and export registries from DLLs. This will allow us to pick up the registry entries added in the DLL's copy of FrontendPluginRegistry. This will allow us to use plugins on Windows using: $ clang-cl -Xclang -load -Xclang plugin.dll \ -Xclang -add-plugin -Xclang foo clang-cl: Enable plugins on Windows http://reviews.llvm.org/D16761 Files: docs/ClangPlugins.rst examples/PrintFunctionNames/PrintFunctionNames.cpp lib/FrontendTool/ExecuteCompilerInvocation.cpp test/Frontend/plugins.c test/lit.cfg Index: test/lit.cfg =================================================================== --- test/lit.cfg +++ test/lit.cfg @@ -196,7 +196,7 @@ # Plugins (loadable modules) # TODO: This should be supplied by Makefile or autoconf. -if sys.platform in ['win32', 'cygwin']: +if sys.platform in ['cygwin']: has_plugins = (config.enable_shared == 1) else: has_plugins = True Index: test/Frontend/plugins.c =================================================================== --- test/Frontend/plugins.c +++ test/Frontend/plugins.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -load %llvmshlibdir/PrintFunctionNames%pluginext -plugin print-fns %s 2>&1 | FileCheck %s +// RUN: %clang_cl -Xclang -load -Xclang %llvmshlibdir/PrintFunctionNames%pluginext -Xclang -plugin -Xclang print-fns %s 2>&1 | FileCheck %s // REQUIRES: plugins, examples // CHECK: top-level-decl: "x" Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -184,9 +184,18 @@ e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { const std::string &Path = Clang->getFrontendOpts().Plugins[i]; std::string Error; - if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + llvm::sys::DynamicLibrary DL( + llvm::sys::DynamicLibrary::getPermanentLibrary(Path.c_str(), &Error)); + if (DL.isValid()) { +#ifdef _MSC_VER + // On Windows, we need to import the plugin front-end action + // dynamically. + LLVM_IMPORT_REGISTRY(FrontendPluginRegistry, DL); +#endif + } else { Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) << Path << Error; + } } // Honor -mllvm. Index: examples/PrintFunctionNames/PrintFunctionNames.cpp =================================================================== --- examples/PrintFunctionNames/PrintFunctionNames.cpp +++ examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -121,3 +121,6 @@ static FrontendPluginRegistry::Add<PrintFunctionNamesAction> X("print-fns", "print function names"); +#ifdef _MSC_VER +LLVM_EXPORT_REGISTRY(FrontendPluginRegistry) +#endif Index: docs/ClangPlugins.rst =================================================================== --- docs/ClangPlugins.rst +++ docs/ClangPlugins.rst @@ -37,11 +37,16 @@ ==================== A plugin is loaded from a dynamic library at runtime by the compiler. To -register a plugin in a library, use ``FrontendPluginRegistry::Add<>``: +register a plugin in a library, use ``FrontendPluginRegistry::Add<>``. +Note that on Windows, you also need to export your plugin registry using +``LLVM_EXPORT_REGISTRY``. Here is an example: .. code-block:: c++ static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description"); + #ifdef _MSC_VER + LLVM_EXPORT_REGISTRY(FrontendPluginRegistry) + #endif Putting it all together =======================
Index: test/lit.cfg =================================================================== --- test/lit.cfg +++ test/lit.cfg @@ -196,7 +196,7 @@ # Plugins (loadable modules) # TODO: This should be supplied by Makefile or autoconf. -if sys.platform in ['win32', 'cygwin']: +if sys.platform in ['cygwin']: has_plugins = (config.enable_shared == 1) else: has_plugins = True Index: test/Frontend/plugins.c =================================================================== --- test/Frontend/plugins.c +++ test/Frontend/plugins.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -load %llvmshlibdir/PrintFunctionNames%pluginext -plugin print-fns %s 2>&1 | FileCheck %s +// RUN: %clang_cl -Xclang -load -Xclang %llvmshlibdir/PrintFunctionNames%pluginext -Xclang -plugin -Xclang print-fns %s 2>&1 | FileCheck %s // REQUIRES: plugins, examples // CHECK: top-level-decl: "x" Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -184,9 +184,18 @@ e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { const std::string &Path = Clang->getFrontendOpts().Plugins[i]; std::string Error; - if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + llvm::sys::DynamicLibrary DL( + llvm::sys::DynamicLibrary::getPermanentLibrary(Path.c_str(), &Error)); + if (DL.isValid()) { +#ifdef _MSC_VER + // On Windows, we need to import the plugin front-end action + // dynamically. + LLVM_IMPORT_REGISTRY(FrontendPluginRegistry, DL); +#endif + } else { Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) << Path << Error; + } } // Honor -mllvm. Index: examples/PrintFunctionNames/PrintFunctionNames.cpp =================================================================== --- examples/PrintFunctionNames/PrintFunctionNames.cpp +++ examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -121,3 +121,6 @@ static FrontendPluginRegistry::Add<PrintFunctionNamesAction> X("print-fns", "print function names"); +#ifdef _MSC_VER +LLVM_EXPORT_REGISTRY(FrontendPluginRegistry) +#endif Index: docs/ClangPlugins.rst =================================================================== --- docs/ClangPlugins.rst +++ docs/ClangPlugins.rst @@ -37,11 +37,16 @@ ==================== A plugin is loaded from a dynamic library at runtime by the compiler. To -register a plugin in a library, use ``FrontendPluginRegistry::Add<>``: +register a plugin in a library, use ``FrontendPluginRegistry::Add<>``. +Note that on Windows, you also need to export your plugin registry using +``LLVM_EXPORT_REGISTRY``. Here is an example: .. code-block:: c++ static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description"); + #ifdef _MSC_VER + LLVM_EXPORT_REGISTRY(FrontendPluginRegistry) + #endif Putting it all together =======================
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits