diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index 957a6f873e102..00f4c4ca9fef0 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -493,8 +493,8 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) { static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ static constexpr llvm::ArrayRef NAME( \ NAME##_init, std::size(NAME##_init) - 1); -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELP, METAVAR, VALUES) \ +#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, PARAM, HELP, METAVAR, VALUES) \ Prefixes[DriverID::OPT_##ID] = PREFIX; #include "clang/Driver/Options.inc" #undef OPTION @@ -505,8 +505,8 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) { DriverID AliasID; const void *AliasArgs; } AliasTable[] = { -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELP, METAVAR, VALUES) \ +#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, PARAM, HELP, METAVAR, VALUES) \ {DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS}, #include "clang/Driver/Options.inc" #undef OPTION diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index b34003041373f..60f5eed8e2d72 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -238,7 +238,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, } void Driver::setDriverMode(StringRef Value) { - static const std::string OptName = + static StringRef OptName = getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); if (auto M = llvm::StringSwitch>(Value) .Case("gcc", GCCMode) @@ -6554,7 +6554,7 @@ bool clang::driver::willEmitRemarks(const ArgList &Args) { llvm::StringRef clang::driver::getDriverMode(StringRef ProgName, ArrayRef Args) { - static const std::string OptName = + static StringRef OptName = getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName(); llvm::StringRef Opt; for (StringRef Arg : Args) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index be53ce3e47265..c4082db009073 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -422,8 +422,8 @@ static T extractMaskValue(T KeyPath) { } #define PARSE_OPTION_WITH_MARSHALLING( \ - ARGS, DIAGS, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, \ + ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \ KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \ DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ if ((FLAGS)&options::CC1Option) { \ @@ -439,10 +439,10 @@ static T extractMaskValue(T KeyPath) { // Capture the extracted value as a lambda argument to avoid potential issues // with lifetime extension of the reference. #define GENERATE_OPTION_WITH_MARSHALLING( \ - CONSUMER, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, \ - KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \ - DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ + DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \ + MERGER, EXTRACTOR, TABLE_INDEX) \ if ((FLAGS)&options::CC1Option) { \ [&](const auto &Extracted) { \ if (ALWAYS_EMIT || \ diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index dc82a1f3772dd..e292fa724d2bb 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -276,14 +276,14 @@ void addTargetAndModeForProgramName(std::vector &CommandLine, return; const auto &Table = driver::getDriverOptTable(); // --target=X - const std::string TargetOPT = + StringRef TargetOPT = Table.getOption(driver::options::OPT_target).getPrefixedName(); // -target X - const std::string TargetOPTLegacy = + StringRef TargetOPTLegacy = Table.getOption(driver::options::OPT_target_legacy_spelling) .getPrefixedName(); // --driver-mode=X - const std::string DriverModeOPT = + StringRef DriverModeOPT = Table.getOption(driver::options::OPT_driver_mode).getPrefixedName(); auto TargetMode = driver::ToolChain::getTargetAndModeFromProgramName(InvokedAs); @@ -303,7 +303,7 @@ void addTargetAndModeForProgramName(std::vector &CommandLine, } if (ShouldAddTarget) { CommandLine.insert(++CommandLine.begin(), - TargetOPT + TargetMode.TargetPrefix); + (TargetOPT + TargetMode.TargetPrefix).str()); } } diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h index ef7d05d6a1ee9..092f41e0ff5a5 100644 --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -44,7 +44,7 @@ class OptTable { /// A null terminated array of prefix strings to apply to name while /// matching. ArrayRef Prefixes; - StringRef Name; + StringLiteral PrefixedName; const char *HelpText; const char *MetaVar; unsigned ID; @@ -55,6 +55,11 @@ class OptTable { unsigned short AliasID; const char *AliasArgs; const char *Values; + + StringRef getName() const { + unsigned PrefixLength = Prefixes.empty() ? 0 : Prefixes[0].size(); + return PrefixedName.drop_front(PrefixLength); + } }; private: @@ -111,7 +116,9 @@ class OptTable { const Option getOption(OptSpecifier Opt) const; /// Lookup the name of the given option. - StringRef getOptionName(OptSpecifier id) const { return getInfo(id).Name; } + StringRef getOptionName(OptSpecifier id) const { + return getInfo(id).getName(); + } /// Get the kind of the given option. unsigned getOptionKind(OptSpecifier id) const { @@ -298,31 +305,31 @@ class PrecomputedOptTable : public OptTable { } // end namespace llvm -#define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(ID_PREFIX, PREFIX, NAME, ID, KIND, \ - GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELPTEXT, METAVAR, VALUES) \ +#define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(ID_PREFIX, PREFIX, PREFIXED_NAME, ID, \ + KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + PARAM, HELPTEXT, METAVAR, VALUES) \ ID_PREFIX##ID -#define LLVM_MAKE_OPT_ID(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \ - LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIX, NAME, ID, KIND, GROUP, ALIAS, \ - ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, \ - VALUE) +#define LLVM_MAKE_OPT_ID(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \ + ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \ + LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIX, PREFIXED_NAME, ID, KIND, \ + GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUE) #define LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \ - ID_PREFIX, PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELPTEXT, METAVAR, VALUES) \ + ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \ llvm::opt::OptTable::Info { \ - PREFIX, NAME, HELPTEXT, METAVAR, ID_PREFIX##ID, \ + PREFIX, PREFIXED_NAME, HELPTEXT, METAVAR, ID_PREFIX##ID, \ llvm::opt::Option::KIND##Class, PARAM, FLAGS, ID_PREFIX##GROUP, \ ID_PREFIX##ALIAS, ALIASARGS, VALUES \ } -#define LLVM_CONSTRUCT_OPT_INFO(PREFIX, NAME, ID, KIND, GROUP, ALIAS, \ +#define LLVM_CONSTRUCT_OPT_INFO(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \ ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, \ VALUES) \ - LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(OPT_, PREFIX, NAME, ID, KIND, GROUP, \ - ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELPTEXT, METAVAR, VALUES) + LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(OPT_, PREFIX, PREFIXED_NAME, ID, \ + KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + PARAM, HELPTEXT, METAVAR, VALUES) #endif // LLVM_OPTION_OPTTABLE_H diff --git a/llvm/include/llvm/Option/Option.h b/llvm/include/llvm/Option/Option.h index 9b35e81cd9914..2460bbedd21f5 100644 --- a/llvm/include/llvm/Option/Option.h +++ b/llvm/include/llvm/Option/Option.h @@ -97,7 +97,7 @@ class Option { /// Get the name of this option without any prefix. StringRef getName() const { assert(Info && "Must have a valid info!"); - return Info->Name; + return Info->getName(); } const Option getGroup() const { @@ -130,10 +130,9 @@ class Option { } /// Get the name of this option with the default prefix. - std::string getPrefixedName() const { - std::string Ret(getPrefix()); - Ret += getName(); - return Ret; + StringLiteral getPrefixedName() const { + assert(Info && "Must have a valid info!"); + return Info->PrefixedName; } /// Get the help text for this option. diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index 3f53ac119c69e..3d7bef8af0dbc 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -59,7 +59,7 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { if (&A == &B) return false; - if (int N = StrCmpOptionName(A.Name, B.Name)) + if (int N = StrCmpOptionName(A.getName(), B.getName())) return N < 0; for (size_t I = 0, K = std::min(A.Prefixes.size(), B.Prefixes.size()); I != K; @@ -77,7 +77,7 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { // Support lower_bound between info and an option name. static inline bool operator<(const OptTable::Info &I, StringRef Name) { - return StrCmpOptionNameIgnoreCase(I.Name, Name) < 0; + return StrCmpOptionNameIgnoreCase(I.getName(), Name) < 0; } } // end namespace opt @@ -163,10 +163,10 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str, for (auto Prefix : I->Prefixes) { if (Str.startswith(Prefix)) { StringRef Rest = Str.substr(Prefix.size()); - bool Matched = IgnoreCase ? Rest.starts_with_insensitive(I->Name) - : Rest.startswith(I->Name); + bool Matched = IgnoreCase ? Rest.starts_with_insensitive(I->getName()) + : Rest.startswith(I->getName()); if (Matched) - return Prefix.size() + StringRef(I->Name).size(); + return Prefix.size() + StringRef(I->getName()).size(); } } return 0; @@ -175,8 +175,8 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str, // 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.endswith(In.Name)) - if (Option.slice(0, Option.size() - In.Name.size()) == Prefix) + if (Option.endswith(In.getName())) + if (Option.slice(0, Option.size() - In.getName().size()) == Prefix) return true; return false; } @@ -215,7 +215,7 @@ OptTable::findByPrefix(StringRef Cur, unsigned int DisableFlags) const { continue; for (auto Prefix : In.Prefixes) { - std::string S = (Prefix + In.Name + "\t").str(); + std::string S = (Prefix + In.getName() + "\t").str(); if (In.HelpText) S += In.HelpText; if (StringRef(S).startswith(Cur) && S != std::string(Cur) + "\t") @@ -240,7 +240,7 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString, for (const Info &CandidateInfo : ArrayRef(OptionInfos).drop_front(FirstSearchableIndex)) { - StringRef CandidateName = CandidateInfo.Name; + StringRef CandidateName = CandidateInfo.getName(); // We can eliminate some option prefix/name pairs as candidates right away: // * Ignore option candidates with empty names, such as "--", or names @@ -529,7 +529,7 @@ InputArgList OptTable::parseArgs(int Argc, char *const *Argv, static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { const Option O = Opts.getOption(Id); - std::string Name = O.getPrefixedName(); + std::string Name = O.getPrefixedName().str(); // Add metavar, if used. switch (O.getKind()) { diff --git a/llvm/unittests/Option/OptionMarshallingTest.cpp b/llvm/unittests/Option/OptionMarshallingTest.cpp index c4d48acc7a3f9..d932095084539 100644 --- a/llvm/unittests/Option/OptionMarshallingTest.cpp +++ b/llvm/unittests/Option/OptionMarshallingTest.cpp @@ -10,7 +10,7 @@ #include "gtest/gtest.h" struct OptionWithMarshallingInfo { - llvm::StringRef Name; + llvm::StringLiteral PrefixedName; const char *KeyPath; const char *ImpliedCheck; const char *ImpliedValue; @@ -18,20 +18,20 @@ struct OptionWithMarshallingInfo { static const OptionWithMarshallingInfo MarshallingTable[] = { #define OPTION_WITH_MARSHALLING( \ - PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ + PREFIX_TYPE, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \ MERGER, EXTRACTOR, TABLE_INDEX) \ - {NAME, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE}, + {PREFIXED_NAME, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE}, #include "Opts.inc" #undef OPTION_WITH_MARSHALLING }; TEST(OptionMarshalling, EmittedOrderSameAsDefinitionOrder) { - ASSERT_STREQ(MarshallingTable[0].Name.data(), "marshalled-flag-d"); - ASSERT_STREQ(MarshallingTable[1].Name.data(), "marshalled-flag-c"); - ASSERT_STREQ(MarshallingTable[2].Name.data(), "marshalled-flag-b"); - ASSERT_STREQ(MarshallingTable[3].Name.data(), "marshalled-flag-a"); + 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"); } TEST(OptionMarshalling, EmittedSpecifiedKeyPath) { diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp index a04680b5d91e1..ff9736781ce20 100644 --- a/llvm/utils/TableGen/OptParserEmitter.cpp +++ b/llvm/utils/TableGen/OptParserEmitter.cpp @@ -34,30 +34,14 @@ static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { return OS; } -static std::string getOptionSpelling(const Record &R, size_t &PrefixLength) { +static std::string getOptionPrefixedName(const Record &R) { std::vector Prefixes = R.getValueAsListOfStrings("Prefixes"); StringRef Name = R.getValueAsString("Name"); - if (Prefixes.empty()) { - PrefixLength = 0; + if (Prefixes.empty()) return Name.str(); - } - - PrefixLength = Prefixes[0].size(); - return (Twine(Prefixes[0]) + Twine(Name)).str(); -} -static std::string getOptionSpelling(const Record &R) { - size_t PrefixLength; - return getOptionSpelling(R, PrefixLength); -} - -static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) { - size_t PrefixLength; - OS << "llvm::StringLiteral("; - write_cstring( - OS, StringRef(getOptionSpelling(R, PrefixLength)).substr(PrefixLength)); - OS << ")"; + return (Prefixes[0] + Twine(Name)).str(); } class MarshallingInfo { @@ -105,8 +89,6 @@ struct SimpleEnumValueTable { } void emit(raw_ostream &OS) const { - write_cstring(OS, StringRef(getOptionSpelling(R))); - OS << ", "; OS << ShouldParse; OS << ", "; OS << ShouldAlwaysEmit; @@ -346,8 +328,8 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { std::vector RPrefixes = R.getValueAsListOfStrings("Prefixes"); OS << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())] << ", "; - // The option string. - emitNameUsingSpelling(OS, R); + // The option prefixed name. + write_cstring(OS, getOptionPrefixedName(R)); // The option identifier name. OS << ", " << getOptionName(R);