https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/224805
>From b0e2823559de11fb14022d051ba46aaa6fb92e09 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Fri, 18 Sep 2026 19:48:57 -0700 Subject: [PATCH 1/3] [Option] Replace the OptionTables object with a function. NFC The generated `Tables` holds seven addresses, so needs dynamic relocations in PIE and shared library builds: ``` static constexpr llvm::opt::OptTable::Tables OptionTables = { OptionStrTable, OptionPrefixesTable, OptionPrefixesUnion, ...}; ... FooOptTable() : OptTable(OptionTables) {} ``` Emit a function instead. The caller builds the aggregate on the stack from PC-relative addresses, which the linker resolves: ``` static constexpr llvm::opt::OptTable::Tables optionTables() { return {OptionStrTable, OptionPrefixesTable, OptionInfoTable, ...}; } ... FooOptTable() : OptTable(optionTables()) {} ``` Derive the prefix union from the prefix table in the constructor and drop the emitted OptionPrefixesUnion. Aided by Opus 5 --- clang/lib/Options/DriverOptions.cpp | 2 +- clang/tools/clang-installapi/Options.cpp | 2 +- .../ClangLinkerWrapper.cpp | 2 +- .../ClangNVLinkWrapper.cpp | 2 +- clang/tools/clang-scan-deps/ClangScanDeps.cpp | 4 ++- .../clang-sycl-linker/ClangSYCLLinker.cpp | 2 +- lld/COFF/DriverUtils.cpp | 2 +- lld/ELF/DriverUtils.cpp | 2 +- lld/MachO/DriverUtils.cpp | 2 +- lld/MinGW/Driver.cpp | 2 +- lld/wasm/Driver.cpp | 2 +- lldb/tools/driver/Driver.cpp | 2 +- lldb/tools/lldb-dap/tool/lldb-dap.cpp | 2 +- lldb/tools/lldb-server/lldb-gdbserver.cpp | 2 +- lldb/tools/lldb-server/lldb-platform.cpp | 2 +- .../examples/OptSubcommand/llvm-hello-sub.cpp | 2 +- llvm/include/llvm/Option/OptTable.h | 4 +-- .../JITLink/COFFDirectiveParser.cpp | 3 +- llvm/lib/Option/OptTable.cpp | 18 ++++++---- .../llvm-dlltool/DlltoolDriver.cpp | 2 +- llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp | 2 +- llvm/tools/dsymutil/dsymutil.cpp | 2 +- llvm/tools/llvm-cas/llvm-cas.cpp | 2 +- llvm/tools/llvm-cgdata/llvm-cgdata.cpp | 2 +- llvm/tools/llvm-cvtres/llvm-cvtres.cpp | 2 +- llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp | 2 +- .../llvm-debuginfod-find.cpp | 2 +- .../tools/llvm-debuginfod/llvm-debuginfod.cpp | 2 +- llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp | 2 +- llvm/tools/llvm-dwp/llvm-dwp.cpp | 2 +- llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp | 4 ++- llvm/tools/llvm-ifs/llvm-ifs.cpp | 4 ++- .../llvm-libtool-darwin.cpp | 2 +- llvm/tools/llvm-lipo/llvm-lipo.cpp | 2 +- llvm/tools/llvm-ml/llvm-ml.cpp | 2 +- llvm/tools/llvm-mt/llvm-mt.cpp | 2 +- llvm/tools/llvm-nm/llvm-nm.cpp | 2 +- llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 11 +++--- llvm/tools/llvm-objdump/llvm-objdump.cpp | 4 +-- llvm/tools/llvm-rc/llvm-rc.cpp | 4 +-- llvm/tools/llvm-readobj/llvm-readobj.cpp | 2 +- llvm/tools/llvm-readtapi/llvm-readtapi.cpp | 4 ++- llvm/tools/llvm-size/llvm-size.cpp | 2 +- llvm/tools/llvm-strings/llvm-strings.cpp | 2 +- .../tools/llvm-symbolizer/llvm-symbolizer.cpp | 2 +- .../llvm-tli-checker/llvm-tli-checker.cpp | 2 +- llvm/tools/sancov/sancov.cpp | 2 +- llvm/unittests/Option/OptionParsingTest.cpp | 2 +- .../Option/OptionSubCommandsTest.cpp | 2 +- llvm/utils/TableGen/OptionParserEmitter.cpp | 34 +++++-------------- 50 files changed, 83 insertions(+), 89 deletions(-) diff --git a/clang/lib/Options/DriverOptions.cpp b/clang/lib/Options/DriverOptions.cpp index 50158f13a9653..4a1684cd3ce8c 100644 --- a/clang/lib/Options/DriverOptions.cpp +++ b/clang/lib/Options/DriverOptions.cpp @@ -23,7 +23,7 @@ namespace { class DriverOptTable : public OptTable { public: - DriverOptTable() : OptTable(OptionTables) { + DriverOptTable() : OptTable(optionTables()) { setValuesCodeFn(getOptionValuesCode); } }; diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index c3bd0b14ce65a..8c9d1142d1510 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -38,7 +38,7 @@ namespace { /// \brief Create OptTable class for parsing actual command line arguments. class DriverOptTable : public opt::OptTable { public: - DriverOptTable() : OptTable(OptionTables) {} + DriverOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace. diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 2e178aee196b6..0e71d0020c071 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -179,7 +179,7 @@ enum ID { class WrapperOptTable : public opt::OptTable { public: - WrapperOptTable() : opt::OptTable(OptionTables) {} + WrapperOptTable() : opt::OptTable(optionTables()) {} }; const OptTable &getOptTable() { diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp index 6df0af65e292b..84a3561fb9725 100644 --- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp +++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp @@ -116,7 +116,7 @@ enum ID { class WrapperOptTable : public opt::OptTable { public: - WrapperOptTable() : opt::OptTable(OptionTables) {} + WrapperOptTable() : opt::OptTable(optionTables()) {} }; const OptTable &getOptTable() { diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 0cbc115f910df..778f73909665d 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -59,7 +59,9 @@ enum ID { class ScanDepsOptTable : public llvm::opt::OptTable { public: - ScanDepsOptTable() : OptTable(OptionTables) { setGroupedShortOptions(true); } + ScanDepsOptTable() : OptTable(optionTables()) { + setGroupedShortOptions(true); + } }; enum ResourceDirRecipeKind { diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp index 84e0ead680d2b..b568c7e87ce7c 100644 --- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp +++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp @@ -103,7 +103,7 @@ enum ID { class LinkerOptTable : public opt::OptTable { public: - LinkerOptTable() : opt::OptTable(OptionTables) {} + LinkerOptTable() : opt::OptTable(optionTables()) {} }; } // namespace diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp index 75530b405c692..265ddee6d8557 100644 --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -751,7 +751,7 @@ MemoryBufferRef LinkerDriver::convertResToCOFF(ArrayRef<MemoryBufferRef> mbs, #define OPTTABLE_CODE #include "Options.inc" -COFFOptTable::COFFOptTable() : OptTable(OptionTables, true) {} +COFFOptTable::COFFOptTable() : OptTable(optionTables(), true) {} // Set color diagnostics according to --color-diagnostics={auto,always,never} // or --no-color-diagnostics flags. diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp index b2c760eeaf3ec..7bee46d8534bf 100644 --- a/lld/ELF/DriverUtils.cpp +++ b/lld/ELF/DriverUtils.cpp @@ -36,7 +36,7 @@ using namespace lld::elf; #define OPTTABLE_CODE #include "Options.inc" -ELFOptTable::ELFOptTable() : OptTable(OptionTables) {} +ELFOptTable::ELFOptTable() : OptTable(optionTables()) {} // Set color diagnostics according to --color-diagnostics={auto,always,never} // or --no-color-diagnostics flags. diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index 9b0f820634ad6..e097d2ce302c3 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -35,7 +35,7 @@ using namespace lld::macho; #define OPTTABLE_CODE #include "Options.inc" -MachOOptTable::MachOOptTable() : OptTable(OptionTables) {} +MachOOptTable::MachOOptTable() : OptTable(optionTables()) {} // Set color diagnostics according to --color-diagnostics={auto,always,never} // or --no-color-diagnostics flags. diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp index b15d06b82146a..53cce5b5c0277 100644 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -64,7 +64,7 @@ enum { namespace { class MinGWOptTable : public opt::OptTable { public: - MinGWOptTable() : opt::OptTable(OptionTables, false) {} + MinGWOptTable() : opt::OptTable(optionTables(), false) {} opt::InputArgList parse(ArrayRef<const char *> argv); }; } // namespace diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index a15c5cf0ad7ed..1de9851d5ed3e 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -151,7 +151,7 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, namespace { class WasmOptTable : public opt::OptTable { public: - WasmOptTable() : opt::OptTable(OptionTables) {} + WasmOptTable() : opt::OptTable(optionTables()) {} opt::InputArgList parse(ArrayRef<const char *> argv); }; } // namespace diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 69894370c07e8..529ec309445cf 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -84,7 +84,7 @@ enum ID { class LLDBOptTable : public opt::OptTable { public: - LLDBOptTable() : opt::OptTable(OptionTables) {} + LLDBOptTable() : opt::OptTable(optionTables()) {} }; } // namespace diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index 7dc367af45199..9444f77ae31ca 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -114,7 +114,7 @@ enum ID { #include "Options.inc" class LLDBDAPOptTable : public llvm::opt::OptTable { public: - LLDBDAPOptTable() : llvm::opt::OptTable(OptionTables, true) {} + LLDBDAPOptTable() : llvm::opt::OptTable(optionTables(), true) {} }; } // anonymous namespace diff --git a/lldb/tools/lldb-server/lldb-gdbserver.cpp b/lldb/tools/lldb-server/lldb-gdbserver.cpp index 853aee10ac4ec..98a79dedf65c0 100644 --- a/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -307,7 +307,7 @@ enum ID { class LLGSOptTable : public opt::OptTable { public: - LLGSOptTable() : opt::OptTable(OptionTables) {} + LLGSOptTable() : opt::OptTable(optionTables()) {} void PrintHelp(llvm::StringRef Name) { std::string Usage = diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp index 8a1e273435d92..29f065c33f409 100644 --- a/lldb/tools/lldb-server/lldb-platform.cpp +++ b/lldb/tools/lldb-server/lldb-platform.cpp @@ -73,7 +73,7 @@ enum ID { class PlatformOptTable : public opt::OptTable { public: - PlatformOptTable() : opt::OptTable(OptionTables) {} + PlatformOptTable() : opt::OptTable(optionTables()) {} void PrintHelp(llvm::StringRef Name) { std::string Usage = diff --git a/llvm/examples/OptSubcommand/llvm-hello-sub.cpp b/llvm/examples/OptSubcommand/llvm-hello-sub.cpp index 485a3bfe89907..bc057002a4b36 100644 --- a/llvm/examples/OptSubcommand/llvm-hello-sub.cpp +++ b/llvm/examples/OptSubcommand/llvm-hello-sub.cpp @@ -24,7 +24,7 @@ enum ID { class HelloSubOptTable : public OptTable { public: - HelloSubOptTable() : OptTable(OptionTables) {}; + HelloSubOptTable() : OptTable(optionTables()) {}; }; } // namespace diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h index 1532f18b105bd..611cfe826a99f 100644 --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -159,7 +159,6 @@ class LLVM_ABI OptTable { struct Tables { const StringTable &StrTable; ArrayRef<StringTable::Offset> PrefixesTable; - ArrayRef<StringTable::Offset> PrefixesUnion; ArrayRef<Info> Infos; ArrayRef<HelpTextVariant> HelpTextVariants; ArrayRef<SubCommand> SubCommands; @@ -252,11 +251,10 @@ class LLVM_ABI OptTable { unsigned &Index) const; protected: - OptTable(const Tables &Tables, bool IgnoreCase = false); - void setValuesCodeFn(ValuesCodeFnTy Fn) { ValuesCodeFn = Fn; } public: + OptTable(const Tables &T, bool IgnoreCase = false); virtual ~OptTable(); /// Return the string table used for option names. diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp index 624ead6a8ea78..6300cfa56f133 100644 --- a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp @@ -17,14 +17,13 @@ using namespace jitlink; #define DEBUG_TYPE "jitlink" -// Create table mapping all options defined in COFFOptions.td using namespace llvm::opt; #define OPTTABLE_CODE #include "COFFOptions.inc" class COFFOptTable : public opt::OptTable { public: - COFFOptTable() : OptTable(OptionTables, true) {} + COFFOptTable() : OptTable(optionTables(), true) {} }; static COFFOptTable optTable; diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index c444235076586..87487d625f7e4 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -78,12 +78,18 @@ OptTable::OptTable(const Tables &T, bool IgnoreCase) OptionInfos(T.Infos), IgnoreCase(IgnoreCase), SubCommands(T.SubCommands), SubCommandIDsTable(T.SubCommandIDs), HelpTextVariantsTable(T.HelpTextVariants) { - for (StringTable::Offset PrefixOffset : T.PrefixesUnion) { - StringRef Prefix = (*StrTable)[PrefixOffset]; - PrefixesUnion.push_back(Prefix); - for (char C : Prefix) - if (!is_contained(PrefixChars, C)) - PrefixChars.push_back(C); + // Each prefix set in PrefixesTable starts with its size. + for (unsigned I = 0, E = PrefixesTable.size(); I != E;) { + unsigned Size = PrefixesTable[I++].value(); + for (unsigned J = 0; J != Size; ++J) { + StringRef Prefix = (*StrTable)[PrefixesTable[I++]]; + if (is_contained(PrefixesUnion, Prefix)) + continue; + PrefixesUnion.push_back(Prefix); + for (char C : Prefix) + if (!is_contained(PrefixChars, C)) + PrefixChars.push_back(C); + } } // Find start of normal options. diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp index cef8f5af611d8..d914b49747c32 100644 --- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp @@ -45,7 +45,7 @@ using namespace llvm::opt; class DllOptTable : public opt::OptTable { public: - DllOptTable() : opt::OptTable(OptionTables, false) {} + DllOptTable() : opt::OptTable(optionTables(), false) {} }; // Opens a file. Path has to be resolved already. diff --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp index 0cae27d4c2765..55e59aa6ac12d 100644 --- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp @@ -50,7 +50,7 @@ using namespace llvm::opt; class LibOptTable : public opt::OptTable { public: - LibOptTable() : opt::OptTable(OptionTables, true) {} + LibOptTable() : opt::OptTable(optionTables(), true) {} }; } // namespace diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 9adf846d1e1a3..0b30d3512d8d2 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -74,7 +74,7 @@ using namespace llvm::opt; class DsymutilOptTable : public opt::OptTable { public: - DsymutilOptTable() : opt::OptTable(OptionTables) {} + DsymutilOptTable() : opt::OptTable(optionTables()) {} }; } // namespace diff --git a/llvm/tools/llvm-cas/llvm-cas.cpp b/llvm/tools/llvm-cas/llvm-cas.cpp index 7ed4f4fc0846a..d4d79336b5d75 100644 --- a/llvm/tools/llvm-cas/llvm-cas.cpp +++ b/llvm/tools/llvm-cas/llvm-cas.cpp @@ -39,7 +39,7 @@ using namespace llvm::opt; class LLVMCASOptTable : public opt::OptTable { public: - LLVMCASOptTable() : opt::OptTable(OptionTables) {} + LLVMCASOptTable() : opt::OptTable(optionTables()) {} }; enum class CommandKind { diff --git a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp index 472805ec06053..f06119a24e6ff 100644 --- a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp +++ b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp @@ -57,7 +57,7 @@ using namespace llvm::opt; class CGDataOptTable : public opt::OptTable { public: - CGDataOptTable() : OptTable(OptionTables) {} + CGDataOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp index a6f1d42f433e9..e13c66c9ab1a7 100644 --- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp +++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp @@ -48,7 +48,7 @@ using namespace llvm::opt; class CvtResOptTable : public opt::OptTable { public: - CvtResOptTable() : opt::OptTable(OptionTables, true) {} + CvtResOptTable() : opt::OptTable(optionTables(), true) {} }; } diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp index 6584da5f9f41f..457623561e241 100644 --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -37,7 +37,7 @@ using namespace llvm::opt; class CxxfiltOptTable : public opt::OptTable { public: - CxxfiltOptTable() : opt::OptTable(OptionTables) { + CxxfiltOptTable() : opt::OptTable(optionTables()) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp index 447038f1601d7..483b14a841083 100644 --- a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp +++ b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp @@ -43,7 +43,7 @@ using namespace llvm::opt; class DebuginfodFindOptTable : public opt::OptTable { public: - DebuginfodFindOptTable() : OptTable(OptionTables) {} + DebuginfodFindOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp index 60c4ba164bc82..1ecb6e8c4bd3d 100644 --- a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp +++ b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp @@ -42,7 +42,7 @@ using namespace llvm::opt; class DebuginfodOptTable : public opt::OptTable { public: - DebuginfodOptTable() : OptTable(OptionTables) {} + DebuginfodOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp index 0d40bb7d75b79..2176db14f06f4 100644 --- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp +++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp @@ -45,7 +45,7 @@ using namespace llvm::opt; class DwarfutilOptTable : public opt::OptTable { public: - DwarfutilOptTable() : opt::OptTable(OptionTables) {} + DwarfutilOptTable() : opt::OptTable(optionTables()) {} }; } // namespace diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp index c24164e3846e2..fac0051aa76e9 100644 --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -40,7 +40,7 @@ using namespace llvm::opt; class DwpOptTable : public opt::OptTable { public: - DwpOptTable() : OptTable(OptionTables) {} + DwpOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp index 386af5186077e..e168c8141def9 100644 --- a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp +++ b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp @@ -75,7 +75,9 @@ enum ID { class GSYMUtilOptTable : public llvm::opt::OptTable { public: - GSYMUtilOptTable() : OptTable(OptionTables) { setGroupedShortOptions(true); } + GSYMUtilOptTable() : OptTable(optionTables()) { + setGroupedShortOptions(true); + } }; static bool Verbose; diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index 35f08b62ebacc..575a1117363fe 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -63,7 +63,9 @@ enum ID { class IFSOptTable : public opt::OptTable { public: - IFSOptTable() : opt::OptTable(OptionTables) { setGroupedShortOptions(true); } + IFSOptTable() : opt::OptTable(optionTables()) { + setGroupedShortOptions(true); + } }; struct DriverConfig { diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp index ad3af47de7dde..b2e02173ee3b4 100644 --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -53,7 +53,7 @@ enum ID { class LibtoolDarwinOptTable : public opt::OptTable { public: - LibtoolDarwinOptTable() : OptTable(OptionTables) {} + LibtoolDarwinOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp index 486321657c3af..c5dd60d1107ad 100644 --- a/llvm/tools/llvm-lipo/llvm-lipo.cpp +++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp @@ -77,7 +77,7 @@ using namespace llvm::opt; class LipoOptTable : public opt::OptTable { public: - LipoOptTable() : opt::OptTable(lipo::OptionTables) {} + LipoOptTable() : opt::OptTable(lipo::optionTables()) {} }; enum class LipoAction { diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp index c6ce99cfc4da7..2a4e0537579d3 100644 --- a/llvm/tools/llvm-ml/llvm-ml.cpp +++ b/llvm/tools/llvm-ml/llvm-ml.cpp @@ -64,7 +64,7 @@ enum ID { class MLOptTable : public opt::OptTable { public: - MLOptTable() : opt::OptTable(OptionTables, /*IgnoreCase=*/false) {} + MLOptTable() : opt::OptTable(optionTables(), /*IgnoreCase=*/false) {} }; } // namespace diff --git a/llvm/tools/llvm-mt/llvm-mt.cpp b/llvm/tools/llvm-mt/llvm-mt.cpp index 3e651cf56e719..9e781ad2fedb3 100644 --- a/llvm/tools/llvm-mt/llvm-mt.cpp +++ b/llvm/tools/llvm-mt/llvm-mt.cpp @@ -46,7 +46,7 @@ using namespace llvm::opt; class CvtResOptTable : public opt::OptTable { public: - CvtResOptTable() : opt::OptTable(OptionTables, true) {} + CvtResOptTable() : opt::OptTable(optionTables(), true) {} }; } // namespace diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index 2e9f865675234..e4e4dc6c83083 100644 --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -72,7 +72,7 @@ enum ID { class NmOptTable : public opt::OptTable { public: - NmOptTable() : opt::OptTable(OptionTables) { setGroupedShortOptions(true); } + NmOptTable() : opt::OptTable(optionTables()) { setGroupedShortOptions(true); } }; enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols }; diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index 0bbaf95660329..4c0f9d1d09daf 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -46,7 +46,7 @@ namespace objcopy_opt { class ObjcopyOptTable : public opt::OptTable { public: - ObjcopyOptTable() : opt::OptTable(objcopy_opt::OptionTables) { + ObjcopyOptTable() : opt::OptTable(objcopy_opt::optionTables()) { setGroupedShortOptions(true); setDashDashParsing(true); } @@ -67,7 +67,7 @@ namespace install_name_tool { class InstallNameToolOptTable : public opt::OptTable { public: - InstallNameToolOptTable() : OptTable(install_name_tool::OptionTables) {} + InstallNameToolOptTable() : OptTable(install_name_tool::optionTables()) {} }; enum BitcodeStripID { @@ -85,7 +85,7 @@ namespace bitcode_strip { class BitcodeStripOptTable : public opt::OptTable { public: - BitcodeStripOptTable() : opt::OptTable(bitcode_strip::OptionTables) {} + BitcodeStripOptTable() : opt::OptTable(bitcode_strip::optionTables()) {} }; enum StripID { @@ -102,7 +102,7 @@ namespace strip { class StripOptTable : public opt::OptTable { public: - StripOptTable() : OptTable(strip::OptionTables) { + StripOptTable() : OptTable(strip::optionTables()) { setGroupedShortOptions(true); } }; @@ -122,7 +122,8 @@ namespace extract_bundle_entry { class ExtractBundleEntryOptTable : public opt::OptTable { public: - ExtractBundleEntryOptTable() : OptTable(extract_bundle_entry::OptionTables) { + ExtractBundleEntryOptTable() + : OptTable(extract_bundle_entry::optionTables()) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 77aac37506d4f..ed45af32fbd8f 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -121,7 +121,7 @@ namespace objdump_opt { class ObjdumpOptTable : public CommonOptTable { public: ObjdumpOptTable() - : CommonOptTable(objdump_opt::OptionTables, + : CommonOptTable(objdump_opt::optionTables(), " [options] <input object files>", "llvm object file dumper") {} }; @@ -141,7 +141,7 @@ namespace otool { class OtoolOptTable : public CommonOptTable { public: OtoolOptTable() - : CommonOptTable(otool::OptionTables, " [option...] [file...]", + : CommonOptTable(otool::optionTables(), " [option...] [file...]", "Mach-O object file displaying tool") {} }; diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp index a091ae5ec6b5b..7be5b16dce3ba 100644 --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -63,7 +63,7 @@ namespace rc_opt { class RcOptTable : public opt::OptTable { public: - RcOptTable() : OptTable(rc_opt::OptionTables, /* IgnoreCase = */ true) {} + RcOptTable() : OptTable(rc_opt::optionTables(), /* IgnoreCase = */ true) {} }; enum Windres_ID { @@ -81,7 +81,7 @@ namespace windres_opt { class WindresOptTable : public opt::OptTable { public: WindresOptTable() - : OptTable(windres_opt::OptionTables, /* IgnoreCase = */ false) {} + : OptTable(windres_opt::optionTables(), /* IgnoreCase = */ false) {} }; static ExitOnError ExitOnErr; diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index 51f2fb326863f..6ec0563d6d327 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -64,7 +64,7 @@ enum ID { class ReadobjOptTable : public opt::OptTable { public: - ReadobjOptTable() : opt::OptTable(OptionTables) { + ReadobjOptTable() : opt::OptTable(optionTables()) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp index aea79e3c0872e..f032e90401d10 100644 --- a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp +++ b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp @@ -50,7 +50,9 @@ enum ID { class TAPIOptTable : public opt::OptTable { public: - TAPIOptTable() : opt::OptTable(OptionTables) { setGroupedShortOptions(true); } + TAPIOptTable() : opt::OptTable(optionTables()) { + setGroupedShortOptions(true); + } }; struct StubOptions { diff --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp index b58306c780f82..66195fdbe4f56 100644 --- a/llvm/tools/llvm-size/llvm-size.cpp +++ b/llvm/tools/llvm-size/llvm-size.cpp @@ -50,7 +50,7 @@ enum ID { class SizeOptTable : public opt::OptTable { public: - SizeOptTable() : OptTable(OptionTables) { setGroupedShortOptions(true); } + SizeOptTable() : OptTable(optionTables()) { setGroupedShortOptions(true); } }; enum OutputFormatTy { berkeley, sysv, darwin }; diff --git a/llvm/tools/llvm-strings/llvm-strings.cpp b/llvm/tools/llvm-strings/llvm-strings.cpp index 04c0f3a16454b..f2abd1c3271a8 100644 --- a/llvm/tools/llvm-strings/llvm-strings.cpp +++ b/llvm/tools/llvm-strings/llvm-strings.cpp @@ -44,7 +44,7 @@ using namespace llvm::opt; class StringsOptTable : public opt::OptTable { public: - StringsOptTable() : OptTable(OptionTables) { + StringsOptTable() : OptTable(optionTables()) { setGroupedShortOptions(true); setDashDashParsing(true); } diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index a820126cf265c..c82cb11ade1ca 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -62,7 +62,7 @@ using namespace llvm::opt; class SymbolizerOptTable : public opt::OptTable { public: - SymbolizerOptTable() : OptTable(OptionTables) { + SymbolizerOptTable() : OptTable(optionTables()) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp index 1b045d7291cf3..8e67d1a087d22 100644 --- a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp +++ b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp @@ -39,7 +39,7 @@ using namespace llvm::opt; class TLICheckerOptTable : public opt::OptTable { public: - TLICheckerOptTable() : OptTable(OptionTables) {} + TLICheckerOptTable() : OptTable(optionTables()) {} }; } // end anonymous namespace diff --git a/llvm/tools/sancov/sancov.cpp b/llvm/tools/sancov/sancov.cpp index 0d91ffb798bcb..2d20caee8355a 100644 --- a/llvm/tools/sancov/sancov.cpp +++ b/llvm/tools/sancov/sancov.cpp @@ -73,7 +73,7 @@ enum ID { class SancovOptTable : public opt::OptTable { public: - SancovOptTable() : OptTable(OptionTables) {} + SancovOptTable() : OptTable(optionTables()) {} }; } // namespace diff --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp index 382de8ee7a195..6b45ea5ea8aa7 100644 --- a/llvm/unittests/Option/OptionParsingTest.cpp +++ b/llvm/unittests/Option/OptionParsingTest.cpp @@ -48,7 +48,7 @@ enum OptionVisibility { namespace { class TestOptTable : public OptTable { public: - TestOptTable(bool IgnoreCase = false) : OptTable(OptionTables, IgnoreCase) { + TestOptTable(bool IgnoreCase = false) : OptTable(optionTables(), IgnoreCase) { setValuesCodeFn(getOptionValuesCode); } }; diff --git a/llvm/unittests/Option/OptionSubCommandsTest.cpp b/llvm/unittests/Option/OptionSubCommandsTest.cpp index 8885ee2f83668..27405beeec0ef 100644 --- a/llvm/unittests/Option/OptionSubCommandsTest.cpp +++ b/llvm/unittests/Option/OptionSubCommandsTest.cpp @@ -37,7 +37,7 @@ enum ID { class TestOptSubCommandTable : public OptTable { public: TestOptSubCommandTable(bool IgnoreCase = false) - : OptTable(OptionTables, IgnoreCase) {} + : OptTable(optionTables(), IgnoreCase) {} }; // Test fixture diff --git a/llvm/utils/TableGen/OptionParserEmitter.cpp b/llvm/utils/TableGen/OptionParserEmitter.cpp index e4a3313e67a42..4fa18551f79d3 100644 --- a/llvm/utils/TableGen/OptionParserEmitter.cpp +++ b/llvm/utils/TableGen/OptionParserEmitter.cpp @@ -282,17 +282,10 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { SubCommandIDs.try_emplace(SubCommandKey, 0); } - DenseSet<StringRef> PrefixesUnionSet; - for (const auto &[Prefix, _] : Prefixes) - PrefixesUnionSet.insert_range(Prefix); - SmallVector<StringRef> PrefixesUnion(PrefixesUnionSet.begin(), - PrefixesUnionSet.end()); - array_pod_sort(PrefixesUnion.begin(), PrefixesUnion.end()); - llvm::StringToOffsetTable Table; - // We can add all the prefixes via the union. - for (const auto &Prefix : PrefixesUnion) - Table.GetOrAddStringOffset(Prefix); + for (const auto &[PrefixSet, _] : Prefixes) + for (const auto &Prefix : PrefixSet) + Table.GetOrAddStringOffset(Prefix); for (const Record &R : llvm::make_pointee_range(Groups)) { Table.GetOrAddStringOffset(R.getValueAsString("Name")); Table.GetOrAddStringOffset(getHelpText(R)); @@ -370,17 +363,6 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { } OS << "\n};\n\n"; - // Dump prefixes union. - if (!PrefixesUnion.empty()) { - OS << "static constexpr llvm::StringTable::Offset OptionPrefixesUnion[] = " - "{\n"; - llvm::ListSeparator Sep(", "); - for (auto Prefix : PrefixesUnion) - OS << Sep << " " << *Table.GetStringOffset(Prefix) << " /* '" << Prefix - << "' */"; - OS << "\n};\n\n"; - } - // Dump help text variants. Each option's variants form a run ended by a zero // row; offset 0 is the empty run. OS << "static constexpr llvm::opt::OptTable::HelpTextVariant " @@ -489,13 +471,13 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { } OS << "};\n\n"; - OS << "static constexpr llvm::opt::OptTable::Tables OptionTables = {\n"; - OS << " OptionStrTable, OptionPrefixesTable, " - << (PrefixesUnion.empty() ? "{}" : "OptionPrefixesUnion") - << ", OptionInfoTable,\n"; - OS << " OptionHelpTextVariantsTable, " + // A function rather than an object: the object needs relocations. + OS << "static constexpr llvm::opt::OptTable::Tables optionTables() {\n"; + OS << " return {OptionStrTable, OptionPrefixesTable, OptionInfoTable,\n"; + OS << " OptionHelpTextVariantsTable, " << (SubCommands.empty() ? "{}" : "OptionSubCommands") << ", OptionSubCommandIDsTable};\n"; + OS << "}\n"; OS << "#undef OPTTABLE_CODE\n"; OS << "#endif // OPTTABLE_CODE\n\n"; >From e280d307f51de86a856fc4897f63544f16202e27 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Fri, 18 Sep 2026 22:25:27 -0700 Subject: [PATCH 2/3] OptTables() -> optTables() --- llvm/utils/TableGen/OptionParserEmitter.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/llvm/utils/TableGen/OptionParserEmitter.cpp b/llvm/utils/TableGen/OptionParserEmitter.cpp index 4fa18551f79d3..59a681ff2dd52 100644 --- a/llvm/utils/TableGen/OptionParserEmitter.cpp +++ b/llvm/utils/TableGen/OptionParserEmitter.cpp @@ -339,8 +339,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { OS << "#ifdef OPTTABLE_CODE\n"; // Dump prefixes. - OS << "static constexpr llvm::StringTable::Offset OptionPrefixesTable[] = " - "{\n"; + OS << "constexpr llvm::StringTable::Offset OptionPrefixesTable[] = {\n"; { // Ensure the first prefix set is always empty. assert(!Prefixes.empty() && @@ -365,7 +364,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { // Dump help text variants. Each option's variants form a run ended by a zero // row; offset 0 is the empty run. - OS << "static constexpr llvm::opt::OptTable::HelpTextVariant " + OS << "constexpr llvm::opt::OptTable::HelpTextVariant " "OptionHelpTextVariantsTable[] = {\n"; DenseMap<const Record *, unsigned> HelpTextVariantsOffset; unsigned NumVariantRows = 1; @@ -395,8 +394,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { // Dump subcommands. if (!SubCommands.empty()) { - OS << "static constexpr llvm::opt::OptTable::SubCommand " - "OptionSubCommands[] = {\n"; + OS << "constexpr llvm::opt::OptTable::SubCommand OptionSubCommands[] = {\n"; for (const Record *SubCommand : SubCommands) { OS << " { \"" << SubCommand->getValueAsString("Name") << "\", "; OS << "\"" << SubCommand->getValueAsString("HelpText") << "\", "; @@ -406,7 +404,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { } // Dump subcommand IDs. - OS << "static constexpr unsigned OptionSubCommandIDsTable[] = {\n"; + OS << "constexpr unsigned OptionSubCommandIDsTable[] = {\n"; { // Ensure the first subcommand set is always empty. assert(!SubCommandIDs.empty() && @@ -436,7 +434,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { OS << "\n};\n\n"; // Dump the option table in OptTable::Info field order. - OS << "static constexpr llvm::opt::OptTable::Info OptionInfoTable[] = {\n"; + OS << "constexpr llvm::opt::OptTable::Info OptionInfoTable[] = {\n"; for (const Record &R : llvm::make_pointee_range(Groups)) { OS << " {"; writeStrTableOffset(OS, Table, R.getValueAsString("Name"), >From c6f103149a5e5bf45945e16694df651b443793c8 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Fri, 18 Sep 2026 22:27:10 -0700 Subject: [PATCH 3/3] clarify comments --- llvm/utils/TableGen/OptionParserEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/utils/TableGen/OptionParserEmitter.cpp b/llvm/utils/TableGen/OptionParserEmitter.cpp index 59a681ff2dd52..88a1b57c2f6b2 100644 --- a/llvm/utils/TableGen/OptionParserEmitter.cpp +++ b/llvm/utils/TableGen/OptionParserEmitter.cpp @@ -469,7 +469,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { } OS << "};\n\n"; - // A function rather than an object: the object needs relocations. + // A function rather than an object: the object needs dynamic relocations. OS << "static constexpr llvm::opt::OptTable::Tables optionTables() {\n"; OS << " return {OptionStrTable, OptionPrefixesTable, OptionInfoTable,\n"; OS << " OptionHelpTextVariantsTable, " _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
