[clang] [clang-tools-extra] [flang] [lld] [llvm] [flang][clang] Add Visibility specific help text for options (PR #81869)

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 12 08:06:30 PDT 2024


https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/81869

>From 72bbd9d38cb6e292d92391fcf04154cfbc336192 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Thu, 15 Feb 2024 09:52:22 +0000
Subject: [PATCH 1/9] [flang][clang] Add Visibility specific help text for
 options

And use it to print the correct default OpenMP version for flang.

This change adds an optional HelpTextForVisibility to options.
This allows you to change the help text (shown in documentation
and --help) for one specific visibility.

It could be generalised to a list, but we only need to pick out
flang right now so I've kept it simple but not so simple that it's
"if flang else".

For example the OpenMP option will show one default value for
Clang and another for Flang. Clang will use the existing HelpText
string.

I have not applied this to group descriptions just because
I don't know of one that needs changing. It could easily be
enabled for those too if needed. There are minor changes to them
just to get it all to compile.

This approach of storing many help strings per option in the 1
driver library seemed perferrable to making a whole new library
for Flang (even if that would mostly be including stuff from Clang).
---
 clang/include/clang/Driver/Options.td         |  5 ++-
 clang/lib/Frontend/CompilerInvocation.cpp     | 16 ++++----
 .../utils/TableGen/ClangOptionDocEmitter.cpp  | 21 +++++++++-
 flang/test/Driver/driver-help-hidden.f90      |  2 +-
 flang/test/Driver/driver-help.f90             |  2 +-
 lld/MachO/DriverUtils.cpp                     | 20 ++++++---
 lld/MinGW/Driver.cpp                          | 20 ++++++---
 lld/wasm/Driver.cpp                           | 20 ++++++---
 llvm/include/llvm/Option/OptParser.td         | 10 +++++
 llvm/include/llvm/Option/OptTable.h           | 41 +++++++++++++------
 llvm/lib/Option/OptTable.cpp                  | 14 ++++---
 .../Option/OptionMarshallingTest.cpp          |  6 +--
 llvm/utils/TableGen/OptParserEmitter.cpp      | 16 ++++++++
 13 files changed, 143 insertions(+), 50 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3a028fadb25b18..765d5fbc1e692d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3385,7 +3385,10 @@ def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>,
 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<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 51 for Clang">,
+  HelpForVisibility<HelpTextForVisibility<FlangOption,
+    "Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang"
+  >>;
 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 8d7b75b56d6129..790b0fb51cbfbd 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -522,10 +522,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, HELPTEXTFORVISIBILITY, 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);                                \
@@ -539,10 +539,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, HELPTEXTFORVISIBILITY, 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/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index 3fe98909940749..1ad3fcc3d76b82 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -359,8 +359,25 @@ 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.
+  if (!isa<UnsetInit>(R->getValueInit("HelpTextForVisibility"))) {
+    const Record *VisibilityHelp = R->getValueAsDef("HelpTextForVisibility");
+    std::string VisibilityStr =
+        VisibilityHelp->getValue("Visibility")->getValue()->getAsString();
+
+    for (StringRef Mask : DocInfo->getValueAsListOfStrings("VisibilityMask")) {
+      if (VisibilityStr == Mask) {
+        Description = escapeRST(VisibilityHelp->getValueAsString("Text"));
+        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 44dbac44772b29..94f2f4d1f522ec 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -83,7 +83,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 b4280a454e3128..31bc67e1742482 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.
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index d6f18ecb85b8a8..ea86b8074b146b 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, HELPTEXTFORVISIBILITY, METAVAR,    \
+               VALUES)                                                         \
+  {PREFIX,                                                                     \
+   NAME,                                                                       \
+   HELPTEXT,                                                                   \
+   HELPTEXTFORVISIBILITY,                                                      \
+   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 efd643f9a32203..3a1eb082d9df2b 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, HELPTEXTFORVISIBILITY, METAVAR,    \
+               VALUES)                                                         \
+  {PREFIX,                                                                     \
+   NAME,                                                                       \
+   HELPTEXT,                                                                   \
+   HELPTEXTFORVISIBILITY,                                                      \
+   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 635f19f78b15e6..79dda5a41a4001 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, HELPTEXTFORVISIBILITY, METAVAR,    \
+               VALUES)                                                         \
+  {PREFIX,                                                                     \
+   NAME,                                                                       \
+   HELPTEXT,                                                                   \
+   HELPTEXTFORVISIBILITY,                                                      \
+   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..67757ad91b8a5d 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 HelpTextForVisibility<OptionVisibility visibility, string text> {
+  OptionVisibility Visibility = visibility;
+  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 = ?;
+  HelpTextForVisibility HelpTextForVisibility = ?;
   string MetaVarName = ?;
   string Values = ?;
   code ValuesCode = ?;
@@ -155,6 +161,10 @@ class Visibility<list<OptionVisibility> visibility> {
 }
 class Group<OptionGroup group> { OptionGroup Group = group; }
 class HelpText<string text> { string HelpText = text; }
+class HelpForVisibility<HelpTextForVisibility text> {
+  HelpTextForVisibility HelpTextForVisibility = 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..457a46a269c83a 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -58,6 +58,7 @@ class OptTable {
     ArrayRef<StringLiteral> Prefixes;
     StringLiteral PrefixedName;
     const char *HelpText;
+    std::pair<unsigned int, const char *> HelpForVisibility;
     const char *MetaVar;
     unsigned ID;
     unsigned char Kind;
@@ -145,7 +146,18 @@ 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);
+    if (VisibilityMask & Info.HelpForVisibility.first)
+      return Info.HelpForVisibility.second;
+    return Info.HelpText;
   }
 
   /// Get the meta-variable name to use when describing
@@ -323,7 +335,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 +371,32 @@ 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, HELPTEXTFORVISIBILITY, 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)
+                         HELPTEXTFORVISIBILITY, METAVAR, VALUES)               \
+  LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(                                             \
+      OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,   \
+      VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITY, 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, HELPTEXTFORVISIBILITY, 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, HELPTEXTFORVISIBILITY, 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)                               \
+                                HELPTEXTFORVISIBILITY, 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, HELPTEXTFORVISIBILITY, 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..97fbc118d1fc17 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, HELPTEXTFORVISIBILITY, 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 c25f6c59cab383..6da8f1d182c187 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -312,6 +312,9 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     } else
       OS << ", nullptr";
 
+    // Not using Visibility specific text for group help.
+    OS << ", std::make_pair(0, nullptr)";
+
     // The option meta-variable name (unused).
     OS << ", nullptr";
 
@@ -410,6 +413,19 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     } else
       OS << ", nullptr";
 
