Author: David Spickett Date: 2024-04-05T08:27:59Z New Revision: aff197ff2163a4b7732d08b833906cc21f4a5c89
URL: https://github.com/llvm/llvm-project/commit/aff197ff2163a4b7732d08b833906cc21f4a5c89 DIFF: https://github.com/llvm/llvm-project/commit/aff197ff2163a4b7732d08b833906cc21f4a5c89.diff LOG: Reland "[flang][clang] Add Visibility specific help text for options (#81869)" This reverts commit 67d20412b448533c77f54ac7a1e5d0775d273729. This includes fixes for clanginstallapi. Added: Modified: clang-tools-extra/clangd/CompileCommands.cpp clang/include/clang/Driver/Options.td clang/lib/Frontend/CompilerInvocation.cpp clang/tools/clang-installapi/Options.cpp clang/tools/clang-installapi/Options.h clang/utils/TableGen/ClangOptionDocEmitter.cpp flang/test/Driver/driver-help-hidden.f90 flang/test/Driver/driver-help.f90 lld/MachO/DriverUtils.cpp lld/MinGW/Driver.cpp lld/wasm/Driver.cpp llvm/include/llvm/Option/OptParser.td llvm/include/llvm/Option/OptTable.h llvm/lib/Option/OptTable.cpp llvm/unittests/Option/OptionMarshallingTest.cpp llvm/utils/TableGen/OptParserEmitter.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index 5b8128fca62668..fddfffe7523d95 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -466,7 +466,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) { static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \ NAME##_init, std::size(NAME##_init) - 1); #define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELP, METAVAR, VALUES) \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, VALUES) \ Prefixes[DriverID::OPT_##ID] = PREFIX; #include "clang/Driver/Options.inc" #undef OPTION @@ -478,7 +479,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) { const void *AliasArgs; } AliasTable[] = { #define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELP, METAVAR, VALUES) \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, VALUES) \ {DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS}, #include "clang/Driver/Options.inc" #undef OPTION diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 12e8dc7912c3b8..f051bca6c1e953 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3409,10 +3409,16 @@ def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, HelpText<"Parse OpenMP pragmas and generate parallel code.">; def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>; +class OpenMPVersionHelp<string program, string default> { + string str = !strconcat( + "Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is ", + default, " for ", program); +} def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, - HelpText<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 51 for Clang">; + HelpText<OpenMPVersionHelp<"Clang", "51">.str>, + HelpTextForVariants<[FlangOption, FC1Option], OpenMPVersionHelp<"Flang", "11">.str>; defm openmp_extensions: BoolFOption<"openmp-extensions", LangOpts<"OpenMPExtensions">, DefaultTrue, PosFlag<SetTrue, [NoArgumentUnused], [ClangOption, CC1Option], diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index c5bfb8ef1b5607..1f1f5440ddd75f 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -533,10 +533,10 @@ static T extractMaskValue(T KeyPath) { #define PARSE_OPTION_WITH_MARSHALLING( \ ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, \ - ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, \ - NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ - if ((VISIBILITY)&options::CC1Option) { \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ + SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ + IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + if ((VISIBILITY) & options::CC1Option) { \ KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \ if (IMPLIED_CHECK) \ KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \ @@ -550,10 +550,10 @@ static T extractMaskValue(T KeyPath) { // with lifetime extension of the reference. #define GENERATE_OPTION_WITH_MARSHALLING( \ CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \ - KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \ - DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ - if ((VISIBILITY)&options::CC1Option) { \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ + SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ + IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + if ((VISIBILITY) & options::CC1Option) { \ [&](const auto &Extracted) { \ if (ALWAYS_EMIT || \ (Extracted != \ diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index c4f39b7c841742..04d5e3cbb9d68c 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -45,9 +45,21 @@ static constexpr const ArrayRef<StringLiteral> /// Create table mapping all options defined in InstallAPIOpts.td. static constexpr OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ - {PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \ - PARAM, FLAGS, VISIBILITY, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ + VALUES) \ + {PREFIX, \ + NAME, \ + HELPTEXT, \ + HELPTEXTSFORVARIANTS, \ + METAVAR, \ + OPT_##ID, \ + Option::KIND##Class, \ + PARAM, \ + FLAGS, \ + VISIBILITY, \ + OPT_##GROUP, \ + OPT_##ALIAS, \ + ALIASARGS, \ VALUES}, #include "InstallAPIOpts.inc" #undef OPTION diff --git a/clang/tools/clang-installapi/Options.h b/clang/tools/clang-installapi/Options.h index 82e04b49d12596..cd74722c92c893 100644 --- a/clang/tools/clang-installapi/Options.h +++ b/clang/tools/clang-installapi/Options.h @@ -144,7 +144,8 @@ class Options { enum ID { OPT_INVALID = 0, // This is not an option ID. #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ + VALUES) \ OPT_##ID, #include "InstallAPIOpts.inc" LastOption diff --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp index 3fe98909940749..86835611b84218 100644 --- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp +++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp @@ -359,8 +359,38 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo, // Emit the description, if we have one. const Record *R = Option.Option; - std::string Description = - getRSTStringWithTextFallback(R, "DocBrief", "HelpText"); + std::string Description; + + // Prefer a program specific help string. + // This is a list of (visibilities, string) pairs. + std::vector<Record *> VisibilitiesHelp = + R->getValueAsListOfDefs("HelpTextsForVariants"); + for (Record *VisibilityHelp : VisibilitiesHelp) { + // This is a list of visibilities. + ArrayRef<Init *> Visibilities = + VisibilityHelp->getValueAsListInit("Visibilities")->getValues(); + + // See if any of the program's visibilities are in the list. + for (StringRef DocInfoMask : + DocInfo->getValueAsListOfStrings("VisibilityMask")) { + for (Init *Visibility : Visibilities) { + if (Visibility->getAsUnquotedString() == DocInfoMask) { + // Use the first one we find. + Description = escapeRST(VisibilityHelp->getValueAsString("Text")); + break; + } + } + if (!Description.empty()) + break; + } + + if (!Description.empty()) + break; + } + + // If there's not a program specific string, use the default one. + if (Description.empty()) + Description = getRSTStringWithTextFallback(R, "DocBrief", "HelpText"); if (!isa<UnsetInit>(R->getValueInit("Values"))) { if (!Description.empty() && Description.back() != '.') diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 index 4405b64a8d0090..48f48f5384fdc5 100644 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -81,7 +81,7 @@ ! CHECK-NEXT: -fopenmp-targets=<value> ! CHECK-NEXT: Specify comma-separated list of triples OpenMP offloading targets to be supported ! CHECK-NEXT: -fopenmp-version=<value> -! CHECK-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 51 for Clang +! CHECK-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang ! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! CHECK-NEXT: -foptimization-record-file=<file> ! CHECK-NEXT: Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch <arch> options. diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index c80453f0ef21ba..38f74395a678ab 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -69,7 +69,7 @@ ! HELP-NEXT: -fopenmp-targets=<value> ! HELP-NEXT: Specify comma-separated list of triples OpenMP offloading targets to be supported ! HELP-NEXT: -fopenmp-version=<value> -! HELP-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 51 for Clang +! HELP-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang ! HELP-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! HELP-NEXT: -foptimization-record-file=<file> ! HELP-NEXT: Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch <arch> options. @@ -226,7 +226,7 @@ ! HELP-FC1-NEXT: Generate code only for an OpenMP target device. ! HELP-FC1-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL ! HELP-FC1-NEXT: -fopenmp-version=<value> -! HELP-FC1-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 51 for Clang +! HELP-FC1-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang ! HELP-FC1-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! HELP-FC1-NEXT: -fpass-plugin=<dsopath> Load pass plugin from a dynamic shared object file (only with new pass manager). ! HELP-FC1-NEXT: -fppc-native-vector-element-order diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index d6f18ecb85b8a8..077a639bf7ab1e 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -45,11 +45,21 @@ using namespace lld::macho; // Create table mapping all options defined in Options.td static constexpr OptTable::Info optInfo[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ - {PREFIX, NAME, HELPTEXT, \ - METAVAR, OPT_##ID, opt::Option::KIND##Class, \ - PARAM, FLAGS, VISIBILITY, \ - OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ + VALUES) \ + {PREFIX, \ + NAME, \ + HELPTEXT, \ + HELPTEXTSFORVARIANTS, \ + METAVAR, \ + OPT_##ID, \ + opt::Option::KIND##Class, \ + PARAM, \ + FLAGS, \ + VISIBILITY, \ + OPT_##GROUP, \ + OPT_##ALIAS, \ + ALIASARGS, \ VALUES}, #include "Options.inc" #undef OPTION diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp index bb08c77b2e11d4..0d55d5b3672a40 100644 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -69,11 +69,21 @@ enum { // Create table mapping all options defined in Options.td static constexpr opt::OptTable::Info infoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ - {PREFIX, NAME, HELPTEXT, \ - METAVAR, OPT_##ID, opt::Option::KIND##Class, \ - PARAM, FLAGS, VISIBILITY, \ - OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ + VALUES) \ + {PREFIX, \ + NAME, \ + HELPTEXT, \ + HELPTEXTSFORVARIANTS, \ + METAVAR, \ + OPT_##ID, \ + opt::Option::KIND##Class, \ + PARAM, \ + FLAGS, \ + VISIBILITY, \ + OPT_##GROUP, \ + OPT_##ALIAS, \ + ALIASARGS, \ VALUES}, #include "Options.inc" #undef OPTION diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index df7d4d1cc3d679..d5d763b0a4ae17 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -132,11 +132,21 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, // Create table mapping all options defined in Options.td static constexpr opt::OptTable::Info optInfo[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ - {PREFIX, NAME, HELPTEXT, \ - METAVAR, OPT_##ID, opt::Option::KIND##Class, \ - PARAM, FLAGS, VISIBILITY, \ - OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ + VALUES) \ + {PREFIX, \ + NAME, \ + HELPTEXT, \ + HELPTEXTSFORVARIANTS, \ + METAVAR, \ + OPT_##ID, \ + opt::Option::KIND##Class, \ + PARAM, \ + FLAGS, \ + VISIBILITY, \ + OPT_##GROUP, \ + OPT_##ALIAS, \ + ALIASARGS, \ VALUES}, #include "Options.inc" #undef OPTION diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td index 7bbee1da643b8c..9fd606b0d6fcb0 100644 --- a/llvm/include/llvm/Option/OptParser.td +++ b/llvm/include/llvm/Option/OptParser.td @@ -93,6 +93,11 @@ class OptionGroup<string name> { // Define the option class. +class HelpTextVariant<list<OptionVisibility> visibilities, string text> { + list<OptionVisibility> Visibilities = visibilities; + string Text = text; +} + class Option<list<string> prefixes, string name, OptionKind kind> { string EnumName = ?; // Uses the def name if undefined. list<string> Prefixes = prefixes; @@ -101,6 +106,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> { // Used by MultiArg option kind. int NumArgs = 0; string HelpText = ?; + list<HelpTextVariant> HelpTextsForVariants = []; string MetaVarName = ?; string Values = ?; code ValuesCode = ?; @@ -155,6 +161,12 @@ class Visibility<list<OptionVisibility> visibility> { } class Group<OptionGroup group> { OptionGroup Group = group; } class HelpText<string text> { string HelpText = text; } +class HelpTextForVariants<list<OptionVisibility> Visibilities, string text> { + list<HelpTextVariant> HelpTextsForVariants = [ + HelpTextVariant<Visibilities, text> + ]; +} + class MetaVarName<string name> { string MetaVarName = name; } class Values<string value> { string Values = value; } class ValuesCode<code valuecode> { code ValuesCode = valuecode; } diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h index bb3b665a16319f..d8bf292bac21aa 100644 --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -58,6 +58,17 @@ class OptTable { ArrayRef<StringLiteral> Prefixes; StringLiteral PrefixedName; 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 + // visibilities. If no help text is found in this list for the visibility of + // the program, HelpText is used instead. This cannot use std::vector + // because OptTable is used in constexpr contexts. Increase the array sizes + // here if you need more entries and adjust the constants in + // OptParserEmitter::EmitHelpTextsForVariants. + std::array<std::pair<std::array<unsigned int, 2 /*MaxVisibilityPerHelp*/>, + const char *>, + 1 /*MaxVisibilityHelp*/> + HelpTextsForVariants; const char *MetaVar; unsigned ID; unsigned char Kind; @@ -145,7 +156,20 @@ class OptTable { /// Get the help text to use to describe this option. const char *getOptionHelpText(OptSpecifier id) const { - return getInfo(id).HelpText; + return getOptionHelpText(id, Visibility(0)); + } + + // Get the help text to use to describe this option. + // If it has visibility specific help text and that visibility is in the + // visibility mask, use that text instead of the generic text. + const char *getOptionHelpText(OptSpecifier id, + Visibility VisibilityMask) const { + auto Info = getInfo(id); + for (auto [Visibilities, Text] : Info.HelpTextsForVariants) + for (auto Visibility : Visibilities) + if (VisibilityMask & Visibility) + return Text; + return Info.HelpText; } /// Get the meta-variable name to use when describing @@ -323,7 +347,8 @@ class OptTable { private: void internalPrintHelp(raw_ostream &OS, const char *Usage, const char *Title, bool ShowHidden, bool ShowAllAliases, - std::function<bool(const Info &)> ExcludeOption) const; + std::function<bool(const Info &)> ExcludeOption, + Visibility VisibilityMask) const; }; /// Specialization of OptTable @@ -358,30 +383,30 @@ class PrecomputedOptTable : public OptTable { #define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX( \ ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ + 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, \ - METAVAR, VALUES) \ - LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIX, PREFIXED_NAME, ID, KIND, \ - GROUP, ALIAS, ALIASARGS, FLAGS, VISIBILITY, \ - PARAM, HELPTEXT, METAVAR, VALUE) + 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_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \ ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ llvm::opt::OptTable::Info { \ - PREFIX, PREFIXED_NAME, HELPTEXT, METAVAR, ID_PREFIX##ID, \ - llvm::opt::Option::KIND##Class, PARAM, FLAGS, VISIBILITY, \ - ID_PREFIX##GROUP, ID_PREFIX##ALIAS, ALIASARGS, VALUES \ + PREFIX, PREFIXED_NAME, 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, \ - METAVAR, VALUES) \ + HELPTEXTSFORVARIANTS, METAVAR, VALUES) \ LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \ OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) #endif // LLVM_OPTION_OPTTABLE_H diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index cf69f6173b6d41..b8b6b90c253f23 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -710,7 +710,8 @@ void OptTable::printHelp(raw_ostream &OS, const char *Usage, const char *Title, OS, Usage, Title, ShowHidden, ShowAllAliases, [VisibilityMask](const Info &CandidateInfo) -> bool { return (CandidateInfo.Visibility & VisibilityMask) == 0; - }); + }, + VisibilityMask); } void OptTable::printHelp(raw_ostream &OS, const char *Usage, const char *Title, @@ -726,13 +727,14 @@ void OptTable::printHelp(raw_ostream &OS, const char *Usage, const char *Title, if (CandidateInfo.Flags & FlagsToExclude) return true; return false; - }); + }, + Visibility(0)); } void OptTable::internalPrintHelp( raw_ostream &OS, const char *Usage, const char *Title, bool ShowHidden, - bool ShowAllAliases, - std::function<bool(const Info &)> ExcludeOption) const { + bool ShowAllAliases, std::function<bool(const Info &)> ExcludeOption, + Visibility VisibilityMask) const { OS << "OVERVIEW: " << Title << "\n\n"; OS << "USAGE: " << Usage << "\n\n"; @@ -754,11 +756,11 @@ void OptTable::internalPrintHelp( // If an alias doesn't have a help text, show a help text for the aliased // option instead. - const char *HelpText = getOptionHelpText(Id); + const char *HelpText = getOptionHelpText(Id, VisibilityMask); if (!HelpText && ShowAllAliases) { const Option Alias = getOption(Id).getAlias(); if (Alias.isValid()) - HelpText = getOptionHelpText(Alias.getID()); + HelpText = getOptionHelpText(Alias.getID(), VisibilityMask); } if (HelpText && (strlen(HelpText) != 0)) { diff --git a/llvm/unittests/Option/OptionMarshallingTest.cpp b/llvm/unittests/Option/OptionMarshallingTest.cpp index 339d825c2016bf..0464e27d5248a8 100644 --- a/llvm/unittests/Option/OptionMarshallingTest.cpp +++ b/llvm/unittests/Option/OptionMarshallingTest.cpp @@ -19,9 +19,9 @@ struct OptionWithMarshallingInfo { static const OptionWithMarshallingInfo MarshallingTable[] = { #define OPTION_WITH_MARSHALLING( \ PREFIX_TYPE, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \ - KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \ - DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + 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}, #include "Opts.inc" #undef OPTION_WITH_MARSHALLING diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp index 6334af53f88f6a..4fb1ca18ac11db 100644 --- a/llvm/utils/TableGen/OptParserEmitter.cpp +++ b/llvm/utils/TableGen/OptParserEmitter.cpp @@ -191,6 +191,62 @@ static MarshallingInfo createMarshallingInfo(const Record &R) { return Ret; } +static void EmitHelpTextsForVariants( + raw_ostream &OS, std::vector<std::pair<std::vector<std::string>, StringRef>> + HelpTextsForVariants) { + // OptTable must be constexpr so it uses std::arrays with these capacities. + const unsigned MaxVisibilityPerHelp = 2; + const unsigned MaxVisibilityHelp = 1; + + assert(HelpTextsForVariants.size() <= MaxVisibilityHelp && + "Too many help text variants to store in " + "OptTable::HelpTextsForVariants"); + + // This function must initialise any unused elements of those arrays. + for (auto [Visibilities, _] : HelpTextsForVariants) + while (Visibilities.size() < MaxVisibilityPerHelp) + Visibilities.push_back("0"); + + while (HelpTextsForVariants.size() < MaxVisibilityHelp) + HelpTextsForVariants.push_back( + {std::vector<std::string>(MaxVisibilityPerHelp, "0"), ""}); + + OS << ", (std::array<std::pair<std::array<unsigned, " << MaxVisibilityPerHelp + << ">, const char*>, " << MaxVisibilityHelp << ">{{ "; + + auto VisibilityHelpEnd = HelpTextsForVariants.cend(); + for (auto VisibilityHelp = HelpTextsForVariants.cbegin(); + VisibilityHelp != VisibilityHelpEnd; ++VisibilityHelp) { + auto [Visibilities, Help] = *VisibilityHelp; + + assert(Visibilities.size() <= MaxVisibilityPerHelp && + "Too many visibilities to store in an " + "OptTable::HelpTextsForVariants entry"); + OS << "std::make_pair(std::array<unsigned, " << MaxVisibilityPerHelp + << ">{{"; + + auto VisibilityEnd = Visibilities.cend(); + for (auto Visibility = Visibilities.cbegin(); Visibility != VisibilityEnd; + ++Visibility) { + OS << *Visibility; + if (std::next(Visibility) != VisibilityEnd) + OS << ", "; + } + + OS << "}}, "; + + if (Help.size()) + write_cstring(OS, Help); + else + OS << "nullptr"; + OS << ")"; + + if (std::next(VisibilityHelp) != VisibilityHelpEnd) + OS << ", "; + } + OS << " }})"; +} + /// OptParserEmitter - This tablegen backend takes an input .td file /// describing a list of options and emits a data structure for parsing and /// working with those options when given an input command line. @@ -312,6 +368,9 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { } else OS << ", nullptr"; + // Not using Visibility specific text for group help. + EmitHelpTextsForVariants(OS, {}); + // The option meta-variable name (unused). OS << ", nullptr"; @@ -410,6 +469,22 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { } else OS << ", nullptr"; + std::vector<std::pair<std::vector<std::string>, StringRef>> + HelpTextsForVariants; + for (Record *VisibilityHelp : + R.getValueAsListOfDefs("HelpTextsForVariants")) { + ArrayRef<Init *> Visibilities = + VisibilityHelp->getValueAsListInit("Visibilities")->getValues(); + + std::vector<std::string> VisibilityNames; + for (Init *Visibility : Visibilities) + VisibilityNames.push_back(Visibility->getAsUnquotedString()); + + HelpTextsForVariants.push_back(std::make_pair( + VisibilityNames, VisibilityHelp->getValueAsString("Text"))); + } + EmitHelpTextsForVariants(OS, HelpTextsForVariants); + // The option meta-variable name. OS << ", "; if (!isa<UnsetInit>(R.getValueInit("MetaVarName"))) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits