<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/163367>163367</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[Windows] Plugin registry symbols not exported/linked with CLANG_LINK_CLANG_DYLIB, breaking external plugins
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
zond
</td>
</tr>
</table>
<pre>
**Summary**
On Windows, when building LLVM with `CLANG_LINK_CLANG_DYLIB=ON`, external plugins cannot register themselves 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 breaks the plugin registration mechanism that relies on static initialization.
**Affected Versions**
- LLVM 19, 20, 21, and main branch (verified 2025-01-14)
- Specifically affects Windows builds with `CLANG_LINK_CLANG_DYLIB=ON`
**Problem Description**
**Issue 1: Registry symbols filtered from DLL exports**
The script `llvm/utils/extract_symbols.py` generates `.def` files for Windows DLL symbol exports. At line 126, it filters symbols with this regex:
```python
elif re.search(r"(llvm|clang)@@[A-Z][A-Z0-9_]*[A-JQ].+(X|.+@|.*Z)$", symbol):
```
This pattern matches MSVC-mangled function symbols but excludes static data members, which have `@@0` or `@@3` suffixes. The `Registry<T>` static members `Head` and `Tail` are therefore filtered out:
```
?Head@?$Registry@VPluginASTAction@clang@@@llvm@@0PEAVnode@12@EA
?Tail@?$Registry@VPluginASTAction@clang@@@llvm@@0PEAPEAVnode@12@EA
```
Without these symbols exported, plugins cannot access the registry's linked list.
**Issue 2: Registry methods not linked into executable**
Even if the symbols are exported from the DLL, the `Registry<T>` methods `add_node()` and `begin()` exist in libraries but aren't linked into `clang.exe` by default because nothing in the main executable references them. When plugins try to call these functions, they fail because the symbols aren't present in the executable's import address table.
**Reproduction**
1. Build LLVM with `-DCLANG_LINK_CLANG_DYLIB=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON` on Windows
2. Create an external plugin that registers via `Registry<PluginASTAction>`
3. Try to load the plugin with `clang.exe -Xclang -load -Xclang plugin.dll`
Result: Plugin fails to register, either due to missing symbols or unresolved externals.
**Expected Behavior**
Plugins should be able to register themselves using the `Registry<T>` pattern, as they can on Linux/macOS and as documented in the LLVM plugin documentation.
**Context**
This issue was discovered while enabling Clang 20 support for Firefox's clang-plugin on Windows. Firefox has been working around similar issues with local patches, but this affects any downstream project trying to build Windows plugins with dynamic linking.
The `Registry<T>` pattern is fundamental to LLVM's plugin infrastructure and is used throughout the codebase for various plugin types (`PluginASTAction`, `PassBuilderOptPluginPass`, etc.).
**Related**
- `llvm/utils/extract_symbols.py` - Symbol export script
- `clang/tools/driver/driver.cpp` - Main executable
- `llvm/include/llvm/Support/Registry.h` - Registry template definition
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykV12P4joS_TXulxJRcICGBx7oprk7u8x079A7M_e-tJykQrzj2Mh2aLi_flV2wtfMXF1pJYQcY8r1cerUiXBObjXinI0f2Hh5J1pfGzv_0-jyLjflcc74gvHFpm0aYY_xgaX0edbwVerSvDvGH-G9Rg15K1Up9RbW6y8f4V36GtgkfVwvPv32tv7w6V9vcbn8ff3hgWXL509sktKf8eDRaqFgp9qt1A4KobXxYHErnUcLvsbGodqjA19b026DYaX2DcsWLFt8DgftkWWPhRJ6G3dfgrXF5nVReGk0y57YJIWyRfAG_LsB6VyLjg6ni2ECGy-8LKAUXkCDTY7WAeNTNkn_gaLsfGWT9FVIFZ5mICxCJZVHiyWY1kPZWkqAOza5UYCHnbGepQt-st6gr03ZGxZl-aZNifTEZ-crctxKfbEZb6KcKKm_YwlSUww1Ah6waL3IFcayvNbSQW5RfHfh95jSLpVWUCKgwaIWWroGfC0ozUqiA6PBRR-lll4KJf8Mx5NoONZ-UVVYeCzhC1onjXaXkBjEwg9nFAUPsfAhfQtdQiOkhtwKXdQU_B6trCSWwFM-HqTDwXBEwZKRzQ4LWclCKHUEES50PdYixtzfBdeF5y_W5AobWKIrrNwFRFz4HtcfCBEwZNkCekx1tXTnOlfWNLBcr7vyXqXgtUaI9k8I5avWS-UYX-HBW1H4t85isjsSILeo0QqPjv6RlFjRZiUVOqiMPQVOF17ByiWwCHhAGPIJpVn6zkl3cjrkyRMmLG7xELFOn0kaP7ujr41m6QKVrMBi4lDYomZ8ahnnjE9DDPddX_EZG6X0GT8sBn-w8TIu0sHsjR74Ijz_899svEwYf2B8-o3dP4blKI2rxR9khY-C9cfOUdrKrvy6QPNOeOIHaIQvanTwcfPlcdAIvVVUjFaH7j5FnLce8FCotkTXA_qypSNbyaKGWuyRch5DokvB2PNGRhuurSp5QJcAVZZN0guqee0YxfWd3VHGiS8C7s-EEXrY12ixMje88WNdaJ2tgqFRyrIV46PT1aP0yy23jdJYoFHnfKhajOvlafElcMwoHXI2Sp8W0Xbw6v-3_XPz12X8Kn1N7OhrdHiqVIQxllSRG-YXRYEuEpjtPeP3rmc_JZ1PfuxbftW3PdPesuYFY1407tMeNcgqXNk7SPXqnYxdT78u12vy2P8SDyeK_wm_95C4JnjAg3QepAYlcyss0THhWFjUjN9f-88msR4JHpD-mx-hxEq0ykOOhWhdGBQ1jSGpg5uBes9hg8UKLeoijFNsEvhK07svAeXOGyD67QrW95jr4j5CJaQ63XaTsujxzqJD7XsXLpN-70A2lFUQZWlDnemHq4J-xp01ZVvc0vQwgQeaANcSY7D8izkAgyUdfnv69vL8-fVt8_vHh-f15m31_PntZf2f3z582vTjgkZgr2nCzH60KDyC0LcSpR-cUZ842EtxA4afig-WLrIEXmOClRHl5YjugzkVFwbfwhoG4Wj_FI8npVKn_vqMrlVEIhCvDfVxdEnvYpBZksinF0CNdO4sVRxRX6stOqP2WJ7idVdVeTrs4vR_wFrspbGXpXnp8ONq06oScoQAtgsnLnVcGy7_dRN1pB_Ug4ugK4SmCq2lbg-MrxpRPG9CPwkHpSnaBrUPTRLMBoB0qe1__VHPPBrt8eCvR7h0URrCO1mWrjD7QNTvtVQIqEWuyPnHUA5OQ2IX4EzjeiWJ3g8B5aFeg86HM7aS_hDUwkGOqOHd2O9kUljT6hKcbKQSthOoERnKFAS_OAMpLXkgVOlOEknoI5TmXTtvUTSws-a_WHjq55BqE7XTSVD0_R6sl0ctGlkEopF6m5zVzF-WB6QjdihFyK6iSyjvIfoubqkrK5y3beFbi6FeksqPZa_lu8kAhSkxF8Q3xsJeWGnakxV_3GEvmm9b66SaX4RzgR3QPu98PEZ7_WuGLxLGZzc8o0QYQZcq9u8qtwFsLgVZJ_x6E51iWnljgo3Syj01YrdIit0uGvl4Tc83LkgdtAzjq25jE9HG-KqvS1JHQ6fR57HZUVw0GIKYDwrvrpxn5SybiTucD-8n6Wg0nEymd_U8zaosTWfI0wynKLKKF7P76ZSPeVUWk_H0Ts5JpQ_T4Wg4zEZ8mowyzCZinFeTYTrMecZGKTZCqoR8TIzd3gXozoeTLJvc3ymRo3L9O6ad06lB3m4dqQnpvDv_z0uvwttoT8TjZU9q9laR02Q_i4hVNyQDnn8xD6ht6N2IGuL2rfOutWpee78Lb4R8xfhqK33d5klhmnP6g-9db1F54jskX3Wh7uf8fwEAAP__lML8Rw">