Skip to content

Commit a42836f

Browse files
committed
[Windows] Fix plugin registry symbols not exported/linked with CLANG_LINK_CLANG_DYLIB
When building LLVM with CLANG_LINK_CLANG_DYLIB=ON on Windows, external plugins cannot register through llvm::Registry<clang::PluginASTAction> due to two issues: 1. Static data members (Head, Tail) are filtered out during symbol export 2. Static methods (add_node(), begin()) are not linked into the executable This change fixes both issues: - Modified extract_symbols.py to recognize and export Registry<T>::Head and Registry<T>::Tail static members using pattern matching instead of filtering them out as non-function symbols. - Added code in driver.cpp that references Registry methods, forcing the linker to include these symbols in clang.exe even though they're not directly called by the driver. Fixes #163367
1 parent 0ebcc97 commit a42836f

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

clang/tools/driver/driver.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,25 @@
5555
#include <set>
5656
#include <system_error>
5757

58+
#if defined(CLANG_PLUGIN_SUPPORT) && defined(_WIN32)
59+
#include "clang/Frontend/FrontendPluginRegistry.h"
60+
61+
// Force plugin registry symbols into clang.exe on Windows so plugins can
62+
// register. These methods exist in libraries but aren't linked by default
63+
// because they're unreferenced. Taking their addresses forces the linker to
64+
// include them.
65+
namespace {
66+
void ForcePluginRegistrySymbols() {
67+
using PluginRegistry = llvm::Registry<clang::PluginASTAction>;
68+
// Use volatile to prevent the compiler from optimizing away these references
69+
volatile auto add_node_ptr = &PluginRegistry::add_node;
70+
volatile auto begin_ptr = &PluginRegistry::begin;
71+
(void)add_node_ptr;
72+
(void)begin_ptr;
73+
}
74+
} // anonymous namespace
75+
#endif
76+
5877
using namespace clang;
5978
using namespace clang::driver;
6079
using namespace llvm::opt;

llvm/utils/extract_symbols.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration):
105105
# Skip X86GenMnemonicTables functions, they are not exposed from llvm/include/.
106106
elif re.match(r"\?is[A-Z0-9]*@X86@llvm", symbol):
107107
return None
108+
# Keep Registry<T>::Head and Registry<T>::Tail static members for plugin support.
109+
# Pattern matches: ?Head@?$Registry@<template_args>@llvm@@ or ?Tail@?$Registry@...
110+
elif ("?$Registry@" in symbol and "@llvm@@" in symbol and
111+
(symbol.startswith("?Head@") or symbol.startswith("?Tail@"))):
112+
return symbol
108113
# Keep mangled llvm:: and clang:: function symbols. How we detect these is a
109114
# bit of a mess and imprecise, but that avoids having to completely demangle
110115
# the symbol name. The outermost namespace is at the end of the identifier

0 commit comments

Comments
 (0)