//===- OptionParserEmitter.cpp - Table Driven Command Option Line Parsing -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Common/OptEmitter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/InterleavedRange.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <cstring>
#include <map>

using namespace llvm;

static std::string getOptionName(const Record &R) {
  // Use the record name unless EnumName is defined.
  if (isa<UnsetInit>(R.getValueInit("EnumName")))
    return R.getName().str();

  return R.getValueAsString("EnumName").str();
}

static raw_ostream &writeStrTableOffset(raw_ostream &OS,
                                        const StringToOffsetTable &Table,
                                        llvm::StringRef Str) {
  OS << Table.GetStringOffset(Str) << " /* ";
  OS.write_escaped(Str);
  OS << " */";
  return OS;
}

static raw_ostream &writeCstring(raw_ostream &OS, llvm::StringRef Str) {
  OS << '"';
  OS.write_escaped(Str);
  OS << '"';
  return OS;
}

static std::string getOptionPrefixedName(const Record &R) {
  std::vector<StringRef> Prefixes = R.getValueAsListOfStrings("Prefixes");
  StringRef Name = R.getValueAsString("Name");

  if (Prefixes.empty())
    return Name.str();

  return (Prefixes[0] + Twine(Name)).str();
}

class MarshallingInfo {
public:
  static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING";
  const Record &R;
  bool ShouldAlwaysEmit = false;
  StringRef MacroPrefix;
  StringRef KeyPath;
  StringRef DefaultValue;
  StringRef NormalizedValuesScope;
  StringRef ImpliedCheck;
  StringRef ImpliedValue;
  StringRef ShouldParse;
  StringRef Normalizer;
  StringRef Denormalizer;
  StringRef ValueMerger;
  StringRef ValueExtractor;
  int TableIndex = -1;
  std::vector<StringRef> Values;
  std::vector<StringRef> NormalizedValues;
  std::string ValueTableName;

  static size_t NextTableIndex;

  static constexpr const char *ValueTablePreamble = R"(
struct SimpleEnumValue {
  const char *Name;
  unsigned Value;
};

struct SimpleEnumValueTable {
  const SimpleEnumValue *Table;
  unsigned Size;
};
)";

  static constexpr const char *ValueTablesDecl =
      "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";

  MarshallingInfo(const Record &R) : R(R) {}

  std::string getMacroName() const {
    return (MacroPrefix + MarshallingInfo::MacroName).str();
  }

  void emit(raw_ostream &OS) const {
    OS << ShouldParse;
    OS << ", ";
    OS << ShouldAlwaysEmit;
    OS << ", ";
    OS << KeyPath;
    OS << ", ";
    emitScopedNormalizedValue(OS, DefaultValue);
    OS << ", ";
    OS << ImpliedCheck;
    OS << ", ";
    emitScopedNormalizedValue(OS, ImpliedValue);
    OS << ", ";
    OS << Normalizer;
    OS << ", ";
    OS << Denormalizer;
    OS << ", ";
    OS << ValueMerger;
    OS << ", ";
    OS << ValueExtractor;
    OS << ", ";
    OS << TableIndex;
  }

  std::optional<StringRef> emitValueTable(raw_ostream &OS) const {
    if (TableIndex == -1)
      return {};
    OS << "static const SimpleEnumValue " << ValueTableName << "[] = {\n";
    for (unsigned I = 0, E = Values.size(); I != E; ++I) {
      OS << "{";
      writeCstring(OS, Values[I]);
      OS << ",";
      OS << "static_cast<unsigned>(";
      emitScopedNormalizedValue(OS, NormalizedValues[I]);
      OS << ")},";
    }
    OS << "};\n";
    return StringRef(ValueTableName);
  }

private:
  void emitScopedNormalizedValue(raw_ostream &OS,
                                 StringRef NormalizedValue) const {
    if (!NormalizedValuesScope.empty())
      OS << NormalizedValuesScope << "::";
    OS << NormalizedValue;
  }
};

size_t MarshallingInfo::NextTableIndex = 0;

