diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 7390d7d610ec0..855c8285e841c 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -55,6 +55,25 @@ #include #include +#if defined(CLANG_PLUGIN_SUPPORT) && defined(_WIN32) +#include "clang/Frontend/FrontendPluginRegistry.h" + +// Force plugin registry symbols into clang.exe on Windows so plugins can +// register. These methods exist in libraries but aren't linked by default +// because they're unreferenced. Taking their addresses forces the linker to +// include them. +namespace { +void ForcePluginRegistrySymbols() { + using PluginRegistry = llvm::Registry; + // Use volatile to prevent the compiler from optimizing away these references + volatile auto add_node_ptr = &PluginRegistry::add_node; + volatile auto begin_ptr = &PluginRegistry::begin; + (void)add_node_ptr; + (void)begin_ptr; +} +} // anonymous namespace +#endif + using namespace clang; using namespace clang::driver; using namespace llvm::opt; diff --git a/llvm/utils/extract_symbols.py b/llvm/utils/extract_symbols.py index 388723421d660..72f992f560c7f 100755 --- a/llvm/utils/extract_symbols.py +++ b/llvm/utils/extract_symbols.py @@ -105,6 +105,11 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration): # Skip X86GenMnemonicTables functions, they are not exposed from llvm/include/. elif re.match(r"\?is[A-Z0-9]*@X86@llvm", symbol): return None + # Keep Registry::Head and Registry::Tail static members for plugin support. + # Pattern matches: ?Head@?$Registry@@llvm@@ or ?Tail@?$Registry@... + elif ("?$Registry@" in symbol and "@llvm@@" in symbol and + (symbol.startswith("?Head@") or symbol.startswith("?Tail@"))): + return symbol # Keep mangled llvm:: and clang:: function symbols. How we detect these is a # bit of a mess and imprecise, but that avoids having to completely demangle # the symbol name. The outermost namespace is at the end of the identifier