Skip to content

Conversation

@zond
Copy link
Contributor

@zond zond commented Oct 14, 2025

Summary

This PR fixes an issue where external plugins cannot register through llvm::Registry<clang::PluginASTAction> when building LLVM statically on Windows with LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON.

Problem

When building LLVM with a static configuration (the default) and enabling plugin support via LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON, the extract_symbols.py script filters out Registry static data members (Head and Tail) during symbol export because they don't match the function signature patterns that the script looks for.

These static data members are essential for the plugin registry mechanism - they form the linked list that stores registered plugins.

Solution

This patch modifies extract_symbols.py to add pattern matching that recognizes and exports Registry static data members. The pattern matches mangled symbols like:

  • ?Head@?$Registry@<template_args>@llvm@@
  • ?Tail@?$Registry@<template_args>@llvm@@

Technical Details

When both LLVM and plugins are built with /Zc:dllexportInlines-, the static methods (add_node(), begin()) are inlined by the plugin at call sites. This means only the data symbols (Head, Tail) need to be exported from the executable - no changes to driver.cpp are necessary.

Testing

Verified on Firefox's clang-plugin build for Windows with Clang 20, which uses:

  • Static LLVM build
  • LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON
  • /Zc:dllexportInlines- for both LLVM and plugin compilation (which makes inline functions inlined instead of exported)

After this patch, all required Registry symbols are correctly exported from clang.exe and the plugin successfully registers.

Fixes #163367

@github-actions
Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 14, 2025

@llvm/pr-subscribers-clang

Author: None (zond)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/163391.diff

2 Files Affected:

  • (modified) clang/tools/driver/driver.cpp (+19)
  • (modified) llvm/utils/extract_symbols.py (+5)
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 <set>
 #include <system_error>
 
+#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<clang::PluginASTAction>;
+  // 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<T>::Head and Registry<T>::Tail static members for plugin support.
+    # Pattern matches: ?Head@?$Registry@<template_args>@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

zond added a commit to zond/firefox that referenced this pull request Oct 14, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced two breaking changes that prevented the clang-plugin
from loading on Windows:

1. The CLANG_ABI macro was added to Attr classes, causing inline methods
   like classof() and getAnnotation() to generate dllimport references.
   This fails because these methods are defined inline in headers, not
   exported from the DLL.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of three patches for the Clang 20 build:

- add-plugin-symbols_clang_20.patch: Adds pattern matching to
  extract_symbols.py to recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation. This replaces
  the need for hardcoded symbol whitelists and works across different
  plugin types.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- force-plugin-symbols_clang_20.patch: Adds C++ code to driver.cpp that
  references Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols. This replaces hardcoded mangled
  symbol names with type-safe references that work across compiler versions.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI
  macro from Attr class generation to prevent dllimport issues with
  inline methods.

  See llvm/llvm-project#163349.

To test this locally:

- Install the current clang-20 inside the firefox checkout:

`./mach artifact toolchain --from-build win64-clang-20`

- Install libxml2 (necessary for clang-mt.exe):

`./mach artifact toolchain --from-build win64-libxml2`

- Install wasm32-wasi-compiler-rt-20 (necessary for WASM compilation?):

`./mach artifact toolchain --from-build wasm32-wasi-compiler-rt-20`

- Check out llvm 20.1.8 in a directory alongside the firefox checkout.
- Try to build llvm, and fail when the wasi lib is missing:

`MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json`

- Copy the missing wasi lib to the stage2 build directory:

```
mkdir build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi
cp ../firefox/compiler-rt-wasm32-wasi/lib/wasi/libclang_rt.builtins-wasm32.a build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi/libclang_rt.builtins.a
```

- Try to build llvm again and succeed:

`MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json`

- Update the mozconfig in the firefox checkout to turn on the clang
  plugin and use the right compiler:

```
export CC=[THE LLVM CHECKOUT DIRECTORY]/build/stage2/clang/bin/clang-cl.exe
ac_add_options --enable-clang-plugin
```

- Build firefox:

`./mach clobber && ./mach configure --enable-bootstrap=no-update && ./mach build`

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 15, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced two breaking changes that prevented the clang-plugin
from loading on Windows:

1. The CLANG_ABI macro was added to Attr classes, causing inline methods
   like classof() and getAnnotation() to generate dllimport references.
   This fails because these methods are defined inline in headers, not
   exported from the DLL.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of two patches for the Clang 20 build:

- plugin-registry-symbols_clang_20-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  References Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI
  macro from Attr class generation to prevent dllimport issues with
  inline methods in Windows.

  See llvm/llvm-project#163349.

