diff options
Diffstat (limited to 'llvm')
35 files changed, 603 insertions, 387 deletions
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h index 8fabc78..decb6cb 100644 --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -53,10 +53,8 @@ class OptTable { public: /// Entry for a single option instance in the option data table. struct Info { - /// A null terminated array of prefix strings to apply to name while - /// matching. - ArrayRef<StringLiteral> Prefixes; - StringLiteral PrefixedName; + unsigned PrefixesOffset; + unsigned PrefixedNameOffset; const char *HelpText; // Help text for specific visibilities. A list of pairs, where each pair // is a list of visibilities and a specific help string for those @@ -80,15 +78,56 @@ public: const char *AliasArgs; const char *Values; - StringRef getName() const { - unsigned PrefixLength = Prefixes.empty() ? 0 : Prefixes[0].size(); - return PrefixedName.drop_front(PrefixLength); + bool hasNoPrefix() const { return PrefixesOffset == 0; } + + unsigned getNumPrefixes(ArrayRef<unsigned> PrefixesTable) const { + return PrefixesTable[PrefixesOffset]; + } + + ArrayRef<unsigned> + getPrefixOffsets(ArrayRef<unsigned> PrefixesTable) const { + return hasNoPrefix() ? ArrayRef<unsigned>() + : PrefixesTable.slice(PrefixesOffset + 1, + getNumPrefixes(PrefixesTable)); + } + + void appendPrefixes(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + SmallVectorImpl<StringRef> &Prefixes) const { + for (unsigned PrefixOffset : getPrefixOffsets(PrefixesTable)) + Prefixes.push_back(&StrTable[PrefixOffset]); + } + + StringRef getPrefix(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + unsigned PrefixIndex) const { + return &StrTable[getPrefixOffsets(PrefixesTable)[PrefixIndex]]; + } + + StringRef getPrefixedName(const char *StrTable) const { + return &StrTable[PrefixedNameOffset]; + } + + StringRef getName(const char *StrTable, + ArrayRef<unsigned> PrefixesTable) const { + unsigned PrefixLength = + hasNoPrefix() ? 0 : getPrefix(StrTable, PrefixesTable, 0).size(); + return getPrefixedName(StrTable).drop_front(PrefixLength); } }; private: + // A unified string table for these options. Individual strings are stored as + // null terminated C-strings at offsets within this table. + const char *StrTable; + + // A table of different sets of prefixes. Each set starts with the number of + // prefixes in that set followed by that many offsets into the string table + // for each of the prefix strings. This is essentially a Pascal-string style + // encoding. + ArrayRef<unsigned> PrefixesTable; + /// The option information table. ArrayRef<Info> OptionInfos; + bool IgnoreCase; bool GroupedShortOptions = false; bool DashDashParsing = false; @@ -102,12 +141,12 @@ protected: /// special option like 'input' or 'unknown', and is not an option group). unsigned FirstSearchableIndex = 0; - /// The union of the first element of all option prefixes. - SmallString<8> PrefixChars; - /// The union of all option prefixes. If an argument does not begin with /// one of these, it is an input. - virtual ArrayRef<StringLiteral> getPrefixesUnion() const = 0; + SmallVector<StringRef> PrefixesUnion; + + /// The union of the first element of all option prefixes. + SmallString<8> PrefixChars; private: const Info &getInfo(OptSpecifier Opt) const { @@ -122,7 +161,8 @@ private: protected: /// Initialize OptTable using Tablegen'ed OptionInfos. Child class must /// manually call \c buildPrefixChars once they are fully constructed. - OptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase = false); + OptTable(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + ArrayRef<Info> OptionInfos, bool IgnoreCase = false); /// Build (or rebuild) the PrefixChars member. void buildPrefixChars(); @@ -130,6 +170,12 @@ protected: public: virtual ~OptTable(); + /// Return the string table used for option names. + const char *getStrTable() const { return StrTable; } + + /// Return the prefixes table used for option names. + ArrayRef<unsigned> getPrefixesTable() const { return PrefixesTable; } + /// Return the total number of option classes. unsigned getNumOptions() const { return OptionInfos.size(); } @@ -141,7 +187,25 @@ public: /// Lookup the name of the given option. StringRef getOptionName(OptSpecifier id) const { - return getInfo(id).getName(); + return getInfo(id).getName(StrTable, PrefixesTable); + } + + /// Lookup the prefix of the given option. + StringRef getOptionPrefix(OptSpecifier id) const { + const Info &I = getInfo(id); + return I.hasNoPrefix() ? StringRef() + : I.getPrefix(StrTable, PrefixesTable, 0); + } + + void appendOptionPrefixes(OptSpecifier id, + SmallVectorImpl<StringRef> &Prefixes) const { + const Info &I = getInfo(id); + I.appendPrefixes(StrTable, PrefixesTable, Prefixes); + } + + /// Lookup the prefixed name of the given option. + StringRef getOptionPrefixedName(OptSpecifier id) const { + return getInfo(id).getPrefixedName(StrTable); } /// Get the kind of the given option. @@ -353,28 +417,22 @@ private: /// Specialization of OptTable class GenericOptTable : public OptTable { - SmallVector<StringLiteral> PrefixesUnionBuffer; - protected: - GenericOptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase = false); - ArrayRef<StringLiteral> getPrefixesUnion() const final { - return PrefixesUnionBuffer; - } + GenericOptTable(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + ArrayRef<Info> OptionInfos, bool IgnoreCase = false); }; class PrecomputedOptTable : public OptTable { - ArrayRef<StringLiteral> PrefixesUnion; - protected: - PrecomputedOptTable(ArrayRef<Info> OptionInfos, - ArrayRef<StringLiteral> PrefixesTable, + PrecomputedOptTable(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + ArrayRef<Info> OptionInfos, + ArrayRef<unsigned> PrefixesUnionOffsets, bool IgnoreCase = false) - : OptTable(OptionInfos, IgnoreCase), PrefixesUnion(PrefixesTable) { + : OptTable(StrTable, PrefixesTable, OptionInfos, IgnoreCase) { + for (unsigned PrefixOffset : PrefixesUnionOffsets) + PrefixesUnion.push_back(&StrTable[PrefixOffset]); buildPrefixChars(); } - ArrayRef<StringLiteral> getPrefixesUnion() const final { - return PrefixesUnion; - } }; } // end namespace opt @@ -382,31 +440,35 @@ protected: } // end namespace llvm #define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX( \ - ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ + ID_PREFIX, PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, ID, KIND, GROUP, ALIAS, \ + ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, VALUES) \ ID_PREFIX##ID -#define LLVM_MAKE_OPT_ID(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \ - ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, \ - HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ - LLVM_MAKE_OPT_ID_WITH_ID_PREFIX( \ - OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUE) +#define LLVM_MAKE_OPT_ID(PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, ID, KIND, \ + GROUP, ALIAS, ALIASARGS, FLAGS, VISIBILITY, PARAM, \ + HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ + LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, \ + ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + VISIBILITY, PARAM, HELPTEXT, \ + HELPTEXTSFORVARIANTS, METAVAR, VALUE) #define LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \ - ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ + ID_PREFIX, PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, ID, KIND, GROUP, ALIAS, \ + ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, VALUES) \ llvm::opt::OptTable::Info { \ - PREFIX, PREFIXED_NAME, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ - ID_PREFIX##ID, llvm::opt::Option::KIND##Class, PARAM, FLAGS, \ + PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, ID_PREFIX##ID, llvm::opt::Option::KIND##Class, PARAM, FLAGS, \ VISIBILITY, ID_PREFIX##GROUP, ID_PREFIX##ALIAS, ALIASARGS, VALUES \ } -#define LLVM_CONSTRUCT_OPT_INFO(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \ - ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, \ - HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ +#define LLVM_CONSTRUCT_OPT_INFO( \ + PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \ - OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) + OPT_, PREFIXES_OFFSET, PREFIXED_NAME_OFFSET, ID, KIND, GROUP, ALIAS, \ + ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, VALUES) #endif // LLVM_OPTION_OPTTABLE_H diff --git a/llvm/include/llvm/Option/Option.h b/llvm/include/llvm/Option/Option.h index 5d16fbd..a0563da 100644 --- a/llvm/include/llvm/Option/Option.h +++ b/llvm/include/llvm/Option/Option.h @@ -100,7 +100,8 @@ public: /// Get the name of this option without any prefix. StringRef getName() const { assert(Info && "Must have a valid info!"); - return Info->getName(); + assert(Owner && "Must have a valid owner!"); + return Owner->getOptionName(Info->ID); } const Option getGroup() const { @@ -127,15 +128,16 @@ public: /// Get the default prefix for this option. StringRef getPrefix() const { - return Info->Prefixes.empty() - ? StringRef() - : static_cast<const StringRef &>(Info->Prefixes[0]); + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOptionPrefix(Info->ID); } /// Get the name of this option with the default prefix. - StringLiteral getPrefixedName() const { + StringRef getPrefixedName() const { assert(Info && "Must have a valid info!"); - return Info->PrefixedName; + assert(Owner && "Must have a valid owner!"); + return Owner->getOptionPrefixedName(Info->ID); } /// Get the help text for this option. diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp index f23f3ed..ecf5c0e5 100644 --- a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp @@ -19,21 +19,17 @@ using namespace jitlink; #define DEBUG_TYPE "jitlink" -// Create prefix string literals used in Options.td -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "COFFOptions.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE -static constexpr const StringLiteral PrefixTable_init[] = -#define PREFIX_UNION(VALUES) VALUES +#define OPTTABLE_PREFIXES_TABLE_CODE #include "COFFOptions.inc" -#undef PREFIX_UNION - ; -static constexpr const ArrayRef<StringLiteral> - PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); +#undef OPTTABLE_PREFIXES_TABLE_CODE + +#define OPTTABLE_PREFIXES_UNION_CODE +#include "COFFOptions.inc" +#undef OPTTABLE_PREFIXES_UNION_CODE // Create table mapping all options defined in COFFOptions.td using namespace llvm::opt; @@ -46,7 +42,9 @@ static constexpr opt::OptTable::Info infoTable[] = { class COFFOptTable : public opt::PrecomputedOptTable { public: - COFFOptTable() : PrecomputedOptTable(infoTable, PrefixTable, true) {} + COFFOptTable() + : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, infoTable, + OptionPrefixesUnion, true) {} }; static COFFOptTable optTable; diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index 9fdafed..87e6f1f 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -31,46 +31,55 @@ using namespace llvm; using namespace llvm::opt; -namespace llvm::opt { +namespace { +struct OptNameLess { + const char *StrTable; + ArrayRef<unsigned> PrefixesTable; + + explicit OptNameLess(const char *StrTable, ArrayRef<unsigned> PrefixesTable) + : StrTable(StrTable), PrefixesTable(PrefixesTable) {} + #ifndef NDEBUG -static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { - if (&A == &B) - return false; - - if (int Cmp = StrCmpOptionName(A.getName(), B.getName())) - return Cmp < 0; - - // Note: we are converting ArrayRef<StringLiteral> to ArrayRef<StringRef>. - // In general, ArrayRef<SubClass> cannot be safely viewed as ArrayRef<Base> - // since sizeof(SubClass) may not be same as sizeof(Base). However in this - // case, sizeof(StringLiteral) is same as sizeof(StringRef), so this - // conversion is safe. - static_assert(sizeof(StringRef) == sizeof(StringLiteral)); - ArrayRef<StringRef> APrefixes(A.Prefixes.data(), A.Prefixes.size()); - ArrayRef<StringRef> BPrefixes(B.Prefixes.data(), B.Prefixes.size()); - - if (int Cmp = StrCmpOptionPrefixes(APrefixes, BPrefixes)) - return Cmp < 0; - - // Names are the same, check that classes are in order; exactly one - // should be joined, and it should succeed the other. - assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) && - "Unexpected classes for options with same name."); - return B.Kind == Option::JoinedClass; -} + inline bool operator()(const OptTable::Info &A, + const OptTable::Info &B) const { + if (&A == &B) + return false; + + if (int Cmp = StrCmpOptionName(A.getName(StrTable, PrefixesTable), + B.getName(StrTable, PrefixesTable))) + return Cmp < 0; + + SmallVector<StringRef, 8> APrefixes, BPrefixes; + A.appendPrefixes(StrTable, PrefixesTable, APrefixes); + B.appendPrefixes(StrTable, PrefixesTable, BPrefixes); + + if (int Cmp = StrCmpOptionPrefixes(APrefixes, BPrefixes)) + return Cmp < 0; + + // Names are the same, check that classes are in order; exactly one + // should be joined, and it should succeed the other. + assert( + ((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) && + "Unexpected classes for options with same name."); + return B.Kind == Option::JoinedClass; + } #endif -// Support lower_bound between info and an option name. -static inline bool operator<(const OptTable::Info &I, StringRef Name) { - // Do not fallback to case sensitive comparison. - return StrCmpOptionName(I.getName(), Name, false) < 0; -} -} // namespace llvm::opt + // Support lower_bound between info and an option name. + inline bool operator()(const OptTable::Info &I, StringRef Name) const { + // Do not fallback to case sensitive comparison. + return StrCmpOptionName(I.getName(StrTable, PrefixesTable), Name, false) < + 0; + } +}; +} // namespace OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {} -OptTable::OptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase) - : OptionInfos(OptionInfos), IgnoreCase(IgnoreCase) { +OptTable::OptTable(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + ArrayRef<Info> OptionInfos, bool IgnoreCase) + : StrTable(StrTable), PrefixesTable(PrefixesTable), + OptionInfos(OptionInfos), IgnoreCase(IgnoreCase) { // Explicitly zero initialize the error to work around a bug in array // value-initialization on MinGW with gcc 4.3.5. @@ -102,7 +111,7 @@ OptTable::OptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase) // Check that options are in order. for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions(); i != e; ++i){ - if (!(getInfo(i) < getInfo(i + 1))) { + if (!(OptNameLess(StrTable, PrefixesTable)(getInfo(i), getInfo(i + 1)))) { getOption(i).dump(); getOption(i + 1).dump(); llvm_unreachable("Options are not in order!"); @@ -115,7 +124,7 @@ void OptTable::buildPrefixChars() { assert(PrefixChars.empty() && "rebuilding a non-empty prefix char"); // Build prefix chars. - for (const StringLiteral &Prefix : getPrefixesUnion()) { + for (StringRef Prefix : PrefixesUnion) { for (char C : Prefix) if (!is_contained(PrefixChars, C)) PrefixChars.push_back(C); @@ -132,7 +141,7 @@ const Option OptTable::getOption(OptSpecifier Opt) const { return Option(&getInfo(id), this); } -static bool isInput(const ArrayRef<StringLiteral> &Prefixes, StringRef Arg) { +static bool isInput(const ArrayRef<StringRef> &Prefixes, StringRef Arg) { if (Arg == "-") return true; for (const StringRef &Prefix : Prefixes) @@ -142,25 +151,32 @@ static bool isInput(const ArrayRef<StringLiteral> &Prefixes, StringRef Arg) { } /// \returns Matched size. 0 means no match. -static unsigned matchOption(const OptTable::Info *I, StringRef Str, +static unsigned matchOption(const char *StrTable, + ArrayRef<unsigned> PrefixesTable, + const OptTable::Info *I, StringRef Str, bool IgnoreCase) { - for (auto Prefix : I->Prefixes) { + StringRef Name = I->getName(StrTable, PrefixesTable); + for (unsigned PrefixOffset : I->getPrefixOffsets(PrefixesTable)) { + StringRef Prefix = &StrTable[PrefixOffset]; if (Str.starts_with(Prefix)) { StringRef Rest = Str.substr(Prefix.size()); - bool Matched = IgnoreCase ? Rest.starts_with_insensitive(I->getName()) - : Rest.starts_with(I->getName()); + bool Matched = IgnoreCase ? Rest.starts_with_insensitive(Name) + : Rest.starts_with(Name); if (Matched) - return Prefix.size() + StringRef(I->getName()).size(); + return Prefix.size() + Name.size(); } } return 0; } // Returns true if one of the Prefixes + In.Names matches Option -static bool optionMatches(const OptTable::Info &In, StringRef Option) { - for (auto Prefix : In.Prefixes) - if (Option.ends_with(In.getName())) - if (Option.slice(0, Option.size() - In.getName().size()) == Prefix) +static bool optionMatches(const char *StrTable, + ArrayRef<unsigned> PrefixesTable, + const OptTable::Info &In, StringRef Option) { + StringRef Name = In.getName(StrTable, PrefixesTable); + if (Option.consume_back(Name)) + for (unsigned PrefixOffset : In.getPrefixOffsets(PrefixesTable)) + if (Option == &StrTable[PrefixOffset]) return true; return false; } @@ -173,7 +189,7 @@ OptTable::suggestValueCompletions(StringRef Option, StringRef Arg) const { // Search all options and return possible values. for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) { const Info &In = OptionInfos[I]; - if (!In.Values || !optionMatches(In, Option)) + if (!In.Values || !optionMatches(StrTable, PrefixesTable, In, Option)) continue; SmallVector<StringRef, 8> Candidates; @@ -194,15 +210,17 @@ OptTable::findByPrefix(StringRef Cur, Visibility VisibilityMask, std::vector<std::string> Ret; for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) { const Info &In = OptionInfos[I]; - if (In.Prefixes.empty() || (!In.HelpText && !In.GroupID)) + if (In.hasNoPrefix() || (!In.HelpText && !In.GroupID)) continue; if (!(In.Visibility & VisibilityMask)) continue; if (In.Flags & DisableFlags) continue; - for (auto Prefix : In.Prefixes) { - std::string S = (Prefix + In.getName() + "\t").str(); + StringRef Name = In.getName(StrTable, PrefixesTable); + for (unsigned PrefixOffset : In.getPrefixOffsets(PrefixesTable)) { + StringRef Prefix = &StrTable[PrefixOffset]; + std::string S = (Twine(Prefix) + Name + "\t").str(); if (In.HelpText) S += In.HelpText; if (StringRef(S).starts_with(Cur) && S != std::string(Cur) + "\t") @@ -253,7 +271,7 @@ unsigned OptTable::internalFindNearest( for (const Info &CandidateInfo : ArrayRef<Info>(OptionInfos).drop_front(FirstSearchableIndex)) { - StringRef CandidateName = CandidateInfo.getName(); + StringRef CandidateName = CandidateInfo.getName(StrTable, PrefixesTable); // We can eliminate some option prefix/name pairs as candidates right away: // * Ignore option candidates with empty names, such as "--", or names @@ -267,7 +285,7 @@ unsigned OptTable::internalFindNearest( // * Ignore positional argument option candidates (which do not // have prefixes). - if (CandidateInfo.Prefixes.empty()) + if (CandidateInfo.hasNoPrefix()) continue; // Now check if the candidate ends with a character commonly used when @@ -286,7 +304,9 @@ unsigned OptTable::internalFindNearest( // 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) { + for (unsigned CandidatePrefixOffset : + CandidateInfo.getPrefixOffsets(PrefixesTable)) { + StringRef CandidatePrefix = &StrTable[CandidatePrefixOffset]; // If Candidate and NormalizedName have more than 'BestDistance' // characters of difference, no need to compute the edit distance, it's // going to be greater than BestDistance. Don't bother computing Candidate @@ -332,19 +352,21 @@ std::unique_ptr<Arg> OptTable::parseOneArgGrouped(InputArgList &Args, // itself. const char *CStr = Args.getArgString(Index); StringRef Str(CStr); - if (isInput(getPrefixesUnion(), Str)) + if (isInput(PrefixesUnion, Str)) return std::make_unique<Arg>(getOption(InputOptionID), Str, Index++, CStr); const Info *End = OptionInfos.data() + OptionInfos.size(); StringRef Name = Str.ltrim(PrefixChars); const Info *Start = - std::lower_bound(OptionInfos.data() + FirstSearchableIndex, End, Name); + std::lower_bound(OptionInfos.data() + FirstSearchableIndex, End, Name, + OptNameLess(StrTable, PrefixesTable)); const Info *Fallback = nullptr; unsigned Prev = Index; // Search for the option which matches Str. for (; Start != End; ++Start) { - unsigned ArgSize = matchOption(Start, Str, IgnoreCase); + unsigned ArgSize = + matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase); if (!ArgSize) continue; @@ -417,7 +439,7 @@ std::unique_ptr<Arg> OptTable::internalParseOneArg( // Anything that doesn't start with PrefixesUnion is an input, as is '-' // itself. - if (isInput(getPrefixesUnion(), Str)) + if (isInput(PrefixesUnion, Str)) return std::make_unique<Arg>(getOption(InputOptionID), Str, Index++, Str.data()); @@ -426,7 +448,8 @@ std::unique_ptr<Arg> OptTable::internalParseOneArg( StringRef Name = Str.ltrim(PrefixChars); // Search for the first next option which could be a prefix. - Start = std::lower_bound(Start, End, Name); + Start = + std::lower_bound(Start, End, Name, OptNameLess(StrTable, PrefixesTable)); // Options are stored in sorted order, with '\0' at the end of the // alphabet. Since the only options which can accept a string must @@ -440,7 +463,8 @@ std::unique_ptr<Arg> OptTable::internalParseOneArg( unsigned ArgSize = 0; // Scan for first option which is a proper prefix. for (; Start != End; ++Start) - if ((ArgSize = matchOption(Start, Str, IgnoreCase))) + if ((ArgSize = + matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase))) break; if (Start == End) break; @@ -763,12 +787,15 @@ void OptTable::internalPrintHelp( OS.flush(); } -GenericOptTable::GenericOptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase) - : OptTable(OptionInfos, IgnoreCase) { +GenericOptTable::GenericOptTable(const char *StrTable, + ArrayRef<unsigned> PrefixesTable, + ArrayRef<Info> OptionInfos, bool IgnoreCase) + : OptTable(StrTable, PrefixesTable, OptionInfos, IgnoreCase) { - std::set<StringLiteral> TmpPrefixesUnion; + std::set<StringRef> TmpPrefixesUnion; for (auto const &Info : OptionInfos.drop_front(FirstSearchableIndex)) - TmpPrefixesUnion.insert(Info.Prefixes.begin(), Info.Prefixes.end()); - PrefixesUnionBuffer.append(TmpPrefixesUnion.begin(), TmpPrefixesUnion.end()); + for (unsigned PrefixOffset : Info.getPrefixOffsets(PrefixesTable)) + TmpPrefixesUnion.insert(StringRef(&StrTable[PrefixOffset])); + PrefixesUnion.append(TmpPrefixesUnion.begin(), TmpPrefixesUnion.end()); buildPrefixChars(); } diff --git a/llvm/lib/Option/Option.cpp b/llvm/lib/Option/Option.cpp index ecb3e84..738f75b 100644 --- a/llvm/lib/Option/Option.cpp +++ b/llvm/lib/Option/Option.cpp @@ -57,10 +57,13 @@ void Option::print(raw_ostream &O, bool AddNewLine) const { #undef P } - if (!Info->Prefixes.empty()) { + if (!Info->hasNoPrefix()) { O << " Prefixes:["; - for (size_t I = 0, N = Info->Prefixes.size(); I != N; ++I) - O << '"' << Info->Prefixes[I] << (I == N - 1 ? "\"" : "\", "); + for (size_t I = 0, N = Info->getNumPrefixes(Owner->getPrefixesTable()); + I != N; ++I) + O << '"' + << Info->getPrefix(Owner->getStrTable(), Owner->getPrefixesTable(), I) + << (I == N - 1 ? "\"" : "\", "); O << ']'; } diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp index b3dcc0f..58ff720 100644 --- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp @@ -31,6 +31,10 @@ using namespace llvm::COFF; namespace { +#define OPTTABLE_STR_TABLE_CODE +#include "Options.inc" +#undef OPTTABLE_STR_TABLE_CODE + enum { OPT_INVALID = 0, #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__), @@ -38,12 +42,9 @@ enum { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_PREFIXES_TABLE_CODE #include "Options.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -54,7 +55,9 @@ static constexpr opt::OptTable::Info InfoTable[] = { class DllOptTable : public opt::GenericOptTable { public: - DllOptTable() : opt::GenericOptTable(InfoTable, false) {} + DllOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + 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 2e0841b..319aebf 100644 --- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp @@ -37,6 +37,10 @@ using namespace llvm::object; namespace { +#define OPTTABLE_STR_TABLE_CODE +#include "Options.inc" +#undef OPTTABLE_STR_TABLE_CODE + enum { OPT_INVALID = 0, #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__), @@ -44,12 +48,9 @@ enum { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_PREFIXES_TABLE_CODE #include "Options.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -60,7 +61,9 @@ static constexpr opt::OptTable::Info InfoTable[] = { class LibOptTable : public opt::GenericOptTable { public: - LibOptTable() : opt::GenericOptTable(InfoTable, true) {} + LibOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + true) {} }; } // namespace diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 594b523..913077e 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -64,12 +64,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Options.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Options.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -80,7 +81,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class DsymutilOptTable : public opt::GenericOptTable { public: - DsymutilOptTable() : opt::GenericOptTable(InfoTable) {} + DsymutilOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // namespace diff --git a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp index d33459b..9e3800f 100644 --- a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp +++ b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp @@ -51,12 +51,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -67,7 +68,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class CGDataOptTable : public opt::GenericOptTable { public: - CGDataOptTable() : GenericOptTable(InfoTable) {} + CGDataOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp index 0c10769..8ef8d6e 100644 --- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp +++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp @@ -42,12 +42,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -58,7 +59,9 @@ static constexpr opt::OptTable::Info InfoTable[] = { class CvtResOptTable : public opt::GenericOptTable { public: - CvtResOptTable() : opt::GenericOptTable(InfoTable, true) {} + CvtResOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + true) {} }; } diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp index 41b379e..1467093 100644 --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -31,12 +31,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \ - NAME##_init, std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -47,7 +48,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class CxxfiltOptTable : public opt::GenericOptTable { public: - CxxfiltOptTable() : opt::GenericOptTable(InfoTable) { + CxxfiltOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { 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 7786273..934833b 100644 --- a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp +++ b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp @@ -37,12 +37,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -53,7 +54,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class DebuginfodFindOptTable : public opt::GenericOptTable { public: - DebuginfodFindOptTable() : GenericOptTable(InfoTable) {} + DebuginfodFindOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp index 44d6561..2859a36 100644 --- a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp +++ b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp @@ -36,12 +36,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -52,7 +53,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class DebuginfodOptTable : public opt::GenericOptTable { public: - DebuginfodOptTable() : GenericOptTable(InfoTable) {} + DebuginfodOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp index 7b777b1..0180abb 100644 --- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp +++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp @@ -38,12 +38,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Options.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Options.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -54,7 +55,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class DwarfutilOptTable : public opt::GenericOptTable { public: - DwarfutilOptTable() : opt::GenericOptTable(InfoTable) {} + DwarfutilOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // namespace diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp index 60a89cb..e34fcad 100644 --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -47,12 +47,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -63,7 +64,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class DwpOptTable : public opt::GenericOptTable { public: - DwpOptTable() : GenericOptTable(InfoTable) {} + DwpOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp index 4d44146..4290015 100644 --- a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp +++ b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp @@ -64,12 +64,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \ - NAME##_init, std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE const opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -79,7 +80,8 @@ const opt::OptTable::Info InfoTable[] = { class GSYMUtilOptTable : public llvm::opt::GenericOptTable { public: - GSYMUtilOptTable() : GenericOptTable(InfoTable) { + GSYMUtilOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index b76ea8d..e12016c 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -59,12 +59,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -74,7 +75,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class IFSOptTable : public opt::GenericOptTable { public: - IFSOptTable() : opt::GenericOptTable(InfoTable) { + IFSOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp index 3d3f3f0..9424711 100644 --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -48,12 +48,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -63,7 +64,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class LibtoolDarwinOptTable : public opt::GenericOptTable { public: - LibtoolDarwinOptTable() : GenericOptTable(InfoTable) {} + LibtoolDarwinOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // end anonymous namespace diff --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp index 711a918..3c0197e 100644 --- a/llvm/tools/llvm-lipo/llvm-lipo.cpp +++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp @@ -72,12 +72,13 @@ enum LipoID { }; namespace lipo { -#define PREFIX(NAME, VALUE) \ - static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \ - NAME##_init, std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "LipoOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "LipoOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info LipoInfoTable[] = { @@ -89,7 +90,9 @@ static constexpr opt::OptTable::Info LipoInfoTable[] = { class LipoOptTable : public opt::GenericOptTable { public: - LipoOptTable() : opt::GenericOptTable(lipo::LipoInfoTable) {} + LipoOptTable() + : opt::GenericOptTable(lipo::OptionStrTable, lipo::OptionPrefixesTable, + lipo::LipoInfoTable) {} }; enum class LipoAction { diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp index db69109..1aa4109 100644 --- a/llvm/tools/llvm-ml/llvm-ml.cpp +++ b/llvm/tools/llvm-ml/llvm-ml.cpp @@ -58,12 +58,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -73,7 +74,9 @@ static constexpr opt::OptTable::Info InfoTable[] = { class MLOptTable : public opt::GenericOptTable { public: - MLOptTable() : opt::GenericOptTable(InfoTable, /*IgnoreCase=*/false) {} + MLOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + /*IgnoreCase=*/false) {} }; } // namespace diff --git a/llvm/tools/llvm-mt/llvm-mt.cpp b/llvm/tools/llvm-mt/llvm-mt.cpp index 8b793b8..3bd1bc7 100644 --- a/llvm/tools/llvm-mt/llvm-mt.cpp +++ b/llvm/tools/llvm-mt/llvm-mt.cpp @@ -40,12 +40,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -56,7 +57,9 @@ static constexpr opt::OptTable::Info InfoTable[] = { class CvtResOptTable : public opt::GenericOptTable { public: - CvtResOptTable() : opt::GenericOptTable(InfoTable, true) {} + CvtResOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + true) {} }; } // namespace diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index d3e8d4c..e7c3e36 100644 --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -65,12 +65,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -80,7 +81,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class NmOptTable : public opt::GenericOptTable { public: - NmOptTable() : opt::GenericOptTable(InfoTable) { + NmOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index 104d802..0925fc5 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -39,12 +39,13 @@ enum ObjcopyID { }; namespace objcopy_opt { -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "ObjcopyOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "ObjcopyOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info ObjcopyInfoTable[] = { #define OPTION(...) \ @@ -56,7 +57,10 @@ static constexpr opt::OptTable::Info ObjcopyInfoTable[] = { class ObjcopyOptTable : public opt::GenericOptTable { public: - ObjcopyOptTable() : opt::GenericOptTable(objcopy_opt::ObjcopyInfoTable) { + ObjcopyOptTable() + : opt::GenericOptTable(objcopy_opt::OptionStrTable, + objcopy_opt::OptionPrefixesTable, + objcopy_opt::ObjcopyInfoTable) { setGroupedShortOptions(true); setDashDashParsing(true); } @@ -71,13 +75,13 @@ enum InstallNameToolID { }; namespace install_name_tool { +#define OPTTABLE_STR_TABLE_CODE +#include "InstallNameToolOpts.inc" +#undef OPTTABLE_STR_TABLE_CODE -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_PREFIXES_TABLE_CODE #include "InstallNameToolOpts.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = { #define OPTION(...) \ @@ -90,7 +94,9 @@ static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = { class InstallNameToolOptTable : public opt::GenericOptTable { public: InstallNameToolOptTable() - : GenericOptTable(install_name_tool::InstallNameToolInfoTable) {} + : GenericOptTable(install_name_tool::OptionStrTable, + install_name_tool::OptionPrefixesTable, + install_name_tool::InstallNameToolInfoTable) {} }; enum BitcodeStripID { @@ -102,13 +108,13 @@ enum BitcodeStripID { }; namespace bitcode_strip { +#define OPTTABLE_STR_TABLE_CODE +#include "BitcodeStripOpts.inc" +#undef OPTTABLE_STR_TABLE_CODE -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_PREFIXES_TABLE_CODE #include "BitcodeStripOpts.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = { #define OPTION(...) \ @@ -121,7 +127,9 @@ static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = { class BitcodeStripOptTable : public opt::GenericOptTable { public: BitcodeStripOptTable() - : opt::GenericOptTable(bitcode_strip::BitcodeStripInfoTable) {} + : opt::GenericOptTable(bitcode_strip::OptionStrTable, + bitcode_strip::OptionPrefixesTable, + bitcode_strip::BitcodeStripInfoTable) {} }; enum StripID { @@ -132,12 +140,13 @@ enum StripID { }; namespace strip { -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE +#include "StripOpts.inc" +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE #include "StripOpts.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info StripInfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(STRIP_, __VA_ARGS__), @@ -148,7 +157,9 @@ static constexpr opt::OptTable::Info StripInfoTable[] = { class StripOptTable : public opt::GenericOptTable { public: - StripOptTable() : GenericOptTable(strip::StripInfoTable) { + StripOptTable() + : GenericOptTable(strip::OptionStrTable, strip::OptionPrefixesTable, + strip::StripInfoTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 246d5cf..1e74cb8 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -99,10 +99,11 @@ namespace { class CommonOptTable : public opt::GenericOptTable { public: - CommonOptTable(ArrayRef<Info> OptionInfos, const char *Usage, + CommonOptTable(const char *StrTable, ArrayRef<unsigned> PrefixesTable, + ArrayRef<Info> OptionInfos, const char *Usage, const char *Description) - : opt::GenericOptTable(OptionInfos), Usage(Usage), - Description(Description) { + : opt::GenericOptTable(StrTable, PrefixesTable, OptionInfos), + Usage(Usage), Description(Description) { setGroupedShortOptions(true); } @@ -121,12 +122,13 @@ private: // ObjdumpOptID is in ObjdumpOptID.h namespace objdump_opt { -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "ObjdumpOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "ObjdumpOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info ObjdumpInfoTable[] = { #define OPTION(...) \ @@ -139,9 +141,10 @@ static constexpr opt::OptTable::Info ObjdumpInfoTable[] = { class ObjdumpOptTable : public CommonOptTable { public: ObjdumpOptTable() - : CommonOptTable(objdump_opt::ObjdumpInfoTable, - " [options] <input object files>", - "llvm object file dumper") {} + : CommonOptTable( + objdump_opt::OptionStrTable, objdump_opt::OptionPrefixesTable, + objdump_opt::ObjdumpInfoTable, " [options] <input object files>", + "llvm object file dumper") {} }; enum OtoolOptID { @@ -152,12 +155,13 @@ enum OtoolOptID { }; namespace otool { -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE +#include "OtoolOpts.inc" +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE #include "OtoolOpts.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info OtoolInfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(OTOOL_, __VA_ARGS__), @@ -169,7 +173,8 @@ static constexpr opt::OptTable::Info OtoolInfoTable[] = { class OtoolOptTable : public CommonOptTable { public: OtoolOptTable() - : CommonOptTable(otool::OtoolInfoTable, " [option...] [file...]", + : CommonOptTable(otool::OptionStrTable, otool::OptionPrefixesTable, + otool::OtoolInfoTable, " [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 4bc9d90..a77188c 100644 --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -57,12 +57,13 @@ enum ID { }; namespace rc_opt { -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -73,7 +74,10 @@ static constexpr opt::OptTable::Info InfoTable[] = { class RcOptTable : public opt::GenericOptTable { public: - RcOptTable() : GenericOptTable(rc_opt::InfoTable, /* IgnoreCase = */ true) {} + RcOptTable() + : GenericOptTable(rc_opt::OptionStrTable, rc_opt::OptionPrefixesTable, + rc_opt::InfoTable, + /* IgnoreCase = */ true) {} }; enum Windres_ID { @@ -84,12 +88,13 @@ enum Windres_ID { }; namespace windres_opt { -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE +#include "WindresOpts.inc" +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE #include "WindresOpts.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) \ @@ -102,7 +107,10 @@ static constexpr opt::OptTable::Info InfoTable[] = { class WindresOptTable : public opt::GenericOptTable { public: WindresOptTable() - : GenericOptTable(windres_opt::InfoTable, /* IgnoreCase = */ false) {} + : GenericOptTable(windres_opt::OptionStrTable, + windres_opt::OptionPrefixesTable, + windres_opt::InfoTable, + /* IgnoreCase = */ false) {} }; static ExitOnError ExitOnErr; diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index 3e76cda..2f77e5d 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -59,12 +59,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -74,7 +75,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class ReadobjOptTable : public opt::GenericOptTable { public: - ReadobjOptTable() : opt::GenericOptTable(InfoTable) { + ReadobjOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp index 04282d3e..b5574ea 100644 --- a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp +++ b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp @@ -45,12 +45,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "TapiOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "TapiOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -60,7 +61,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class TAPIOptTable : public opt::GenericOptTable { public: - TAPIOptTable() : opt::GenericOptTable(InfoTable) { + TAPIOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); } }; diff --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp index 4a1b0e8..0d7bf24 100644 --- a/llvm/tools/llvm-size/llvm-size.cpp +++ b/llvm/tools/llvm-size/llvm-size.cpp @@ -45,12 +45,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -60,7 +61,10 @@ static constexpr opt::OptTable::Info InfoTable[] = { class SizeOptTable : public opt::GenericOptTable { public: - SizeOptTable() : GenericOptTable(InfoTable) { setGroupedShortOptions(true); } + SizeOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { + 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 d430509..9979b93 100644 --- a/llvm/tools/llvm-strings/llvm-strings.cpp +++ b/llvm/tools/llvm-strings/llvm-strings.cpp @@ -38,12 +38,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -54,7 +55,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class StringsOptTable : public opt::GenericOptTable { public: - StringsOptTable() : GenericOptTable(InfoTable) { + StringsOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); setDashDashParsing(true); } diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index 3e41a85..3ba7f59 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -56,12 +56,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -72,7 +73,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class SymbolizerOptTable : public opt::GenericOptTable { public: - SymbolizerOptTable() : GenericOptTable(InfoTable) { + SymbolizerOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { 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 a091e37..ca0b424 100644 --- a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp +++ b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp @@ -33,12 +33,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE using namespace llvm::opt; static constexpr opt::OptTable::Info InfoTable[] = { @@ -49,7 +50,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class TLICheckerOptTable : public opt::GenericOptTable { public: - TLICheckerOptTable() : GenericOptTable(InfoTable) {} + TLICheckerOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // end anonymous namespace diff --git a/llvm/tools/sancov/sancov.cpp b/llvm/tools/sancov/sancov.cpp index 39feff6..727b94b 100644 --- a/llvm/tools/sancov/sancov.cpp +++ b/llvm/tools/sancov/sancov.cpp @@ -67,12 +67,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -82,7 +83,8 @@ static constexpr opt::OptTable::Info InfoTable[] = { class SancovOptTable : public opt::GenericOptTable { public: - SancovOptTable() : GenericOptTable(InfoTable) {} + SancovOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; } // namespace diff --git a/llvm/unittests/Option/OptionMarshallingTest.cpp b/llvm/unittests/Option/OptionMarshallingTest.cpp index 2ec422f..08c3b01 100644 --- a/llvm/unittests/Option/OptionMarshallingTest.cpp +++ b/llvm/unittests/Option/OptionMarshallingTest.cpp @@ -9,29 +9,37 @@ #include "llvm/ADT/StringRef.h" #include "gtest/gtest.h" +#define OPTTABLE_STR_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_STR_TABLE_CODE + struct OptionWithMarshallingInfo { - llvm::StringLiteral PrefixedName; + int PrefixedNameOffset; const char *KeyPath; const char *ImpliedCheck; const char *ImpliedValue; + + llvm::StringRef getPrefixedName() const { + return &OptionStrTable[PrefixedNameOffset]; + } }; static const OptionWithMarshallingInfo MarshallingTable[] = { #define OPTION_WITH_MARSHALLING( \ - PREFIX_TYPE, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ + PREFIX_TYPE, PREFIXED_NAME_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ - {PREFIXED_NAME, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE}, + {PREFIXED_NAME_OFFSET, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE}, #include "Opts.inc" #undef OPTION_WITH_MARSHALLING }; TEST(OptionMarshalling, EmittedOrderSameAsDefinitionOrder) { - ASSERT_EQ(MarshallingTable[0].PrefixedName, "-marshalled-flag-d"); - ASSERT_EQ(MarshallingTable[1].PrefixedName, "-marshalled-flag-c"); - ASSERT_EQ(MarshallingTable[2].PrefixedName, "-marshalled-flag-b"); - ASSERT_EQ(MarshallingTable[3].PrefixedName, "-marshalled-flag-a"); + ASSERT_EQ(MarshallingTable[0].getPrefixedName(), "-marshalled-flag-d"); + ASSERT_EQ(MarshallingTable[1].getPrefixedName(), "-marshalled-flag-c"); + ASSERT_EQ(MarshallingTable[2].getPrefixedName(), "-marshalled-flag-b"); + ASSERT_EQ(MarshallingTable[3].getPrefixedName(), "-marshalled-flag-a"); } TEST(OptionMarshalling, EmittedSpecifiedKeyPath) { diff --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp index cd8743e..3da015e 100644 --- a/llvm/unittests/Option/OptionParsingTest.cpp +++ b/llvm/unittests/Option/OptionParsingTest.cpp @@ -20,6 +20,10 @@ using namespace llvm::opt; #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif +#define OPTTABLE_STR_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_STR_TABLE_CODE + enum ID { OPT_INVALID = 0, // This is not an option ID. #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__), @@ -28,20 +32,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_PREFIXES_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE -static constexpr const StringLiteral PrefixTable_init[] = -#define PREFIX_UNION(VALUES) VALUES +#define OPTTABLE_PREFIXES_UNION_CODE #include "Opts.inc" -#undef PREFIX_UNION - ; -static constexpr const ArrayRef<StringLiteral> - PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); +#undef OPTTABLE_PREFIXES_UNION_CODE enum OptionFlags { OptFlag1 = (1 << 4), @@ -64,13 +61,15 @@ namespace { class TestOptTable : public GenericOptTable { public: TestOptTable(bool IgnoreCase = false) - : GenericOptTable(InfoTable, IgnoreCase) {} + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + IgnoreCase) {} }; class TestPrecomputedOptTable : public PrecomputedOptTable { public: TestPrecomputedOptTable(bool IgnoreCase = false) - : PrecomputedOptTable(InfoTable, PrefixTable, IgnoreCase) {} + : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + OptionPrefixesUnion, IgnoreCase) {} }; } diff --git a/llvm/utils/TableGen/OptionParserEmitter.cpp b/llvm/utils/TableGen/OptionParserEmitter.cpp index 48f5818..eca828c 100644 --- a/llvm/utils/TableGen/OptionParserEmitter.cpp +++ b/llvm/utils/TableGen/OptionParserEmitter.cpp @@ -9,9 +9,11 @@ #include "Common/OptEmitter.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringToOffsetTable.h" #include "llvm/TableGen/TableGenBackend.h" #include <cstring> #include <map> @@ -26,6 +28,15 @@ static std::string getOptionName(const Record &R) { return std::string(R.getValueAsString("EnumName")); } +static raw_ostream &writeStrTableOffset(raw_ostream &OS, + const StringToOffsetTable &Table, + llvm::StringRef Str) { + OS << Table.GetStringOffset(Str) << " /* "; + OS.write_escaped(Str); + OS << " */"; + return OS; +} + static raw_ostream &writeCstring(raw_ostream &OS, llvm::StringRef Str) { OS << '"'; OS.write_escaped(Str); @@ -260,59 +271,84 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { // Generate prefix groups. typedef SmallVector<SmallString<2>, 2> PrefixKeyT; - typedef std::map<PrefixKeyT, std::string> PrefixesT; + typedef std::map<PrefixKeyT, unsigned> PrefixesT; PrefixesT Prefixes; - Prefixes.insert(std::pair(PrefixKeyT(), "prefix_0")); - unsigned CurPrefix = 0; + Prefixes.insert({PrefixKeyT(), 0}); for (const Record &R : llvm::make_pointee_range(Opts)) { std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes"); PrefixKeyT PrefixKey(RPrefixes.begin(), RPrefixes.end()); - unsigned NewPrefix = CurPrefix + 1; - std::string Prefix = (Twine("prefix_") + Twine(NewPrefix)).str(); - if (Prefixes.insert(std::pair(PrefixKey, Prefix)).second) - CurPrefix = NewPrefix; + Prefixes.insert({PrefixKey, 0}); } DenseSet<StringRef> PrefixesUnionSet; - for (const auto &Prefix : Prefixes) - PrefixesUnionSet.insert(Prefix.first.begin(), Prefix.first.end()); + for (const auto &[Prefix, _] : Prefixes) + PrefixesUnionSet.insert(Prefix.begin(), Prefix.end()); SmallVector<StringRef> PrefixesUnion(PrefixesUnionSet.begin(), PrefixesUnionSet.end()); array_pod_sort(PrefixesUnion.begin(), PrefixesUnion.end()); + llvm::StringToOffsetTable Table; + // Make sure the empty string is the zero-th one in the table. This both makes + // it easy to check for empty strings (zero offset == empty) and makes + // initialization cheaper for empty strings. + Table.GetOrAddStringOffset(""); + // We can add all the prefixes via the union. + for (const auto &Prefix : PrefixesUnion) + Table.GetOrAddStringOffset(Prefix); + for (const Record &R : llvm::make_pointee_range(Groups)) + Table.GetOrAddStringOffset(R.getValueAsString("Name")); + for (const Record &R : llvm::make_pointee_range(Opts)) + Table.GetOrAddStringOffset(getOptionPrefixedName(R)); + + // Dump string table. + OS << "/////////\n"; + OS << "// String table\n\n"; + OS << "#ifdef OPTTABLE_STR_TABLE_CODE\n"; + Table.EmitStringLiteralDef(OS, "static constexpr char OptionStrTable[]", + /*Indent=*/""); + OS << "#endif // OPTTABLE_STR_TABLE_CODE\n\n"; + // Dump prefixes. OS << "/////////\n"; OS << "// Prefixes\n\n"; - OS << "#ifdef PREFIX\n"; - OS << "#define COMMA ,\n"; - for (const auto &Prefix : Prefixes) { - OS << "PREFIX("; - - // Prefix name. - OS << Prefix.second; - - // Prefix values. - OS << ", {"; - for (const auto &PrefixKey : Prefix.first) - OS << "llvm::StringLiteral(\"" << PrefixKey << "\") COMMA "; - // Append an empty element to avoid ending up with an empty array. - OS << "llvm::StringLiteral(\"\")})\n"; + OS << "#ifdef OPTTABLE_PREFIXES_TABLE_CODE\n"; + OS << "static constexpr unsigned OptionPrefixesTable[] = {\n"; + { + // Ensure the first prefix set is always empty. + assert(!Prefixes.empty() && + "We should always emit an empty set of prefixes"); + assert(Prefixes.begin()->first.empty() && + "First prefix set should always be empty"); + llvm::ListSeparator Sep(",\n"); + unsigned CurIndex = 0; + for (auto &[Prefix, PrefixIndex] : Prefixes) { + // First emit the number of prefix strings in this list of prefixes. + OS << Sep << " " << Prefix.size() << " /* prefixes */"; + PrefixIndex = CurIndex; + assert((CurIndex == 0 || !Prefix.empty()) && + "Only first prefix set should be empty!"); + for (const auto &PrefixKey : Prefix) + OS << ", " << *Table.GetStringOffset(PrefixKey) << " /* '" << PrefixKey + << "' */"; + CurIndex += Prefix.size() + 1; + } } - OS << "#undef COMMA\n"; - OS << "#endif // PREFIX\n\n"; + OS << "\n};\n"; + OS << "#endif // OPTTABLE_PREFIXES_TABLE_CODE\n\n"; - // Dump prefix unions. + // Dump prefixes union. 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 << "#ifdef OPTTABLE_PREFIXES_UNION_CODE\n"; + OS << "static constexpr unsigned OptionPrefixesUnion[] = {\n"; + { + llvm::ListSeparator Sep(", "); + for (auto Prefix : PrefixesUnion) + OS << Sep << " " << *Table.GetStringOffset(Prefix) << " /* '" << Prefix + << "' */"; } - OS << "llvm::StringLiteral(\"\")})\n"; - OS << "#undef COMMA\n"; - OS << "#endif // PREFIX_UNION\n\n"; + OS << "\n};\n"; + OS << "#endif // OPTTABLE_PREFIXES_UNION_CODE\n\n"; // Dump groups. OS << "/////////\n"; @@ -337,11 +373,12 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { // Start a single option entry. OS << "OPTION("; - // The option prefix; - OS << "llvm::ArrayRef<llvm::StringLiteral>()"; + // A zero prefix offset corresponds to an empty set of prefixes. + OS << "0 /* no prefixes */"; - // The option string. - OS << ", \"" << R.getValueAsString("Name") << '"'; + // The option string offset. + OS << ", "; + writeStrTableOffset(OS, Table, R.getValueAsString("Name")); // The option identifier name. OS << ", " << getOptionName(R); @@ -387,7 +424,7 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) { OS << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())] << ", "; // The option prefixed name. - writeCstring(OS, getOptionPrefixedName(R)); + writeStrTableOffset(OS, Table, getOptionPrefixedName(R)); // The option identifier name. OS << ", " << getOptionName(R); |