static MarshallingInfo createMarshallingInfo(const Record &R) {
  assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
         !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
         !isa<UnsetInit>(R.getValueInit("ValueMerger")) &&
         "MarshallingInfo must have a provide a keypath, default value and a "
         "value merger");

  MarshallingInfo Ret(R);

  Ret.ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
  Ret.MacroPrefix = R.getValueAsString("MacroPrefix");
  Ret.KeyPath = R.getValueAsString("KeyPath");
  Ret.DefaultValue = R.getValueAsString("DefaultValue");
  Ret.NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
  Ret.ImpliedCheck = R.getValueAsString("ImpliedCheck");
  Ret.ImpliedValue =
      R.getValueAsOptionalString("ImpliedValue").value_or(Ret.DefaultValue);

  Ret.ShouldParse = R.getValueAsString("ShouldParse");
  Ret.Normalizer = R.getValueAsString("Normalizer");
  Ret.Denormalizer = R.getValueAsString("Denormalizer");
  Ret.ValueMerger = R.getValueAsString("ValueMerger");
  Ret.ValueExtractor = R.getValueAsString("ValueExtractor");

  if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
    assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
           "Cannot provide normalized values for value-less options");
    Ret.TableIndex = MarshallingInfo::NextTableIndex++;
    Ret.NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
    Ret.Values.reserve(Ret.NormalizedValues.size());
    Ret.ValueTableName = getOptionName(R) + "ValueTable";

    StringRef ValuesStr = R.getValueAsString("Values");
    for (;;) {
      size_t Idx = ValuesStr.find(',');
      if (Idx == StringRef::npos)
        break;
      if (Idx > 0)
        Ret.Values.push_back(ValuesStr.slice(0, Idx));
      ValuesStr = ValuesStr.substr(Idx + 1);
    }
    if (!ValuesStr.empty())
      Ret.Values.push_back(ValuesStr);

    assert(Ret.Values.size() == Ret.NormalizedValues.size() &&
           "The number of normalized values doesn't match the number of "
           "values");
  }

  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::array<unsigned, " << MaxVisibilityPerHelp << ">{{"
       << llvm::interleaved(Visibilities) << "}}, ";

    if (Help.size())
      writeCstring(OS, Help);
    else
      OS << "nullptr";
    OS << "}";

    if (std::next(VisibilityHelp) != VisibilityHelpEnd)
      OS << ", ";
  }
  OS << " }})";
}