To test this locally:

- Install the current clang-20 inside the firefox checkout:

`./mach artifact toolchain --from-build win64-clang-20`

- Install libxml2 (necessary for clang-mt.exe):

`./mach artifact toolchain --from-build win64-libxml2`

- Install wasm32-wasi-compiler-rt-20 (necessary for WASM compilation?):

`./mach artifact toolchain --from-build wasm32-wasi-compiler-rt-20`

- Check out llvm 20.1.8 in a directory alongside the firefox checkout.
- Try to build llvm, and fail when the wasi lib is missing:

`MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json`

- Copy the missing wasi lib to the stage2 build directory:

```
mkdir build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi
cp ../firefox/compiler-rt-wasm32-wasi/lib/wasi/libclang_rt.builtins-wasm32.a build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi/libclang_rt.builtins.a
```

- Try to build llvm again and succeed:

`MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json`

- Update the mozconfig in the firefox checkout to turn on the clang
  plugin and use the right compiler:

```
export CC=[THE LLVM CHECKOUT DIRECTORY]/build/stage2/clang/bin/clang-cl.exe
ac_add_options --enable-clang-plugin
```

- Build firefox:

`./mach clobber && ./mach configure --enable-bootstrap=no-update && ./mach build`

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 16, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced two breaking changes that prevented the clang-plugin
from loading on Windows:

1. The CLANG_ABI macro was added to Attr classes, causing inline methods
   like classof() and getAnnotation() to generate dllimport references.
   This fails because these methods are defined inline in headers, not
   exported from the DLL.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of two patches for the Clang 20 build:

- plugin-registry-symbols_clang_20-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  References Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI
  macro from Attr class generation to prevent dllimport issues with
  inline methods in Windows.

  See llvm/llvm-project#163349.

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 16, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced two breaking changes that prevented the clang-plugin
from loading on Windows:

1. The CLANG_ABI macro was added to Attr classes, causing inline methods
   like classof() and getAnnotation() to generate dllimport references.
   This fails because these methods are defined inline in headers, not
   exported from the DLL.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of two patches for the Clang 20 build:

- plugin-registry-symbols_clang_20-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  References Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI
  macro from Attr class generation to prevent dllimport issues with
  inline methods in Windows.

  See llvm/llvm-project#163349.

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 16, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced two breaking changes that prevented the clang-plugin
from loading on Windows:

1. The CLANG_ABI macro was added to Attr classes, causing inline methods
   like classof() and getAnnotation() to generate dllimport references.
   This fails because these methods are defined inline in headers, not
   exported from the DLL.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of two patches for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  References Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- remove-clang-abi-from-attrs-clang-[20|trunk].patch: Removes the CLANG_ABI
  macro from Attr class generation to prevent dllimport issues with
  inline methods in Windows.

  See llvm/llvm-project#163349.

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 16, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced two breaking changes that prevented the clang-plugin
from loading on Windows:

1. The CLANG_ABI macro was added to Attr classes, causing inline methods
   like classof() and getAnnotation() to generate dllimport references.
   This fails because these methods are defined inline in headers, not
   exported from the DLL.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of two patches for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  References Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- remove-clang-abi-from-attrs-clang-[20|trunk].patch: Removes the CLANG_ABI
  macro from Attr class generation to prevent dllimport issues with
  inline methods in Windows.

  See llvm/llvm-project#163349.

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 17, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  References Registry<PluginASTAction>::add_node() and ::begin() to force
  the linker to include these symbols.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
@zmodem zmodem requested a review from john-brawn-arm October 17, 2025 07:19
Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@john-brawn-arm and @glandium are probably more familiar with extract_symbols.py.

Comment on lines 58 to 76
#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<clang::PluginASTAction>;
// 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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right to me. I think the plugin registry symbols are used in clang.exe already, e.g. at

FrontendPluginRegistry::entries()) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright - with /Zc:dllexportInlines- this wasn't necessary - the symbols are now inlined into the plugin as well!

zond added a commit to zond/firefox that referenced this pull request Oct 17, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 17, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
zond added a commit to zond/firefox that referenced this pull request Oct 17, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
@zond zond force-pushed the fix-plugin-registry-symbols branch from a42836f to 8e85cf5 Compare October 17, 2025 15:22
@zond zond changed the title [Windows] Fix plugin registry symbols not exported/linked with CLANG_LINK_CLANG_DYLIB [Windows] Fix Registry static data members not exported by extract_symbols.py in static builds with plugin support Oct 17, 2025
@zond
Copy link
Contributor Author

zond commented Oct 17, 2025

@zmodem Alright - now we removed some crud from this PR, funnily with the help of the solution to #163349