+    // Help text specific to a certain visibility.
+    if (isa<UnsetInit>(R.getValueInit("HelpTextForVisibility")))
+      OS << ", std::make_pair(0, nullptr)";
+    else {
+      const Record *VisibilityHelp = R.getValueAsDef("HelpTextForVisibility");
+      const RecordVal *Visibility = VisibilityHelp->getValue("Visibility");
+      Init *VisibilityInit = Visibility->getValue();
+      std::string VisibilityStr = VisibilityInit->getAsString();
+      StringRef Text = VisibilityHelp->getValueAsString("Text");
+      OS << ", std::make_pair(options::" << VisibilityStr << ", \"" << Text
+         << "\")";
+    }
+
     // The option meta-variable name.
     OS << ", ";
     if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))

>From 6006643ccf44faecc46446d08e6e23046e2952c7 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Thu, 15 Feb 2024 16:29:29 +0000
Subject: [PATCH 2/9] Fix clangd compile

---
 clang-tools-extra/clangd/CompileCommands.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index 5b8128fca62668..1c9ad7ae456a62 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, HELPTEXTFORVISIBILITY,      \
+               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, HELPTEXTFORVISIBILITY,      \
+               METAVAR, VALUES)                                                \
   {DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS},
 #include "clang/Driver/Options.inc"
 #undef OPTION

>From f53898a048de8b03732aec88584e76a6dd098327 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Wed, 21 Feb 2024 10:40:11 +0000
Subject: [PATCH 3/9] List of help texts instead

---
 clang-tools-extra/clangd/CompileCommands.cpp  |  4 +-
 clang/include/clang/Driver/Options.td         | 14 +++++--
 clang/lib/Frontend/CompilerInvocation.cpp     |  4 +-
 .../utils/TableGen/ClangOptionDocEmitter.cpp  |  8 +++-
 flang/test/Driver/driver-help.f90             |  2 +-
 lld/MachO/DriverUtils.cpp                     |  4 +-
 lld/MinGW/Driver.cpp                          |  4 +-
 lld/wasm/Driver.cpp                           |  4 +-
 llvm/include/llvm/Option/OptParser.td         |  6 +--
 llvm/include/llvm/Option/OptTable.h           | 27 ++++++++-----
 .../Option/OptionMarshallingTest.cpp          |  2 +-
 llvm/utils/TableGen/OptParserEmitter.cpp      | 40 ++++++++++++++-----
 12 files changed, 78 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index 1c9ad7ae456a62..cf9fab129b3ac0 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -466,7 +466,7 @@ 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, HELPTEXT, HELPTEXTFORVISIBILITY,      \