/// OptionParserEmitter - 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.
static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) {
  // Get the option groups and options.
  ArrayRef<const Record *> Groups =
      Records.getAllDerivedDefinitions("OptionGroup");
  std::vector<const Record *> Opts = Records.getAllDerivedDefinitions("Option");
  llvm::sort(Opts, IsOptionRecordsLess);

  std::vector<const Record *> SubCommands =
      Records.getAllDerivedDefinitions("SubCommand");

  emitSourceFileHeader("Option Parsing Definitions", OS);

  // Generate prefix groups.
  typedef SmallVector<SmallString<2>, 2> PrefixKeyT;
  typedef std::map<PrefixKeyT, unsigned> PrefixesT;
  PrefixesT Prefixes;
  Prefixes.try_emplace(PrefixKeyT(), 0);
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
    PrefixKeyT PrefixKey(RPrefixes.begin(), RPrefixes.end());
    Prefixes.try_emplace(PrefixKey, 0);
  }

  // Generate sub command groups.
  typedef SmallVector<StringRef, 2> SubCommandKeyT;
  typedef std::map<SubCommandKeyT, unsigned> SubCommandIDsT;
  SubCommandIDsT SubCommandIDs;

  auto PrintSubCommandIdsOffset = [&SubCommandIDs, &OS](const Record &R) {
    if (R.getValue("SubCommands") != nullptr) {
      std::vector<const Record *> SubCommands =
          R.getValueAsListOfDefs("SubCommands");
      SubCommandKeyT SubCommandKey;
      for (const auto &SubCommand : SubCommands)
        SubCommandKey.push_back(SubCommand->getName());
      OS << SubCommandIDs[SubCommandKey];
    } else {
      // The option SubCommandIDsOffset (for default top level toolname is 0).
      OS << " 0";
    }
  };

  SubCommandIDs.try_emplace(SubCommandKeyT(), 0);
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    std::vector<const Record *> RSubCommands =
        R.getValueAsListOfDefs("SubCommands");
    SubCommandKeyT SubCommandKey;
    for (const auto &SubCommand : RSubCommands)
      SubCommandKey.push_back(SubCommand->getName());
    SubCommandIDs.try_emplace(SubCommandKey, 0);
  }

  DenseSet<StringRef> PrefixesUnionSet;
  for (const auto &[Prefix, _] : Prefixes)
    PrefixesUnionSet.insert_range(Prefix);
  SmallVector<StringRef> PrefixesUnion(PrefixesUnionSet.begin(),
                                       PrefixesUnionSet.end());
  array_pod_sort(PrefixesUnion.begin(), PrefixesUnion.end());

  llvm::StringToOffsetTable Table;
  // We can add all the prefixes via the union.
  for (const auto &Prefix : PrefixesUnion)
    Table.GetOrAddStringOffset(Prefix);
  for (const Record &R : llvm::make_pointee_range(Groups))
    Table.GetOrAddStringOffset(R.getValueAsString("Name"));
  for (const Record &R : llvm::make_pointee_range(Opts))
    Table.GetOrAddStringOffset(getOptionPrefixedName(R));

  // Dump string table.
  OS << "/////////\n";
  OS << "// String table\n\n";
  OS << "#ifdef OPTTABLE_STR_TABLE_CODE\n";
  Table.EmitStringTableDef(OS, "OptionStrTable");
  OS << "#endif // OPTTABLE_STR_TABLE_CODE\n\n";

  // Dump prefixes.
  OS << "/////////\n";
  OS << "// Prefixes\n\n";
  OS << "#ifdef OPTTABLE_PREFIXES_TABLE_CODE\n";
  OS << "static constexpr llvm::StringTable::Offset OptionPrefixesTable[] = "
        "{\n";
  {
    // Ensure the first prefix set is always empty.
    assert(!Prefixes.empty() &&
           "We should always emit an empty set of prefixes");
    assert(Prefixes.begin()->first.empty() &&
           "First prefix set should always be empty");
    llvm::ListSeparator Sep(",\n");
    unsigned CurIndex = 0;
    for (auto &[Prefix, PrefixIndex] : Prefixes) {
      // First emit the number of prefix strings in this list of prefixes.
      OS << Sep << "  " << Prefix.size() << " /* prefixes */";
      PrefixIndex = CurIndex;
      assert((CurIndex == 0 || !Prefix.empty()) &&
             "Only first prefix set should be empty!");
      for (const auto &PrefixKey : Prefix)
        OS << ", " << *Table.GetStringOffset(PrefixKey) << " /* '" << PrefixKey
           << "' */";
      CurIndex += Prefix.size() + 1;
    }
  }
  OS << "\n};\n";
  OS << "#endif // OPTTABLE_PREFIXES_TABLE_CODE\n\n";

  // Dump subcommand IDs.
  OS << "/////////";
  OS << "// SubCommand IDs\n\n";
  OS << "#ifdef OPTTABLE_SUBCOMMAND_IDS_TABLE_CODE\n";
  OS << "static constexpr unsigned OptionSubCommandIDsTable[] = {\n";
  {
    // Ensure the first subcommand set is always empty.
    assert(!SubCommandIDs.empty() &&
           "We should always emit an empty set of subcommands");
    assert(SubCommandIDs.begin()->first.empty() &&
           "First subcommand set should always be empty");
    llvm::ListSeparator Sep(",\n");
    unsigned CurIndex = 0;
    for (auto &[SubCommand, SubCommandIndex] : SubCommandIDs) {
      // First emit the number of subcommand strings in this list of
      // subcommands.
      OS << Sep << "  " << SubCommand.size() << " /* subcommands */";
      SubCommandIndex = CurIndex;
      assert((CurIndex == 0 || !SubCommand.empty()) &&
             "Only first subcommand set should be empty!");
      for (const auto &SubCommandKey : SubCommand) {
        auto It = std::find_if(
            SubCommands.begin(), SubCommands.end(),
            [&](const Record *R) { return R->getName() == SubCommandKey; });
        assert(It != SubCommands.end() && "SubCommand not found");
        OS << ", " << std::distance(SubCommands.begin(), It) << " /* '"
           << SubCommandKey << "' */";
      }
      CurIndex += SubCommand.size() + 1;
    }
  }
  OS << "\n};\n";
  OS << "#endif // OPTTABLE_SUBCOMMAND_IDS_TABLE_CODE\n\n";

  // Dump prefixes union.
  OS << "/////////\n";
  OS << "// Prefix Union\n\n";
  OS << "#ifdef OPTTABLE_PREFIXES_UNION_CODE\n";
  OS << "static constexpr llvm::StringTable::Offset OptionPrefixesUnion[] = "
        "{\n";
  {
    llvm::ListSeparator Sep(", ");
    for (auto Prefix : PrefixesUnion)
      OS << Sep << "  " << *Table.GetStringOffset(Prefix) << " /* '" << Prefix
         << "' */";
  }
  OS << "\n};\n";
  OS << "#endif // OPTTABLE_PREFIXES_UNION_CODE\n\n";

  // Dump groups.
  OS << "/////////\n";
  OS << "// ValuesCode\n\n";
  OS << "#ifdef OPTTABLE_VALUES_CODE\n";
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    // The option values, if any;
    if (!isa<UnsetInit>(R.getValueInit("ValuesCode"))) {
      assert(isa<UnsetInit>(R.getValueInit("Values")) &&
             "Cannot choose between Values and ValuesCode");
      OS << "#define VALUES_CODE " << getOptionName(R) << "_Values\n";
      OS << R.getValueAsString("ValuesCode") << "\n";
      OS << "#undef VALUES_CODE\n";
    }
  }
  OS << "#endif\n";

  OS << "/////////\n";
  OS << "// Groups\n\n";
  OS << "#ifdef OPTION\n";
  for (const Record &R : llvm::make_pointee_range(Groups)) {
    // Start a single option entry.
    OS << "OPTION(";

    // A zero prefix offset corresponds to an empty set of prefixes.
    OS << "0 /* no prefixes */";

    // The option string offset.
    OS << ", ";
    writeStrTableOffset(OS, Table, R.getValueAsString("Name"));

    // The option identifier name.
    OS << ", " << getOptionName(R);

    // The option kind.
    OS << ", Group";

    // The containing option group (if any).
    OS << ", ";
    if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
      OS << getOptionName(*DI->getDef());
    else
      OS << "INVALID";

    // The other option arguments (unused for groups).
    OS << ", INVALID, nullptr, 0, 0, 0";

    // The option help text.
    if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
      OS << ",\n";
      OS << "       ";
      writeCstring(OS, R.getValueAsString("HelpText"));
    } else {
      OS << ", nullptr";
    }

    // Not using Visibility specific text for group help.
    emitHelpTextsForVariants(OS, {});

    // The option meta-variable name (unused).
    OS << ", nullptr";

    // The option Values (unused for groups).
    OS << ", nullptr";

    // The option SubCommandIDsOffset.
    OS << ", ";
    PrintSubCommandIdsOffset(R);
    OS << ")\n";
  }
  OS << "\n";

  OS << "//////////\n";
  OS << "// Options\n\n";

  auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) {
    // The option prefix;
    std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
    OS << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())] << ", ";

    // The option prefixed name.
    writeStrTableOffset(OS, Table, getOptionPrefixedName(R));

    // The option identifier name.
    OS << ", " << getOptionName(R);

    // The option kind.
    OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");

    // The containing option group (if any).
    OS << ", ";
    const ListInit *GroupFlags = nullptr;
    const ListInit *GroupVis = nullptr;
    if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
      GroupFlags = DI->getDef()->getValueAsListInit("Flags");
      GroupVis = DI->getDef()->getValueAsListInit("Visibility");
      OS << getOptionName(*DI->getDef());
    } else {
      OS << "INVALID";
    }

    // The option alias (if any).
    OS << ", ";
    if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias")))
      OS << getOptionName(*DI->getDef());
    else
      OS << "INVALID";

    // The option alias arguments (if any).
    // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
    // would become "foo\0bar\0". Note that the compiler adds an implicit
    // terminating \0 at the end.
    OS << ", ";
    std::vector<StringRef> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
    if (AliasArgs.size() == 0) {
      OS << "nullptr";
    } else {
      OS << "\"";
      for (StringRef AliasArg : AliasArgs)
        OS << AliasArg << "\\0";
      OS << "\"";
    }

    // "Flags" for the option, such as HelpHidden and Render*
    OS << ", ";
    int NumFlags = 0;
    const ListInit *LI = R.getValueAsListInit("Flags");
    for (const Init *I : *LI)
      OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName();
    if (GroupFlags) {
      for (const Init *I : *GroupFlags)
        OS << (NumFlags++ ? " | " : "")
           << cast<DefInit>(I)->getDef()->getName();
    }
    if (NumFlags == 0)
      OS << '0';

    // Option visibility, for sharing options between drivers.
    OS << ", ";
    int NumVisFlags = 0;
    LI = R.getValueAsListInit("Visibility");
    for (const Init *I : *LI)
      OS << (NumVisFlags++ ? " | " : "")
         << cast<DefInit>(I)->getDef()->getName();
    if (GroupVis) {
      for (const Init *I : *GroupVis)
        OS << (NumVisFlags++ ? " | " : "")
           << cast<DefInit>(I)->getDef()->getName();
    }
    if (NumVisFlags == 0)
      OS << '0';

    // The option parameter field.
    OS << ", " << R.getValueAsInt("NumArgs");

    // The option help text.
    if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
      OS << ",\n";
      OS << "       ";
      writeCstring(OS, R.getValueAsString("HelpText"));
    } else {
      OS << ", nullptr";
    }

    std::vector<std::pair<std::vector<std::string>, StringRef>>
        HelpTextsForVariants;
    for (const Record *VisibilityHelp :
         R.getValueAsListOfDefs("HelpTextsForVariants")) {
      ArrayRef<const Init *> Visibilities =
          VisibilityHelp->getValueAsListInit("Visibilities")->getElements();

      std::vector<std::string> VisibilityNames;
      for (const Init *Visibility : Visibilities)
        VisibilityNames.push_back(Visibility->getAsUnquotedString());

      HelpTextsForVariants.emplace_back(
          VisibilityNames, VisibilityHelp->getValueAsString("Text"));
    }
    emitHelpTextsForVariants(OS, std::move(HelpTextsForVariants));

    // The option meta-variable name.
    OS << ", ";
    if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))
      writeCstring(OS, R.getValueAsString("MetaVarName"));
    else
      OS << "nullptr";

    // The option Values. Used for shell autocompletion.
    OS << ", ";
    if (!isa<UnsetInit>(R.getValueInit("Values")))
      writeCstring(OS, R.getValueAsString("Values"));
    else if (!isa<UnsetInit>(R.getValueInit("ValuesCode")))
      OS << getOptionName(R) << "_Values";
    else
      OS << "nullptr";

    // The option SubCommandIDsOffset.
    OS << ", ";
    PrintSubCommandIdsOffset(R);
  };

  auto IsMarshallingOption = [](const Record &R) {
    return !isa<UnsetInit>(R.getValueInit("KeyPath")) &&
           !R.getValueAsString("KeyPath").empty();
  };

  std::vector<const Record *> OptsWithMarshalling;
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    // Start a single option entry.
    OS << "OPTION(";
    WriteOptRecordFields(OS, R);
    OS << ")\n";
    if (IsMarshallingOption(R))
      OptsWithMarshalling.push_back(&R);
  }
  OS << "#endif // OPTION\n";

  auto CmpMarshallingOpts = [](const Record *const *A, const Record *const *B) {
    unsigned AID = (*A)->getID();
    unsigned BID = (*B)->getID();

    if (AID < BID)
      return -1;
    if (AID > BID)
      return 1;
    return 0;
  };
  // The RecordKeeper stores records (options) in lexicographical order, and we
  // have reordered the options again when generating prefix groups. We need to
  // restore the original definition order of options with marshalling to honor
  // the topology of the dependency graph implied by `DefaultAnyOf`.
  array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(),
                 CmpMarshallingOpts);

  std::vector<MarshallingInfo> MarshallingInfos;
  MarshallingInfos.reserve(OptsWithMarshalling.size());
  for (const auto *R : OptsWithMarshalling)
    MarshallingInfos.push_back(createMarshallingInfo(*R));

  for (const auto &MI : MarshallingInfos) {
    OS << "#ifdef " << MI.getMacroName() << "\n";
    OS << MI.getMacroName() << "(";
    WriteOptRecordFields(OS, MI.R);
    OS << ", ";
    MI.emit(OS);
    OS << ")\n";
    OS << "#endif // " << MI.getMacroName() << "\n";
  }

  OS << "\n";
  OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE";
  OS << "\n";
  OS << MarshallingInfo::ValueTablePreamble;
  std::vector<StringRef> ValueTableNames;
  for (const auto &MI : MarshallingInfos)
    if (auto MaybeValueTableName = MI.emitValueTable(OS))
      ValueTableNames.push_back(*MaybeValueTableName);

  OS << MarshallingInfo::ValueTablesDecl << "{";
  for (auto ValueTableName : ValueTableNames)
    OS << "{" << ValueTableName << ", std::size(" << ValueTableName << ")},\n";
  OS << "};\n";
  OS << "static const unsigned SimpleEnumValueTablesSize = "
        "std::size(SimpleEnumValueTables);\n";

  OS << "#endif // SIMPLE_ENUM_VALUE_TABLE\n";
  OS << "\n";
  OS << "/////////\n";
  OS << "\n// SubCommands\n\n";
  OS << "#ifdef OPTTABLE_SUBCOMMANDS_CODE\n";
  OS << "static constexpr llvm::opt::OptTable::SubCommand OptionSubCommands[] "
        "= "
        "{\n";
  for (const Record *SubCommand : SubCommands) {
    OS << "  { \"" << SubCommand->getValueAsString("Name") << "\", ";
    OS << "\"" << SubCommand->getValueAsString("HelpText") << "\", ";
    OS << "\"" << SubCommand->getValueAsString("Usage") << "\" },\n";
  }
  OS << "};\n";
  OS << "#endif // OPTTABLE_SUBCOMMANDS_CODE\n\n";

  OS << "\n";
}

static TableGen::Emitter::Opt X("gen-opt-parser-defs", emitOptionParser,
                                "Generate option definitions");