@github-actions
Copy link

github-actions bot commented Oct 20, 2025

✅ With the latest revision this PR passed the Python code formatter.

Copy link
Collaborator

@john-brawn-arm john-brawn-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjusting extract_symbols.py seems like a reasonable way of fixing this, as hopefully once #109483 is finished we can get rid of extract_symbols.py and not have to worry about this kind of thing,

zond added a commit to zond/firefox that referenced this pull request Oct 21, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
…ith plugin support.

When building LLVM statically (without BUILD_SHARED_LIBS) on Windows with
LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON, external plugins cannot register through
llvm::Registry<clang::PluginASTAction> because:

Static data members (Head, Tail) are filtered out during symbol export by
extract_symbols.py because they don't match the function signature patterns
that the script looks for.

This patch fixes the issue by adding pattern matching to extract_symbols.py
to recognize and export Registry static data members.

Note: When LLVM is built with /Zc:dllexportInlines-, inlined functions
aren't exported as symbols, and the plugin must also compile with
/Zc:dllexportInlines- to inline them instead of referencing non-exported
symbols.

Fixes llvm#163367
@zond zond force-pushed the fix-plugin-registry-symbols branch from 8e85cf5 to 9b9319c Compare October 21, 2025 06:53
zond added a commit to zond/firefox that referenced this pull request Oct 21, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
lando-prod-mozilla bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Oct 21, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
Copy link
Collaborator

@john-brawn-arm john-brawn-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zond
Copy link
Contributor Author

zond commented Oct 21, 2025

LGTM

Should I ping someone to actually merge it in, or will it happen on its own? :D

@john-brawn-arm john-brawn-arm merged commit fbcd82a into llvm:main Oct 21, 2025
10 checks passed
@john-brawn-arm
Copy link
Collaborator

I've merged this.

@github-actions
Copy link

@zond Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

i3roly pushed a commit to i3roly/firefox-dynasty that referenced this pull request Oct 25, 2025
… fixes r=glandium

This change adds support for building Firefox with Clang 20, including
critical fixes for the clang-plugin dynamic linking on Windows.

Clang 20 introduced breaking changes that prevented the clang-plugin
from building on Windows:

1. Clang is built with '/Zc:dllexportInlines-' which excludes inlined
   members like some methods of Attr classes from being dllexported.

2. The extract_symbols.py script became more aggressive in filtering
   symbols, blocking Registry<T> static data members (Head/Tail) that
   don't match function signature patterns.

The fix consists of one change to the build configuration of clang-plugin,
and one patch for the Clang 20 and trunk builds:

- plugin-registry-symbols-llvm-pr-163391.patch:

  Make extract_symbols.py recognize and export Registry<T>::Head and
  ::Tail static members for any Registry instantiation.

  See llvm/llvm-project#163367 and
  llvm/llvm-project#163391.

- Add '/Zc:dllexportInlines-' to the CXX flags when building
  clang-plugin, which will match the clang build configuration and
  inline the members instead of referencing the symbols.

Differential Revision: https://phabricator.services.mozilla.com/D268255
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
…mbols.py in static builds with plugin support (llvm#163391)

When building LLVM statically (without BUILD_SHARED_LIBS) on Windows with
LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON, external plugins cannot register through
llvm::Registry<clang::PluginASTAction> because:

Static data members (Head, Tail) are filtered out during symbol export by
extract_symbols.py because they don't match the function signature patterns
that the script looks for.

This patch fixes the issue by adding pattern matching to extract_symbols.py
to recognize and export Registry static data members.

Note: When LLVM is built with /Zc:dllexportInlines-, inlined functions
aren't exported as symbols, and the plugin must also compile with
/Zc:dllexportInlines- to inline them instead of referencing non-exported
symbols.

Fixes llvm#163367
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
…mbols.py in static builds with plugin support (llvm#163391)

When building LLVM statically (without BUILD_SHARED_LIBS) on Windows with
LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON, external plugins cannot register through
llvm::Registry<clang::PluginASTAction> because:

Static data members (Head, Tail) are filtered out during symbol export by
extract_symbols.py because they don't match the function signature patterns
that the script looks for.

This patch fixes the issue by adding pattern matching to extract_symbols.py
to recognize and export Registry static data members.

Note: When LLVM is built with /Zc:dllexportInlines-, inlined functions
aren't exported as symbols, and the plugin must also compile with
/Zc:dllexportInlines- to inline them instead of referencing non-exported
symbols.

Fixes llvm#163367
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Windows] Registry static data members not exported by extract_symbols.py, breaking plugin support in static builds

4 participants