+               FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES,    \
                METAVAR, VALUES)                                                \
   Prefixes[DriverID::OPT_##ID] = PREFIX;
 #include "clang/Driver/Options.inc"
@@ -479,7 +479,7 @@ 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, HELPTEXT, HELPTEXTFORVISIBILITY,      \
+               FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES,    \
                METAVAR, VALUES)                                                \
   {DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS},
 #include "clang/Driver/Options.inc"
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 765d5fbc1e692d..921aabdfc9026d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3382,13 +3382,19 @@ 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">,
-  HelpForVisibility<HelpTextForVisibility<FlangOption,
-    "Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang"
-  >>;
+  HelpText<OpenMPVersionHelp<"Clang", "51">.str>,
+  HelpTextForVisibilities<[
+    HelpTextForVisibility<FlangOption, OpenMPVersionHelp<"Flang", "11">.str>,
+    HelpTextForVisibility<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 790b0fb51cbfbd..b471b8438f3a72 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -522,7 +522,7 @@ static T extractMaskValue(T KeyPath) {
 
 #define PARSE_OPTION_WITH_MARSHALLING(                                         \
     ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS,     \
-    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITY, METAVAR,        \
+    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,      \
     VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK,  \
     IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX)   \
   if ((VISIBILITY) & options::CC1Option) {                                     \
@@ -539,7 +539,7 @@ 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, HELPTEXTFORVISIBILITY, METAVAR, VALUES,       \
+    VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR, VALUES,     \
     SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK,          \
     IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX)   \
   if ((VISIBILITY) & options::CC1Option) {                                     \
diff --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index 1ad3fcc3d76b82..75bc628a96bc39 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -362,8 +362,9 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
   std::string Description;
 
   // Prefer a program specific help string.
-  if (!isa<UnsetInit>(R->getValueInit("HelpTextForVisibility"))) {
-    const Record *VisibilityHelp = R->getValueAsDef("HelpTextForVisibility");
+  std::vector<Record *> VisibilitiesHelp =
+      R->getValueAsListOfDefs("HelpTextForVisibilities");
+  for (Record *VisibilityHelp : VisibilitiesHelp) {
     std::string VisibilityStr =
         VisibilityHelp->getValue("Visibility")->getValue()->getAsString();
 
@@ -373,6 +374,9 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
         break;
       }
     }
+
+    if (!Description.empty())
+      break;
   }
 
   // If there's not a program specific string, use the default one.
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 31bc67e1742482..71ba5e79daa538 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -223,7 +223,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 ea86b8074b146b..c0812f11f95a0f 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -45,12 +45,12 @@ 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, HELPTEXTFORVISIBILITY, METAVAR,    \
+               VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,  \
                VALUES)                                                         \
   {PREFIX,                                                                     \
    NAME,                                                                       \
    HELPTEXT,                                                                   \
-   HELPTEXTFORVISIBILITY,                                                      \
+   HELPTEXTFORVISIBILITIES,                                                    \
    METAVAR,                                                                    \
    OPT_##ID,                                                                   \
    opt::Option::KIND##Class,                                                   \
diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp
index 3a1eb082d9df2b..9aa3228e8ad98c 100644
--- a/lld/MinGW/Driver.cpp
+++ b/lld/MinGW/Driver.cpp
@@ -69,12 +69,12 @@ 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, HELPTEXTFORVISIBILITY, METAVAR,    \
+               VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,  \
                VALUES)                                                         \
   {PREFIX,                                                                     \
    NAME,                                                                       \
    HELPTEXT,                                                                   \
-   HELPTEXTFORVISIBILITY,                                                      \
+   HELPTEXTFORVISIBILITIES,                                                    \
    METAVAR,                                                                    \
    OPT_##ID,                                                                   \
    opt::Option::KIND##Class,                                                   \
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 79dda5a41a4001..f9b99e2a268c86 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -132,12 +132,12 @@ 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, HELPTEXTFORVISIBILITY, METAVAR,    \
+               VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,  \
                VALUES)                                                         \
   {PREFIX,                                                                     \
    NAME,                                                                       \
    HELPTEXT,                                                                   \
-   HELPTEXTFORVISIBILITY,                                                      \
+   HELPTEXTFORVISIBILITIES,                                                    \
    METAVAR,                                                                    \
    OPT_##ID,                                                                   \
    opt::Option::KIND##Class,                                                   \
diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td
index 67757ad91b8a5d..2d25631414adfb 100644
--- a/llvm/include/llvm/Option/OptParser.td
+++ b/llvm/include/llvm/Option/OptParser.td
@@ -106,7 +106,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
   // Used by MultiArg option kind.
   int NumArgs = 0;
   string HelpText = ?;
-  HelpTextForVisibility HelpTextForVisibility = ?;
+  list<HelpTextForVisibility> HelpTextForVisibilities = [];
   string MetaVarName = ?;
   string Values = ?;
   code ValuesCode = ?;
@@ -161,8 +161,8 @@ class Visibility<list<OptionVisibility> visibility> {
 }
 class Group<OptionGroup group> { OptionGroup Group = group; }
 class HelpText<string text> { string HelpText = text; }
-class HelpForVisibility<HelpTextForVisibility text> {
-  HelpTextForVisibility HelpTextForVisibility = text;
+class HelpTextForVisibilities<list<HelpTextForVisibility> texts> {
+  list<HelpTextForVisibility> HelpTextForVisibilities = texts;
 }
 
 class MetaVarName<string name> { string MetaVarName = name; }
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 457a46a269c83a..dd8b136b205a85 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -58,7 +58,11 @@ class OptTable {
     ArrayRef<StringLiteral> Prefixes;
     StringLiteral PrefixedName;
     const char *HelpText;
-    std::pair<unsigned int, const char *> HelpForVisibility;
+    // This cannot be std::vector because OptTable is used in constexpr
+    // contexts. Increase the size of this array if you need more help text
+    // variants.
+    std::array<std::pair<unsigned int, const char *>, 2>
+        HelpTextForVisibilities;
     const char *MetaVar;
     unsigned ID;
     unsigned char Kind;
@@ -150,13 +154,14 @@ class OptTable {
   }
 
   // Get the help text to use to describe this option.
-  // If it has Visibility specific help text and that visibility is in the
+  // 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);
-    if (VisibilityMask & Info.HelpForVisibility.first)
-      return Info.HelpForVisibility.second;
+    for (auto [Visibility, Text] : Info.HelpTextForVisibilities)
+      if (VisibilityMask & Visibility)
+        return Text;
     return Info.HelpText;
   }
 
@@ -371,32 +376,32 @@ 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, HELPTEXTFORVISIBILITY, METAVAR,        \
+    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,      \
     VALUES)                                                                    \
   ID_PREFIX##ID
 
 #define LLVM_MAKE_OPT_ID(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS,        \
                          ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT,        \
-                         HELPTEXTFORVISIBILITY, METAVAR, VALUES)               \
+                         HELPTEXTFORVISIBILITIES, METAVAR, VALUES)             \
   LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(                                             \
       OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,   \
-      VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITY, METAVAR, VALUE)
+      VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR, VALUE)
 
 #define LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(                                \
     ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS,       \
-    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITY, METAVAR,        \
+    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,      \
     VALUES)                                                                    \
   llvm::opt::OptTable::Info {                                                  \
-    PREFIX, PREFIXED_NAME, HELPTEXT, HELPTEXTFORVISIBILITY, METAVAR,           \
+    PREFIX, PREFIXED_NAME, HELPTEXT, HELPTEXTFORVISIBILITIES, 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, \
-                                HELPTEXTFORVISIBILITY, METAVAR, VALUES)        \
+                                HELPTEXTFORVISIBILITIES, METAVAR, VALUES)      \
   LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(                                      \
       OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,   \
-      VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITY, METAVAR, VALUES)
+      VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR, VALUES)
 
 #endif // LLVM_OPTION_OPTTABLE_H
