Skip to content

Commit 8e3aa71

Browse files
committed
Bug 1941482 - Enable Clang 20 support for Firefox with Windows plugin 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
1 parent 77c24e7 commit 8e3aa71

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

build/build-clang/clang-20.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"llvmorg-22-init-4745-gbe179d069664.patch",
1313
"android-hardware-buffer-header-workaround.patch",
1414
"arm64e-hack.patch",
15-
"compiler-rt-rss-limit-heap-profile.patch"
15+
"compiler-rt-rss-limit-heap-profile.patch",
16+
"plugin-registry-symbols-llvm-pr-163391.patch"
1617
]
1718
}

build/build-clang/clang-trunk.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"revert-llvmorg-15-init-13446-g7524fe962e47.patch",
1111
"android-hardware-buffer-header-workaround_clang_21.patch",
1212
"arm64e-hack.patch",
13-
"compiler-rt-rss-limit-heap-profile.patch"
13+
"compiler-rt-rss-limit-heap-profile.patch",
14+
"plugin-registry-symbols-llvm-pr-163391.patch"
1415
]
1516
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
Fix plugin registry symbols not exported/linked with CLANG_LINK_CLANG_DYLIB.
2+
3+
When building LLVM with CLANG_LINK_CLANG_DYLIB=ON on Windows, external plugins
4+
cannot register through llvm::Registry<clang::PluginASTAction> due to two issues:
5+
6+
1. Static data members (Head, Tail) are filtered out during symbol export by
7+
extract_symbols.py because they don't match function signature patterns.
8+
9+
2. Static methods (add_node(), begin()) exist in libraries but aren't linked
10+
into clang.exe because they're unreferenced by the driver.
11+
12+
This patch fixes both issues by adding pattern matching to recognize Registry
13+
symbols for export and by adding C++ code to force linking of Registry methods.
14+
15+
See https://github.com/llvm/llvm-project/issues/163367
16+
17+
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
18+
index 00c00cea16f4..d2622e679a47 100644
19+
--- a/clang/tools/driver/driver.cpp
20+
+++ b/clang/tools/driver/driver.cpp
21+
@@ -55,6 +55,25 @@
22+
#include <set>
23+
#include <system_error>
24+
25+
+#if defined(CLANG_PLUGIN_SUPPORT) && defined(_WIN32)
26+
+#include "clang/Frontend/FrontendPluginRegistry.h"
27+
+
28+
+// Force plugin registry symbols into clang.exe on Windows so plugins can
29+
+// register. These methods exist in libraries but aren't linked by default
30+
+// because they're unreferenced. Taking their addresses forces the linker to
31+
+// include them.
32+
+namespace {
33+
+void ForcePluginRegistrySymbols() {
34+
+ using PluginRegistry = llvm::Registry<clang::PluginASTAction>;
35+
+ // Use volatile to prevent the compiler from optimizing away these references
36+
+ volatile auto add_node_ptr = &PluginRegistry::add_node;
37+
+ volatile auto begin_ptr = &PluginRegistry::begin;
38+
+ (void)add_node_ptr;
39+
+ (void)begin_ptr;
40+
+}
41+
+} // anonymous namespace
42+
+#endif
43+
+
44+
using namespace clang;
45+
using namespace clang::driver;
46+
using namespace llvm::opt;
47+
diff --git a/llvm/utils/extract_symbols.py b/llvm/utils/extract_symbols.py
48+
index 388723421d66..72f992f560c7 100755
49+
--- a/llvm/utils/extract_symbols.py
50+
+++ b/llvm/utils/extract_symbols.py
51+
@@ -105,6 +105,11 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration):
52+
# Skip X86GenMnemonicTables functions, they are not exposed from llvm/include/.
53+
elif re.match(r"\?is[A-Z0-9]*@X86@llvm", symbol):
54+
return None
55+
+ # Keep Registry<T>::Head and Registry<T>::Tail static members for plugin support.
56+
+ # Pattern matches: ?Head@?$Registry@<template_args>@llvm@@ or ?Tail@?$Registry@...
57+
+ elif ("?$Registry@" in symbol and "@llvm@@" in symbol and
58+
+ (symbol.startswith("?Head@") or symbol.startswith("?Tail@"))):
59+
+ return symbol
60+
# Keep mangled llvm:: and clang:: function symbols. How we detect these is a
61+
# bit of a mess and imprecise, but that avoids having to completely demangle
62+
# the symbol name. The outermost namespace is at the end of the identifier

build/clang-plugin/moz.build

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ if CONFIG["HOST_OS_ARCH"] == "WINNT":
134134
# but as of writing, it's not necessary for the plugin code, so enable
135135
# the escape hatch, at least until we generally upgrade to VS 2019.
136136
HOST_DEFINES["LLVM_FORCE_USE_OLD_TOOLCHAIN"] = True
137+
# Clang 20+ needs /Zc:dllexportInlines- to work around CLANG_ABI issues with inline methods
138+
if CONFIG["HOST_CC_VERSION"] and int(CONFIG["HOST_CC_VERSION"].split(".")[0]) >= 20:
139+
extra_cxxflags += ["/Zc:dllexportInlines-"]
137140
else:
138141
extra_cxxflags = ["-fno-rtti", "-fno-exceptions"]
139142

0 commit comments

Comments
 (0)