diff --git a/clang/lib/Driver/DriverOptions.cpp b/clang/lib/Driver/DriverOptions.cpp --- a/clang/lib/Driver/DriverOptions.cpp +++ b/clang/lib/Driver/DriverOptions.cpp @@ -27,6 +27,14 @@ #include "clang/Driver/Options.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "clang/Driver/Options.inc" +#undef PREFIX_UNION + ; +static constexpr const llvm::ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -40,8 +48,7 @@ class DriverOptTable : public OptTable { public: - DriverOptTable() - : OptTable(InfoTable) {} + DriverOptTable() : OptTable(InfoTable, PrefixTable) {} }; } diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -128,6 +128,15 @@ #include "LinkerWrapperOpts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "LinkerWrapperOpts.inc" +#undef PREFIX_UNION + ; + +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -139,7 +148,7 @@ class WrapperOptTable : public opt::OptTable { public: - WrapperOptTable() : OptTable(InfoTable) {} + WrapperOptTable() : OptTable(InfoTable, PrefixTable) {} }; const OptTable &getOptTable() { diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -779,6 +779,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + // Create table mapping all options defined in Options.td static constexpr llvm::opt::OptTable::Info infoTable[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ @@ -788,7 +796,7 @@ #undef OPTION }; -COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {} +COFFOptTable::COFFOptTable() : OptTable(infoTable, PrefixTable, true) {} COFFOptTable optTable; diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp --- a/lld/ELF/DriverUtils.cpp +++ b/lld/ELF/DriverUtils.cpp @@ -41,6 +41,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + // Create table mapping all options defined in Options.td static constexpr opt::OptTable::Info optInfo[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ @@ -50,7 +58,7 @@ #undef OPTION }; -ELFOptTable::ELFOptTable() : OptTable(optInfo) {} +ELFOptTable::ELFOptTable() : OptTable(optInfo, PrefixTable) {} // 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 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -42,6 +42,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + // Create table mapping all options defined in Options.td static constexpr OptTable::Info optInfo[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ @@ -51,7 +59,7 @@ #undef OPTION }; -MachOOptTable::MachOOptTable() : OptTable(optInfo) {} +MachOOptTable::MachOOptTable() : OptTable(optInfo, PrefixTable) {} // 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 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -69,6 +69,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const llvm::ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + // Create table mapping all options defined in Options.td static constexpr opt::OptTable::Info infoTable[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ @@ -81,7 +89,7 @@ namespace { class MinGWOptTable : public opt::OptTable { public: - MinGWOptTable() : OptTable(infoTable, false) {} + MinGWOptTable() : OptTable(infoTable, PrefixTable, false) {} opt::InputArgList parse(ArrayRef argv); }; } // namespace diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -109,6 +109,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + // Create table mapping all options defined in Options.td static constexpr opt::OptTable::Info optInfo[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ @@ -121,7 +129,7 @@ namespace { class WasmOptTable : public llvm::opt::OptTable { public: - WasmOptTable() : OptTable(optInfo) {} + WasmOptTable() : OptTable(optInfo, PrefixTable) {} opt::InputArgList parse(ArrayRef argv); }; } // namespace diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -66,6 +66,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -80,7 +88,7 @@ class LLDBOptTable : public opt::OptTable { public: - LLDBOptTable() : OptTable(InfoTable) {} + LLDBOptTable() : OptTable(InfoTable, PrefixTable) {} }; } // namespace diff --git a/lldb/tools/lldb-server/lldb-gdbserver.cpp b/lldb/tools/lldb-server/lldb-gdbserver.cpp --- a/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -285,6 +285,14 @@ #include "LLGSOptions.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "LLGSOptions.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -299,7 +307,7 @@ class LLGSOptTable : public opt::OptTable { public: - LLGSOptTable() : OptTable(InfoTable) {} + LLGSOptTable() : OptTable(InfoTable, PrefixTable) {} void PrintHelp(llvm::StringRef Name) { std::string Usage = diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp --- a/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -86,6 +86,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const llvm::ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr llvm::opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -98,7 +106,7 @@ }; class LLDBVSCodeOptTable : public llvm::opt::OptTable { public: - LLDBVSCodeOptTable() : OptTable(InfoTable, true) {} + LLDBVSCodeOptTable() : OptTable(InfoTable, PrefixTable, true) {} }; typedef void (*RequestCallback)(const llvm::json::Object &command); diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -74,7 +74,7 @@ /// The union of all option prefixes. If an argument does not begin with /// one of these, it is an input. - StringSet<> PrefixesUnion; + ArrayRef PrefixesUnion; SmallString<8> PrefixChars; private: @@ -88,7 +88,8 @@ unsigned &Index) const; protected: - OptTable(ArrayRef OptionInfos, bool IgnoreCase = false); + OptTable(ArrayRef OptionInfos, ArrayRef PrefixesTable, + bool IgnoreCase = false); public: ~OptTable(); diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp --- a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp @@ -27,6 +27,14 @@ #include "COFFOptions.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "COFFOptions.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + // Create table mapping all options defined in COFFOptions.td static constexpr opt::OptTable::Info infoTable[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ @@ -48,7 +56,7 @@ class COFFOptTable : public opt::OptTable { public: - COFFOptTable() : OptTable(infoTable, true) {} + COFFOptTable() : OptTable(infoTable, PrefixTable, true) {} }; static COFFOptTable optTable; diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -85,8 +85,10 @@ OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {} -OptTable::OptTable(ArrayRef OptionInfos, bool IgnoreCase) - : OptionInfos(OptionInfos), IgnoreCase(IgnoreCase) { +OptTable::OptTable(ArrayRef OptionInfos, + ArrayRef PrefixesTable, bool IgnoreCase) + : OptionInfos(OptionInfos), IgnoreCase(IgnoreCase), + PrefixesUnion(PrefixesTable) { // Explicitly zero initialize the error to work around a bug in array // value-initialization on MinGW with gcc 4.3.5. @@ -126,15 +128,8 @@ } #endif - // Build prefixes. - for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions() + 1; - i != e; ++i) { - const auto &P = getInfo(i).Prefixes; - PrefixesUnion.insert(P.begin(), P.end()); - } - // Build prefix chars. - for (const StringRef &Prefix : PrefixesUnion.keys()) { + for (const StringLiteral &Prefix : PrefixesUnion) { for (char C : Prefix) if (!is_contained(PrefixChars, C)) PrefixChars.push_back(C); @@ -151,10 +146,10 @@ return Option(&getInfo(id), this); } -static bool isInput(const StringSet<> &Prefixes, StringRef Arg) { +static bool isInput(const ArrayRef &Prefixes, StringRef Arg) { if (Arg == "-") return true; - for (const StringRef &Prefix : Prefixes.keys()) + for (const StringRef &Prefix : Prefixes) if (Arg.startswith(Prefix)) return false; return true; @@ -236,6 +231,9 @@ // Consider each [option prefix + option name] pair as a candidate, finding // the closest match. unsigned BestDistance = UINT_MAX; + SmallString<16> Candidate; + SmallString<16> NormalizedName; + for (const Info &CandidateInfo : ArrayRef(OptionInfos).drop_front(FirstSearchableIndex)) { StringRef CandidateName = CandidateInfo.Name; @@ -243,7 +241,7 @@ // We can eliminate some option prefix/name pairs as candidates right away: // * Ignore option candidates with empty names, such as "--", or names // that do not meet the minimum length. - if (CandidateName.empty() || CandidateName.size() < MinimumLength) + if (CandidateName.size() < MinimumLength) continue; // * If FlagsToInclude were specified, ignore options that don't include @@ -262,26 +260,25 @@ // Now check if the candidate ends with a character commonly used when // delimiting an option from its value, such as '=' or ':'. If it does, // attempt to split the given option based on that delimiter. - StringRef LHS, RHS; char Last = CandidateName.back(); bool CandidateHasDelimiter = Last == '=' || Last == ':'; - std::string NormalizedName = std::string(Option); + StringRef RHS; if (CandidateHasDelimiter) { - std::tie(LHS, RHS) = Option.split(Last); - NormalizedName = std::string(LHS); - if (Option.find(Last) == LHS.size()) + std::tie(NormalizedName, RHS) = Option.split(Last); + if (Option.find(Last) == NormalizedName.size()) NormalizedName += Last; - } + } else + NormalizedName = Option; // Consider each possible prefix for each candidate to find the most // appropriate one. For example, if a user asks for "--helm", suggest // "--help" over "-help". for (auto CandidatePrefix : CandidateInfo.Prefixes) { - std::string Candidate = (CandidatePrefix + CandidateName).str(); - StringRef CandidateRef = Candidate; - unsigned Distance = - CandidateRef.edit_distance(NormalizedName, /*AllowReplacements=*/true, - /*MaxEditDistance=*/BestDistance); + Candidate = CandidatePrefix; + Candidate += CandidateName; + unsigned Distance = StringRef(Candidate).edit_distance( + NormalizedName, /*AllowReplacements=*/true, + /*MaxEditDistance=*/BestDistance); if (RHS.empty() && CandidateHasDelimiter) { // The Candidate ends with a = or : delimiter, but the option passed in // didn't contain the delimiter (or doesn't have anything after it). diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp --- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp @@ -44,6 +44,15 @@ #include "Options.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; + +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \ @@ -54,7 +63,7 @@ class DllOptTable : public llvm::opt::OptTable { public: - DllOptTable() : OptTable(InfoTable, false) {} + DllOptTable() : OptTable(InfoTable, PrefixTable, 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 --- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp @@ -48,6 +48,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ @@ -58,7 +66,7 @@ class LibOptTable : public opt::OptTable { public: - LibOptTable() : OptTable(InfoTable, true) {} + LibOptTable() : OptTable(InfoTable, PrefixTable, true) {} }; } diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -70,6 +70,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -84,7 +92,7 @@ class DsymutilOptTable : public opt::OptTable { public: - DsymutilOptTable() : OptTable(InfoTable) {} + DsymutilOptTable() : OptTable(InfoTable, PrefixTable) {} }; } // namespace diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp --- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp +++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp @@ -51,6 +51,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -65,7 +73,7 @@ class CvtResOptTable : public opt::OptTable { public: - CvtResOptTable() : OptTable(InfoTable, true) {} + CvtResOptTable() : OptTable(InfoTable, PrefixTable, true) {} }; } diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -39,6 +39,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -53,7 +61,9 @@ class CxxfiltOptTable : public opt::OptTable { public: - CxxfiltOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + CxxfiltOptTable() : OptTable(InfoTable, PrefixTable) { + setGroupedShortOptions(true); + } }; } // namespace diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp --- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp +++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp @@ -47,6 +47,14 @@ #include "Options.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Options.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -61,7 +69,7 @@ class DwarfutilOptTable : public opt::OptTable { public: - DwarfutilOptTable() : OptTable(InfoTable) {} + DwarfutilOptTable() : OptTable(InfoTable, PrefixTable) {} }; } // namespace diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -67,6 +67,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -81,7 +89,9 @@ class IFSOptTable : public opt::OptTable { public: - IFSOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + IFSOptTable() : OptTable(InfoTable, PrefixTable) { + setGroupedShortOptions(true); + } }; struct DriverConfig { diff --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp --- a/llvm/tools/llvm-lipo/llvm-lipo.cpp +++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp @@ -81,6 +81,14 @@ #include "LipoOpts.inc" #undef PREFIX +static constexpr const StringLiteral LipoPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "LipoOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + LipoPrefixTable(LipoPrefixTable_init, std::size(LipoPrefixTable_init) - 1); + static constexpr opt::OptTable::Info LipoInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -95,7 +103,7 @@ class LipoOptTable : public opt::OptTable { public: - LipoOptTable() : OptTable(lipo::LipoInfoTable) {} + LipoOptTable() : OptTable(lipo::LipoInfoTable, lipo::LipoPrefixTable) {} }; enum class LipoAction { diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp --- a/llvm/tools/llvm-ml/llvm-ml.cpp +++ b/llvm/tools/llvm-ml/llvm-ml.cpp @@ -67,6 +67,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -81,7 +89,7 @@ class MLOptTable : public opt::OptTable { public: - MLOptTable() : OptTable(InfoTable, /*IgnoreCase=*/false) {} + MLOptTable() : OptTable(InfoTable, PrefixTable, /*IgnoreCase=*/false) {} }; } // namespace diff --git a/llvm/tools/llvm-mt/llvm-mt.cpp b/llvm/tools/llvm-mt/llvm-mt.cpp --- a/llvm/tools/llvm-mt/llvm-mt.cpp +++ b/llvm/tools/llvm-mt/llvm-mt.cpp @@ -48,6 +48,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -62,7 +70,7 @@ class CvtResOptTable : public opt::OptTable { public: - CvtResOptTable() : OptTable(InfoTable, true) {} + CvtResOptTable() : OptTable(InfoTable, PrefixTable, true) {} }; } // namespace diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -71,6 +71,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -85,7 +93,9 @@ class NmOptTable : public opt::OptTable { public: - NmOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + NmOptTable() : OptTable(InfoTable, PrefixTable) { + 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 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -44,6 +44,15 @@ #include "ObjcopyOpts.inc" #undef PREFIX +static constexpr const StringLiteral ObjcopyPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "ObjcopyOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + ObjcopyPrefixTable(ObjcopyPrefixTable_init, + std::size(ObjcopyPrefixTable_init) - 1); + static constexpr opt::OptTable::Info ObjcopyInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -58,7 +67,9 @@ class ObjcopyOptTable : public opt::OptTable { public: - ObjcopyOptTable() : OptTable(objcopy_opt::ObjcopyInfoTable) { + ObjcopyOptTable() + : OptTable(objcopy_opt::ObjcopyInfoTable, + objcopy_opt::ObjcopyPrefixTable) { setGroupedShortOptions(true); } }; @@ -81,6 +92,15 @@ #include "InstallNameToolOpts.inc" #undef PREFIX +static constexpr const StringLiteral InstallNameToolPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "InstallNameToolOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + InstallNameToolPrefixTable(InstallNameToolPrefixTable_init, + std::size(InstallNameToolPrefixTable_init) - 1); + static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -104,7 +124,8 @@ class InstallNameToolOptTable : public opt::OptTable { public: InstallNameToolOptTable() - : OptTable(install_name_tool::InstallNameToolInfoTable) {} + : OptTable(install_name_tool::InstallNameToolInfoTable, + install_name_tool::InstallNameToolPrefixTable) {} }; enum BitcodeStripID { @@ -125,6 +146,15 @@ #include "BitcodeStripOpts.inc" #undef PREFIX +static constexpr const StringLiteral BitcodeStripPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "BitcodeStripOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + BitcodeStripPrefixTable(BitcodeStripPrefixTable_init, + std::size(BitcodeStripPrefixTable_init) - 1); + static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -147,7 +177,9 @@ class BitcodeStripOptTable : public opt::OptTable { public: - BitcodeStripOptTable() : OptTable(bitcode_strip::BitcodeStripInfoTable) {} + BitcodeStripOptTable() + : OptTable(bitcode_strip::BitcodeStripInfoTable, + bitcode_strip::BitcodeStripPrefixTable) {} }; enum StripID { @@ -167,6 +199,15 @@ #include "StripOpts.inc" #undef PREFIX +static constexpr const StringLiteral StripPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "StripOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + StripPrefixTable(StripPrefixTable_init, + std::size(StripPrefixTable_init) - 1); + static constexpr opt::OptTable::Info StripInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -181,7 +222,7 @@ class StripOptTable : public opt::OptTable { public: - StripOptTable() : OptTable(strip::StripInfoTable) { + StripOptTable() : OptTable(strip::StripInfoTable, strip::StripPrefixTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -99,9 +99,11 @@ class CommonOptTable : public opt::OptTable { public: - CommonOptTable(ArrayRef OptionInfos, const char *Usage, + CommonOptTable(ArrayRef OptionInfos, + ArrayRef PrefixTable, const char *Usage, const char *Description) - : OptTable(OptionInfos), Usage(Usage), Description(Description) { + : OptTable(OptionInfos, PrefixTable), Usage(Usage), + Description(Description) { setGroupedShortOptions(true); } @@ -127,6 +129,15 @@ #include "ObjdumpOpts.inc" #undef PREFIX +static constexpr const StringLiteral ObjdumpPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "ObjdumpOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + ObjdumpPrefixTable(ObjdumpPrefixTable_init, + std::size(ObjdumpPrefixTable_init) - 1); + static constexpr opt::OptTable::Info ObjdumpInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -142,9 +153,9 @@ class ObjdumpOptTable : public CommonOptTable { public: ObjdumpOptTable() - : CommonOptTable(objdump_opt::ObjdumpInfoTable, - " [options] ", - "llvm object file dumper") {} + : CommonOptTable( + objdump_opt::ObjdumpInfoTable, objdump_opt::ObjdumpPrefixTable, + " [options] ", "llvm object file dumper") {} }; enum OtoolOptID { @@ -164,6 +175,15 @@ #include "OtoolOpts.inc" #undef PREFIX +static constexpr const StringLiteral OtoolPrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "OtoolOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + OtoolPrefixTable(OtoolPrefixTable_init, + std::size(OtoolPrefixTable_init) - 1); + static constexpr opt::OptTable::Info OtoolInfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -179,7 +199,8 @@ class OtoolOptTable : public CommonOptTable { public: OtoolOptTable() - : CommonOptTable(otool::OtoolInfoTable, " [option...] [file...]", + : CommonOptTable(otool::OtoolInfoTable, otool::OtoolPrefixTable, + " [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 --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -63,6 +63,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -78,7 +86,9 @@ class RcOptTable : public opt::OptTable { public: - RcOptTable() : OptTable(rc_opt::InfoTable, /* IgnoreCase = */ true) {} + RcOptTable() + : OptTable(rc_opt::InfoTable, rc_opt::PrefixTable, + /* IgnoreCase = */ true) {} }; enum Windres_ID { @@ -98,6 +108,14 @@ #include "WindresOpts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "WindresOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -113,7 +131,8 @@ class WindresOptTable : public opt::OptTable { public: WindresOptTable() - : OptTable(windres_opt::InfoTable, /* IgnoreCase = */ false) {} + : OptTable(windres_opt::InfoTable, windres_opt::PrefixTable, + /* IgnoreCase = */ false) {} }; static ExitOnError ExitOnErr; diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -68,6 +68,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -82,7 +90,9 @@ class ReadobjOptTable : public opt::OptTable { public: - ReadobjOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + ReadobjOptTable() : OptTable(InfoTable, PrefixTable) { + setGroupedShortOptions(true); + } }; enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols }; diff --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp --- a/llvm/tools/llvm-size/llvm-size.cpp +++ b/llvm/tools/llvm-size/llvm-size.cpp @@ -54,6 +54,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -68,7 +76,9 @@ class SizeOptTable : public opt::OptTable { public: - SizeOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + SizeOptTable() : OptTable(InfoTable, PrefixTable) { + 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 --- a/llvm/tools/llvm-strings/llvm-strings.cpp +++ b/llvm/tools/llvm-strings/llvm-strings.cpp @@ -46,6 +46,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -60,7 +68,9 @@ class StringsOptTable : public opt::OptTable { public: - StringsOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + StringsOptTable() : OptTable(InfoTable, PrefixTable) { + setGroupedShortOptions(true); + } }; } // namespace diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -63,6 +63,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -77,7 +85,7 @@ class SymbolizerOptTable : public opt::OptTable { public: - SymbolizerOptTable() : OptTable(InfoTable) { + SymbolizerOptTable() : OptTable(InfoTable, PrefixTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp --- a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp +++ b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp @@ -42,6 +42,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ @@ -56,7 +64,7 @@ class TLICheckerOptTable : public opt::OptTable { public: - TLICheckerOptTable() : OptTable(InfoTable) {} + TLICheckerOptTable() : OptTable(InfoTable, PrefixTable) {} }; } // end anonymous namespace diff --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp --- a/llvm/unittests/Option/OptionParsingTest.cpp +++ b/llvm/unittests/Option/OptionParsingTest.cpp @@ -32,6 +32,14 @@ #include "Opts.inc" #undef PREFIX +static constexpr const StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "Opts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + enum OptionFlags { OptFlag1 = (1 << 4), OptFlag2 = (1 << 5), @@ -51,7 +59,7 @@ class TestOptTable : public OptTable { public: TestOptTable(bool IgnoreCase = false) - : OptTable(InfoTable, IgnoreCase) {} + : OptTable(InfoTable, PrefixTable, IgnoreCase) {} }; } diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp --- a/llvm/utils/TableGen/OptParserEmitter.cpp +++ b/llvm/utils/TableGen/OptParserEmitter.cpp @@ -237,8 +237,14 @@ CurPrefix = NewPrefix; } - // Dump prefixes. + DenseSet PrefixesUnionSet; + for (const auto &Prefix : Prefixes) + PrefixesUnionSet.insert(Prefix.first.begin(), Prefix.first.end()); + SmallVector PrefixesUnion(PrefixesUnionSet.begin(), + PrefixesUnionSet.end()); + array_pod_sort(PrefixesUnion.begin(), PrefixesUnion.end()); + // Dump prefixes. OS << "/////////\n"; OS << "// Prefixes\n\n"; OS << "#ifdef PREFIX\n"; @@ -259,6 +265,20 @@ OS << "#undef COMMA\n"; OS << "#endif // PREFIX\n\n"; + // Dump prefix unions. + OS << "/////////\n"; + OS << "// Prefix Union\n\n"; + OS << "#ifdef PREFIX_UNION\n"; + OS << "#define COMMA ,\n"; + OS << "PREFIX_UNION({\n"; + for (const auto &Prefix : PrefixesUnion) { + OS << "llvm::StringLiteral(\"" << Prefix << "\") COMMA "; + } + OS << "llvm::StringLiteral(\"\")})\n"; + OS << "#undef COMMA\n"; + OS << "#endif // PREFIX_UNION\n\n"; + + // Dump groups. OS << "/////////\n"; OS << "// ValuesCode\n\n"; OS << "#ifdef OPTTABLE_VALUES_CODE\n";