diff --git a/llvm/unittests/Option/OptionMarshallingTest.cpp b/llvm/unittests/Option/OptionMarshallingTest.cpp
index 97fbc118d1fc17..e3985e0b847369 100644
--- a/llvm/unittests/Option/OptionMarshallingTest.cpp
+++ b/llvm/unittests/Option/OptionMarshallingTest.cpp
@@ -19,7 +19,7 @@ struct OptionWithMarshallingInfo {
 static const OptionWithMarshallingInfo MarshallingTable[] = {
 #define OPTION_WITH_MARSHALLING(                                               \
     PREFIX_TYPE, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,      \
-    VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITY, METAVAR, VALUES,       \
+    VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, 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},
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index 6da8f1d182c187..366450b0e8eaf4 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -313,7 +313,8 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
       OS << ", nullptr";
 
     // Not using Visibility specific text for group help.
-    OS << ", std::make_pair(0, nullptr)";
+    OS << ", (std::array<std::pair<unsigned, const char*>, 2>{{"
+       << "std::make_pair(0, nullptr), std::make_pair(0, nullptr)}})";
 
     // The option meta-variable name (unused).
     OS << ", nullptr";
@@ -413,18 +414,39 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     } else
       OS << ", nullptr";
 
-    // Help text specific to a certain visibility.
-    if (isa<UnsetInit>(R.getValueInit("HelpTextForVisibility")))
-      OS << ", std::make_pair(0, nullptr)";
-    else {
-      const Record *VisibilityHelp = R.getValueAsDef("HelpTextForVisibility");
-      const RecordVal *Visibility = VisibilityHelp->getValue("Visibility");
+    const unsigned MaxVisibilityHelp = 2;
+    OS << ", (std::array<std::pair<unsigned, const char*>, "
+       << MaxVisibilityHelp << ">{{";
+    unsigned NumVisibilityHelpEmitted = 0;
+
+    std::vector<Record *> VisibilitiesHelp =
+        R.getValueAsListOfDefs("HelpTextForVisibilities");
+    assert(VisibilitiesHelp.size() <= MaxVisibilityHelp &&
+           "Too many help text variants to store in "
+           "OptTable::HelpTextForVisibilities");
+
+    for (std::vector<Record *>::const_iterator VisibilityHelp =
+             VisibilitiesHelp.begin();
+         VisibilityHelp != VisibilitiesHelp.end();
+         ++VisibilityHelp, ++NumVisibilityHelpEmitted) {
+      const RecordVal *Visibility = (*VisibilityHelp)->getValue("Visibility");
       Init *VisibilityInit = Visibility->getValue();
       std::string VisibilityStr = VisibilityInit->getAsString();
-      StringRef Text = VisibilityHelp->getValueAsString("Text");
-      OS << ", std::make_pair(options::" << VisibilityStr << ", \"" << Text
+      StringRef Text = (*VisibilityHelp)->getValueAsString("Text");
+      OS << "std::make_pair(options::" << VisibilityStr << ", \"" << Text
          << "\")";
+
+      if (std::next(VisibilityHelp) != VisibilitiesHelp.end())
+        OS << ", ";
+    }
+    // Init any unused elements.
+    for (; NumVisibilityHelpEmitted < MaxVisibilityHelp;
+         ++NumVisibilityHelpEmitted) {
+      OS << "std::make_pair(0, nullptr)";
+      if ((NumVisibilityHelpEmitted + 1) != MaxVisibilityHelp)
+        OS << ", ";
     }
+    OS << "}})";
 
     // The option meta-variable name.
     OS << ", ";

>From b80b164f1a07eda6851f7ab7646d6868363afa65 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 27 Feb 2024 10:15:32 +0000
Subject: [PATCH 4/9] Explain usage

---
 llvm/include/llvm/Option/OptTable.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index dd8b136b205a85..69484504e9ac12 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -58,6 +58,8 @@ class OptTable {
     ArrayRef<StringLiteral> Prefixes;
     StringLiteral PrefixedName;
     const char *HelpText;
+    // Help text for specific visibilities. If there is no entry here for
+    // the visibility of the program, HelpText is used instead.
     // This cannot be std::vector because OptTable is used in constexpr
     // contexts. Increase the size of this array if you need more help text
     // variants.

>From 645842164044f822971b040c91438ed988eaf929 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 12 Mar 2024 11:39:47 +0000
Subject: [PATCH 5/9] Allow (many visibilities) -> single help text

---
 clang/include/clang/Driver/Options.td         |  3 +-
 .../utils/TableGen/ClangOptionDocEmitter.cpp  | 15 +++--
 llvm/include/llvm/Option/OptParser.td         |  4 +-
 llvm/include/llvm/Option/OptTable.h           | 20 ++++---
 llvm/utils/TableGen/OptParserEmitter.cpp      | 58 +++++++++++++++----
 5 files changed, 70 insertions(+), 30 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 921aabdfc9026d..36d99b8edf6e77 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3392,8 +3392,7 @@ def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
   HelpText<OpenMPVersionHelp<"Clang", "51">.str>,
   HelpTextForVisibilities<[
-    HelpTextForVisibility<FlangOption, OpenMPVersionHelp<"Flang", "11">.str>,
-    HelpTextForVisibility<FC1Option,   OpenMPVersionHelp<"Flang", "11">.str>,
+    HelpTextForVisibility<[FlangOption, FC1Option], OpenMPVersionHelp<"Flang", "11">.str>
   ]>;
 defm openmp_extensions: BoolFOption<"openmp-extensions",
   LangOpts<"OpenMPExtensions">, DefaultTrue,
diff --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index 75bc628a96bc39..cb648af00120f7 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -362,14 +362,19 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
   std::string Description;
 
   // Prefer a program specific help string.
+  // This is a list of visibilities -> string pairs.
   std::vector<Record *> VisibilitiesHelp =
       R->getValueAsListOfDefs("HelpTextForVisibilities");
   for (Record *VisibilityHelp : VisibilitiesHelp) {
-    std::string VisibilityStr =
-        VisibilityHelp->getValue("Visibility")->getValue()->getAsString();
-
-    for (StringRef Mask : DocInfo->getValueAsListOfStrings("VisibilityMask")) {
-      if (VisibilityStr == Mask) {
+    // This is a list of visibilities.
+    std::vector<StringRef> Visibilities =
+        VisibilityHelp->getValueAsListOfStrings("Visibilities");
+
+    // See if any of the program's visibilities are in the list.
+    for (StringRef DocInfoMask :
+         DocInfo->getValueAsListOfStrings("VisibilityMask")) {
+      if (std::find(Visibilities.begin(), Visibilities.end(), DocInfoMask) !=
+          Visibilities.end()) {
         Description = escapeRST(VisibilityHelp->getValueAsString("Text"));
         break;
       }
diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td
index 2d25631414adfb..24d9fe1c537dd9 100644
--- a/llvm/include/llvm/Option/OptParser.td
+++ b/llvm/include/llvm/Option/OptParser.td
@@ -93,8 +93,8 @@ class OptionGroup<string name> {
 
 // Define the option class.
 
-class HelpTextForVisibility<OptionVisibility visibility, string text> {
-  OptionVisibility Visibility = visibility;
+class HelpTextForVisibility<list<OptionVisibility> visibilities, string text> {
+  list<OptionVisibility> Visibilities = visibilities;
   string Text = text;
 }
 
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 69484504e9ac12..274e07df07fd92 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -58,12 +58,13 @@ class OptTable {
     ArrayRef<StringLiteral> Prefixes;
     StringLiteral PrefixedName;
     const char *HelpText;
-    // Help text for specific visibilities. If there is no entry here for
-    // the visibility of the program, HelpText is used instead.
-    // This cannot be std::vector because OptTable is used in constexpr
-    // contexts. Increase the size of this array if you need more help text
-    // variants.
-    std::array<std::pair<unsigned int, const char *>, 2>
+    // 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 type cannot use std::vector
+    // because OptTable is used in constexpr contexts. Increase the array sizes
+    // here if you need more entries.
+    std::array<std::pair<std::array<unsigned int, 2>, const char *>, 1>
         HelpTextForVisibilities;
     const char *MetaVar;
     unsigned ID;
@@ -161,9 +162,10 @@ class OptTable {
   const char *getOptionHelpText(OptSpecifier id,
                                 Visibility VisibilityMask) const {
     auto Info = getInfo(id);
-    for (auto [Visibility, Text] : Info.HelpTextForVisibilities)
-      if (VisibilityMask & Visibility)
-        return Text;
+    for (auto [Visibilities, Text] : Info.HelpTextForVisibilities)
+      for (auto Visibility : Visibilities)
+        if (VisibilityMask & Visibility)
+          return Text;
     return Info.HelpText;
   }
 
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index 366450b0e8eaf4..9262574e1eda27 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -313,8 +313,8 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
       OS << ", nullptr";
 
     // Not using Visibility specific text for group help.
-    OS << ", (std::array<std::pair<unsigned, const char*>, 2>{{"
-       << "std::make_pair(0, nullptr), std::make_pair(0, nullptr)}})";
+    OS << ", (std::array<std::pair<std::array<unsigned, 2>, const char*>, 1>{{"
+       << "std::make_pair(std::array<unsigned, 2>{{0, 0}}, nullptr)}})";
 
     // The option meta-variable name (unused).
     OS << ", nullptr";
@@ -414,9 +414,12 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     } else
       OS << ", nullptr";
 
-    const unsigned MaxVisibilityHelp = 2;
-    OS << ", (std::array<std::pair<unsigned, const char*>, "
-       << MaxVisibilityHelp << ">{{";
+    const unsigned MaxVisibilityHelp = 1;
+    const unsigned MaxVisibilityPerHelp = 2;
+    OS << ", (std::array<std::pair<std::array<unsigned, "
+       << MaxVisibilityPerHelp << ">, const char*>, " << MaxVisibilityHelp
+       << ">{{ ";
+
     unsigned NumVisibilityHelpEmitted = 0;
 
     std::vector<Record *> VisibilitiesHelp =
@@ -429,12 +432,34 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
              VisibilitiesHelp.begin();
          VisibilityHelp != VisibilitiesHelp.end();
          ++VisibilityHelp, ++NumVisibilityHelpEmitted) {
-      const RecordVal *Visibility = (*VisibilityHelp)->getValue("Visibility");
-      Init *VisibilityInit = Visibility->getValue();
-      std::string VisibilityStr = VisibilityInit->getAsString();
+      ListInit *Visibilities =
+          (*VisibilityHelp)->getValueAsListInit("Visibilities");
+      ArrayRef<Init *> VisibilitiesValues = Visibilities->getValues();
+      assert(VisibilitiesValues.size() <= MaxVisibilityPerHelp &&
+             "Too many visibilities to store in an "
+             "OptTable::HelpTextForVisibilities entry");
+
+      OS << "std::make_pair(std::array<unsigned, " << MaxVisibilityPerHelp
+         << ">{{";
+      unsigned NumVisibilitiesEmitted = 0;
+      for (auto Visibility = VisibilitiesValues.begin();
+           Visibility != VisibilitiesValues.end();
+           ++Visibility, ++NumVisibilitiesEmitted) {
+        OS << (*Visibility)->getAsUnquotedString();
+        if (std::next(Visibility) != VisibilitiesValues.end())
+          OS << ", ";
+      }
+      // Init unused elements.
+      for (; NumVisibilitiesEmitted < MaxVisibilityPerHelp;
+           ++NumVisibilitiesEmitted) {
+        OS << "0";
+        if ((NumVisibilitiesEmitted + 1) != MaxVisibilityPerHelp)
+          OS << ", ";
+      }
+      OS << "}}, ";
+
       StringRef Text = (*VisibilityHelp)->getValueAsString("Text");
-      OS << "std::make_pair(options::" << VisibilityStr << ", \"" << Text
-         << "\")";
+      OS << "\"" << Text << "\")";
 
       if (std::next(VisibilityHelp) != VisibilitiesHelp.end())
         OS << ", ";
@@ -442,11 +467,20 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     // Init any unused elements.
     for (; NumVisibilityHelpEmitted < MaxVisibilityHelp;
          ++NumVisibilityHelpEmitted) {
-      OS << "std::make_pair(0, nullptr)";
+      OS << "std::make_pair(std::array<unsigned, " << MaxVisibilityPerHelp
+         << ">{{";
+      for (unsigned NumVisibilitiesEmitted = 0;
+           NumVisibilitiesEmitted != MaxVisibilityPerHelp;
+           ++NumVisibilitiesEmitted) {
+        OS << "0";
+        if ((NumVisibilitiesEmitted + 1) != MaxVisibilityPerHelp)
+          OS << ", ";
+      }
+      OS << "}}, nullptr)";
       if ((NumVisibilityHelpEmitted + 1) != MaxVisibilityHelp)
         OS << ", ";
     }
-    OS << "}})";
+    OS << " }})";
 
     // The option meta-variable name.
     OS << ", ";

>From 07d7c7e4592e806819aa23df1e10f14308720622 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 12 Mar 2024 13:49:57 +0000
Subject: [PATCH 6/9] cleanup comments, move constants

---
 clang/utils/TableGen/ClangOptionDocEmitter.cpp |  2 +-
 llvm/include/llvm/Option/OptTable.h            |  5 +++--
 llvm/utils/TableGen/OptParserEmitter.cpp       | 10 ++++++----
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index cb648af00120f7..87ef2b858265dc 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -362,7 +362,7 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
   std::string Description;
 
   // Prefer a program specific help string.
-  // This is a list of visibilities -> string pairs.
+  // This is a list of (visibilities, string) pairs.
   std::vector<Record *> VisibilitiesHelp =
       R->getValueAsListOfDefs("HelpTextForVisibilities");
   for (Record *VisibilityHelp : VisibilitiesHelp) {
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 274e07df07fd92..2bb118b3be041b 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -61,9 +61,10 @@ class OptTable {
     // 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 type cannot use std::vector
+    // 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.
+    // here if you need more entries and adjust the constants in the TableGen
+    // backends that use it.
     std::array<std::pair<std::array<unsigned int, 2>, const char *>, 1>
         HelpTextForVisibilities;
     const char *MetaVar;
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index 9262574e1eda27..efd787e414d410 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -275,6 +275,9 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
   }
   OS << "#endif\n";
 
+  const unsigned MaxVisibilityHelp = 1;
+  const unsigned MaxVisibilityPerHelp = 2;
+
   OS << "/////////\n";
   OS << "// Groups\n\n";
   OS << "#ifdef OPTION\n";
@@ -313,8 +316,9 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
       OS << ", nullptr";
 
     // Not using Visibility specific text for group help.
-    OS << ", (std::array<std::pair<std::array<unsigned, 2>, const char*>, 1>{{"
-       << "std::make_pair(std::array<unsigned, 2>{{0, 0}}, nullptr)}})";
+    OS << ", (std::array<std::pair<std::array<unsigned, "
+       << MaxVisibilityPerHelp << ">, const char*>, " << MaxVisibilityHelp
+       << ">{{std::make_pair(std::array<unsigned, 2>{{0, 0}}, nullptr)}})";
 
     // The option meta-variable name (unused).
     OS << ", nullptr";
@@ -414,8 +418,6 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     } else
       OS << ", nullptr";
 
-    const unsigned MaxVisibilityHelp = 1;
-    const unsigned MaxVisibilityPerHelp = 2;
     OS << ", (std::array<std::pair<std::array<unsigned, "
        << MaxVisibilityPerHelp << ">, const char*>, " << MaxVisibilityHelp
        << ">{{ ";

>From 2adf699b3090ce4c7f53581aebcf55967ba52f56 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 12 Mar 2024 13:56:12 +0000
Subject: [PATCH 7/9] mention backend by name

---
 llvm/include/llvm/Option/OptTable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 2bb118b3be041b..fa408cf439f0ec 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -63,8 +63,8 @@ class OptTable {
     // 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 the TableGen
-    // backends that use it.
+    // here if you need more entries and adjust the constants in the
+    // OptParserEmitter TableGen backend.
     std::array<std::pair<std::array<unsigned int, 2>, const char *>, 1>
         HelpTextForVisibilities;
     const char *MetaVar;

>From eb33c2090042b702696a13b4e0bf4aa5098b4b20 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 12 Mar 2024 14:25:57 +0000
Subject: [PATCH 8/9] Fix docs build

---
 clang/utils/TableGen/ClangOptionDocEmitter.cpp | 16 ++++++++++------
 llvm/utils/TableGen/OptParserEmitter.cpp       | 13 ++++++-------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index 87ef2b858265dc..579aac2c493f5c 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -367,17 +367,21 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
       R->getValueAsListOfDefs("HelpTextForVisibilities");
   for (Record *VisibilityHelp : VisibilitiesHelp) {
     // This is a list of visibilities.
-    std::vector<StringRef> Visibilities =
-        VisibilityHelp->getValueAsListOfStrings("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")) {
-      if (std::find(Visibilities.begin(), Visibilities.end(), DocInfoMask) !=
-          Visibilities.end()) {
-        Description = escapeRST(VisibilityHelp->getValueAsString("Text"));
-        break;
+      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())
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index efd787e414d410..de5c9ef6c83e08 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -434,21 +434,20 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
              VisibilitiesHelp.begin();
          VisibilityHelp != VisibilitiesHelp.end();
          ++VisibilityHelp, ++NumVisibilityHelpEmitted) {
-      ListInit *Visibilities =
-          (*VisibilityHelp)->getValueAsListInit("Visibilities");
-      ArrayRef<Init *> VisibilitiesValues = Visibilities->getValues();
-      assert(VisibilitiesValues.size() <= MaxVisibilityPerHelp &&
+      ArrayRef<Init *> Visibilities =
+          (*VisibilityHelp)->getValueAsListInit("Visibilities")->getValues();
+      assert(Visibilities.size() <= MaxVisibilityPerHelp &&
              "Too many visibilities to store in an "
              "OptTable::HelpTextForVisibilities entry");
 
       OS << "std::make_pair(std::array<unsigned, " << MaxVisibilityPerHelp
          << ">{{";
       unsigned NumVisibilitiesEmitted = 0;
-      for (auto Visibility = VisibilitiesValues.begin();
-           Visibility != VisibilitiesValues.end();
+      for (auto Visibility = Visibilities.begin();
+           Visibility != Visibilities.end();
            ++Visibility, ++NumVisibilitiesEmitted) {
         OS << (*Visibility)->getAsUnquotedString();
-        if (std::next(Visibility) != VisibilitiesValues.end())
+        if (std::next(Visibility) != Visibilities.end())
           OS << ", ";
       }
       // Init unused elements.

>From e422b9bb95c5fd175aaf9adfa52bd282f40ae178 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 12 Mar 2024 15:05:40 +0000
Subject: [PATCH 9/9] Rename the new thing

---
 clang-tools-extra/clangd/CompileCommands.cpp  |  4 ++--
 clang/include/clang/Driver/Options.td         |  4 ++--
 clang/lib/Frontend/CompilerInvocation.cpp     |  6 +++---
 .../utils/TableGen/ClangOptionDocEmitter.cpp  |  2 +-
 lld/MachO/DriverUtils.cpp                     |  4 ++--
 lld/MinGW/Driver.cpp                          |  4 ++--
 lld/wasm/Driver.cpp                           |  4 ++--
 llvm/include/llvm/Option/OptParser.td         |  8 ++++----
 llvm/include/llvm/Option/OptTable.h           | 20 +++++++++----------
 .../Option/OptionMarshallingTest.cpp          |  2 +-
 llvm/utils/TableGen/OptParserEmitter.cpp      |  6 +++---
 11 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index cf9fab129b3ac0..fddfffe7523d95 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -466,7 +466,7 @@ 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, HELPTEXT, HELPTEXTFORVISIBILITIES,    \
+               FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS,       \
                METAVAR, VALUES)                                                \
   Prefixes[DriverID::OPT_##ID] = PREFIX;
 #include "clang/Driver/Options.inc"
@@ -479,7 +479,7 @@ 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, HELPTEXT, HELPTEXTFORVISIBILITIES,    \
+               FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS,       \
                METAVAR, VALUES)                                                \
   {DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS},
 #include "clang/Driver/Options.inc"
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 36d99b8edf6e77..aefe92d1af4c88 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3391,8 +3391,8 @@ def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>,
   Flags<[NoArgumentUnused]>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
   HelpText<OpenMPVersionHelp<"Clang", "51">.str>,
-  HelpTextForVisibilities<[
-    HelpTextForVisibility<[FlangOption, FC1Option], OpenMPVersionHelp<"Flang", "11">.str>
+  HelpTextsForVariants<[
+    HelpTextVariant<[FlangOption, FC1Option], OpenMPVersionHelp<"Flang", "11">.str>
   ]>;
 defm openmp_extensions: BoolFOption<"openmp-extensions",
   LangOpts<"OpenMPExtensions">, DefaultTrue,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index b471b8438f3a72..be1365ddb39ba7 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -522,8 +522,8 @@ static T extractMaskValue(T KeyPath) {
 
 #define PARSE_OPTION_WITH_MARSHALLING(                                         \
     ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS,     \
-    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,      \
-    VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK,  \
+    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);                                  \
@@ -539,7 +539,7 @@ 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, HELPTEXTFORVISIBILITIES, METAVAR, VALUES,     \
+    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) {                                     \
diff --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index 579aac2c493f5c..86835611b84218 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -364,7 +364,7 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
   // Prefer a program specific help string.
   // This is a list of (visibilities, string) pairs.
   std::vector<Record *> VisibilitiesHelp =
-      R->getValueAsListOfDefs("HelpTextForVisibilities");
+      R->getValueAsListOfDefs("HelpTextsForVariants");
   for (Record *VisibilityHelp : VisibilitiesHelp) {
     // This is a list of visibilities.
     ArrayRef<Init *> Visibilities =
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index c0812f11f95a0f..077a639bf7ab1e 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -45,12 +45,12 @@ 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, HELPTEXTFORVISIBILITIES, METAVAR,  \
+               VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR,     \
                VALUES)                                                         \
   {PREFIX,                                                                     \
    NAME,                                                                       \
    HELPTEXT,                                                                   \
-   HELPTEXTFORVISIBILITIES,                                                    \
+   HELPTEXTSFORVARIANTS,                                                       \
    METAVAR,                                                                    \
    OPT_##ID,                                                                   \
    opt::Option::KIND##Class,                                                   \
diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp
index 9aa3228e8ad98c..16e4102a934b33 100644
--- a/lld/MinGW/Driver.cpp
+++ b/lld/MinGW/Driver.cpp
@@ -69,12 +69,12 @@ 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, HELPTEXTFORVISIBILITIES, METAVAR,  \
+               VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR,     \
                VALUES)                                                         \
   {PREFIX,                                                                     \
    NAME,                                                                       \
    HELPTEXT,                                                                   \
-   HELPTEXTFORVISIBILITIES,                                                    \
+   HELPTEXTSFORVARIANTS,                                                       \
    METAVAR,                                                                    \
    OPT_##ID,                                                                   \
    opt::Option::KIND##Class,                                                   \
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index f9b99e2a268c86..47fcba5ce50308 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -132,12 +132,12 @@ 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, HELPTEXTFORVISIBILITIES, METAVAR,  \
+               VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR,     \
                VALUES)                                                         \
   {PREFIX,                                                                     \
    NAME,                                                                       \
    HELPTEXT,                                                                   \
-   HELPTEXTFORVISIBILITIES,                                                    \
+   HELPTEXTSFORVARIANTS,                                                       \
    METAVAR,                                                                    \
    OPT_##ID,                                                                   \
    opt::Option::KIND##Class,                                                   \
diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td
index 24d9fe1c537dd9..430ad07f55f148 100644
--- a/llvm/include/llvm/Option/OptParser.td
+++ b/llvm/include/llvm/Option/OptParser.td
@@ -93,7 +93,7 @@ class OptionGroup<string name> {
 
 // Define the option class.
 
-class HelpTextForVisibility<list<OptionVisibility> visibilities, string text> {
+class HelpTextVariant<list<OptionVisibility> visibilities, string text> {
   list<OptionVisibility> Visibilities = visibilities;
   string Text = text;
 }
@@ -106,7 +106,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
   // Used by MultiArg option kind.
   int NumArgs = 0;
   string HelpText = ?;
-  list<HelpTextForVisibility> HelpTextForVisibilities = [];
+  list<HelpTextVariant> HelpTextsForVariants = [];
   string MetaVarName = ?;
   string Values = ?;
   code ValuesCode = ?;
@@ -161,8 +161,8 @@ class Visibility<list<OptionVisibility> visibility> {
 }
 class Group<OptionGroup group> { OptionGroup Group = group; }
 class HelpText<string text> { string HelpText = text; }
-class HelpTextForVisibilities<list<HelpTextForVisibility> texts> {
-  list<HelpTextForVisibility> HelpTextForVisibilities = texts;
+class HelpTextsForVariants<list<HelpTextVariant> texts> {
+  list<HelpTextVariant> HelpTextsForVariants = texts;
 }
 
 class MetaVarName<string name> { string MetaVarName = name; }
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index fa408cf439f0ec..cfe443c37cb543 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -66,7 +66,7 @@ class OptTable {
     // here if you need more entries and adjust the constants in the
     // OptParserEmitter TableGen backend.
     std::array<std::pair<std::array<unsigned int, 2>, const char *>, 1>
-        HelpTextForVisibilities;
+        HelpTextsForVariants;
     const char *MetaVar;
     unsigned ID;
     unsigned char Kind;
@@ -163,7 +163,7 @@ class OptTable {
   const char *getOptionHelpText(OptSpecifier id,
                                 Visibility VisibilityMask) const {
     auto Info = getInfo(id);
-    for (auto [Visibilities, Text] : Info.HelpTextForVisibilities)
+    for (auto [Visibilities, Text] : Info.HelpTextsForVariants)
       for (auto Visibility : Visibilities)
         if (VisibilityMask & Visibility)
           return Text;
@@ -381,32 +381,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, HELPTEXTFORVISIBILITIES, 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,        \
-                         HELPTEXTFORVISIBILITIES, METAVAR, VALUES)             \
+                         HELPTEXTSFORVARIANTS, METAVAR, VALUES)                \
   LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(                                             \
       OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,   \
-      VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR, VALUE)
+      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, HELPTEXTFORVISIBILITIES, METAVAR,      \
-    VALUES)                                                                    \
+    FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES) \
   llvm::opt::OptTable::Info {                                                  \
-    PREFIX, PREFIXED_NAME, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR,         \
+    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, \
-                                HELPTEXTFORVISIBILITIES, 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, HELPTEXTFORVISIBILITIES, METAVAR, VALUES)
+      VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES)
 
 #endif // LLVM_OPTION_OPTTABLE_H
diff --git a/llvm/unittests/Option/OptionMarshallingTest.cpp b/llvm/unittests/Option/OptionMarshallingTest.cpp
index e3985e0b847369..0464e27d5248a8 100644
--- a/llvm/unittests/Option/OptionMarshallingTest.cpp
+++ b/llvm/unittests/Option/OptionMarshallingTest.cpp
@@ -19,7 +19,7 @@ struct OptionWithMarshallingInfo {
 static const OptionWithMarshallingInfo MarshallingTable[] = {
 #define OPTION_WITH_MARSHALLING(                                               \
     PREFIX_TYPE, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,      \
-    VISIBILITY, PARAM, HELPTEXT, HELPTEXTFORVISIBILITIES, METAVAR, VALUES,     \
+    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},
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index de5c9ef6c83e08..38e0beb129c0a6 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -425,10 +425,10 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     unsigned NumVisibilityHelpEmitted = 0;
 
     std::vector<Record *> VisibilitiesHelp =
-        R.getValueAsListOfDefs("HelpTextForVisibilities");
+        R.getValueAsListOfDefs("HelpTextsForVariants");
     assert(VisibilitiesHelp.size() <= MaxVisibilityHelp &&
            "Too many help text variants to store in "
-           "OptTable::HelpTextForVisibilities");
+           "OptTable::HelpTextsForVariants");
 
     for (std::vector<Record *>::const_iterator VisibilityHelp =
              VisibilitiesHelp.begin();
@@ -438,7 +438,7 @@ static void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
           (*VisibilityHelp)->getValueAsListInit("Visibilities")->getValues();
       assert(Visibilities.size() <= MaxVisibilityPerHelp &&
              "Too many visibilities to store in an "
-             "OptTable::HelpTextForVisibilities entry");
+             "OptTable::HelpTextsForVariants entry");
 
       OS << "std::make_pair(std::array<unsigned, " << MaxVisibilityPerHelp
          << ">{{";



More information about the llvm-commits mailing list