From be215a25f00139d68517589d78a79c3aa7a7eb26 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 10 Sep 2026 03:11:40 -0400 Subject: [PATCH] [Windows] Don't export clang::interp symbols for plugins (#221295) With `LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON`, `clang.exe` built from the 23.x release branch exports 66679 symbols on x86_64 Windows, over the 65535 limit of the PE export table, so it no longer links: ``` lld-link: error: too many exported symbols (got 66679, max 65535) ``` For comparison, the same configuration on 22.1.8 exports 65465 symbols, so the headroom was already almost gone. `clang::interp`, the constant expression bytecode interpreter, accounts for roughly 4500 of the exported symbols (counted with `llvm-readobj --coff-exports` on a linked aarch64 23.1.0 `clang.exe`). Its headers live in `clang/lib/AST/ByteCode` and are not installed; the only mention in a public header is the forward declaration of `interp::Context` in `ASTContext.h`. A plugin cannot call into it, so there is no reason to keep exporting it. Filtering it out follows the existing `dump`/`dumpColor`/`printPretty` exclusions in `should_keep_microsoft_symbol`. Related: #87865 (open; earlier rounds #60109, #56109). This does not get the MSVC-with-examples configuration from that issue under the limit by itself, but it removes the largest block of symbols that can never be used by a plugin, and is what gets the Firefox clang 23 toolchain (x86_64-pc-windows-msvc, X86;ARM;AArch64;WebAssembly, clang+lld+clang-tools-extra) from 66679 to roughly 62100 exports. --- **AI tool use disclosure** (per the [LLVM AI Tool Use Policy](https://llvm.org/docs/AIToolPolicy.html)): this change was developed with Claude Code assisting in the analysis and drafting. The root cause was established against real 23.1.0 binaries and libraries, the patch was reviewed and tested by the author in Firefox's CI, and the author is accountable for and able to answer questions about it. Commits carry an `Assisted-by:` trailer. --- llvm/utils/extract_symbols.py | 4 ++++ 1 file changed, 4 insertions(+) mode change 100755 => 100644 llvm/utils/extract_symbols.py diff --git a/llvm/utils/extract_symbols.py b/llvm/utils/extract_symbols.py old mode 100755 new mode 100644 index 40a43d3655552..6aeef4b2cddca --- a/llvm/utils/extract_symbols.py +++ b/llvm/utils/extract_symbols.py @@ -155,6 +155,10 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration): # because they are used for debugging only. if symbol.startswith(("?dump@", "?dumpColor@", "?printPretty@")): return None + # Remove clang::interp:: symbols: the bytecode interpreter's headers are + # private to clang/lib/AST/ByteCode, so no plugin can reference them. + if "@interp@clang@@" in symbol: + return None return symbol # Keep mangled global variables and static class members in llvm:: namespace. # These have a type mangling that looks like (this is derived from