//===- 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 "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/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <array>
#include <cstring>
#include <map>
#include <set>

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();
}

// Only pass EmitComment for short strings that cannot contain "*/".
static void writeStrTableOffset(raw_ostream &OS,
                                const StringToOffsetTable &Table,
                                llvm::StringRef Str, bool EmitComment = false) {
  std::optional<unsigned> Offset = Table.GetStringOffset(Str);
  if (!Offset)
    PrintFatalError("string was not added to the option string table: " + Str);
  OS << *Offset;
  if (EmitComment) {
    OS << " /* ";
    OS.write_escaped(Str);
    OS << " */";
  }
}

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

static StringRef getOptionalString(const Record &R, StringRef Field) {
  return R.getValueAsOptionalString(Field).value_or("");
}

// Offset zero is the empty string and stands for an unset HelpText. A
// HelpText<""> marks an option as deliberately undocumented, so it maps to a
// second empty string that the table does not put at offset zero.
static StringRef getHelpText(const Record &R) {
  std::optional<StringRef> S = R.getValueAsOptionalString("HelpText");
  if (!S)
    return StringRef();
  return S->empty() ? StringRef("\0", 1) : *S;
}

// The string table appends the empty string that terminates the list.
static std::string getAliasArgsBlob(const Record &R) {
  std::string Blob;
  for (StringRef AliasArg : R.getValueAsListOfStrings("AliasArgs")) {
    if (AliasArg.empty())
      PrintFatalError(R.getLoc(), "AliasArgs entries must not be empty");
    Blob += AliasArg;
    Blob += '\0';
  }
  return Blob;
}

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;
  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 << 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")) &&
         "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");

  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;
}

// -foo-bar becomes foo_bar, or bar if Prefix is "foo-".
static std::string getSpellingIdentifier(const Record &R,
                                         StringRef Prefix = "") {
  StringRef Spelling = R.getValueAsString("Name");
  Spelling.consume_front(Prefix);
  std::string ID = Spelling.str();
  llvm::replace(ID, '-', '_');
  if (ID.empty() || isDigit(ID[0]) ||
      !all_of(ID, [](char C) { return isAlnum(C) || C == '_'; }))
    PrintFatalError(R.getLoc(), "the spelling is not an identifier; name the "
                                "defm");
  return ID;
}

// `defm : BoolField<"foo-bar", ...>` declares member foo_bar, and a named defm
// names it.
static std::string getMemberName(const Record &R, StringRef Prefix) {
  StringRef Name = R.getValueAsString("FieldName");
  return Name.starts_with("anonymous_") ? getSpellingIdentifier(R, Prefix)
                                        : Name.str();
}

// The OPT_ name of an option of an OptionsStruct. `defm :` rows are named
// after the spelling: -foo-bar is OPT_foo_bar.
static std::string getStructOptionID(const Record &R) {
  if (!R.getName().starts_with("anonymous_"))
    return getOptionName(R);
  return getSpellingIdentifier(R);
}

// The preprocessor expression of R's Condition, or "" if it has none.
static StringRef getCondition(const Record &R) {
  const RecordVal *V = R.getValue("Condition");
  const auto *DI = V ? dyn_cast<DefInit>(V->getValue()) : nullptr;
  return DI ? DI->getDef()->getValueAsString("Expr") : "";
}

namespace {
// Wraps what is emitted during its lifetime in `#if Condition` where R has one.
class ConditionScope {
  raw_ostream &OS;
  StringRef Condition;

public:
  ConditionScope(raw_ostream &OS, const Record &R)
      : OS(OS), Condition(getCondition(R)) {
    if (!Condition.empty())
      OS << "#if " << Condition << '\n';
  }
  ~ConditionScope() {
    if (!Condition.empty())
      OS << "#endif\n";
  }
};
} // namespace

// Emits the OPT_ IDs of an OptionsStruct, which its table rows name.
static void emitStructOptionIDs(ArrayRef<const Record *> Groups,
                                ArrayRef<const Record *> Opts,
                                raw_ostream &OS) {
  OS << "namespace {\nenum ID : unsigned {\n  OPT_INVALID = 0,\n";
  for (const Record *R : Groups)
    OS << "  OPT_" << getOptionName(*R) << ",\n";
  for (const Record *R : Opts) {
    ConditionScope CS(OS, *R);
    OS << "  OPT_" << getStructOptionID(*R) << ",\n";
  }
  OS << "};\n} // namespace\n\n";
}

// Emits the struct an OptionsStruct def declares: its declaration under
// OPTIONS_STRUCT_DECL, and under OPTIONS_STRUCT_DEFS the global instance, the
// option table, and apply(), which sets the member an argument names.
static void emitOptionsStruct(const Record &Struct,
                              ArrayRef<const Record *> Groups,
                              ArrayRef<const Record *> Opts, raw_ostream &OS) {
  struct Member {
    std::string Name;
    StringRef Type, Default, Spelling;
  };
  std::vector<const Record *> Fields;
  for (const Record *R : Opts) {
    StringRef Kind = R->getValueAsDef("Kind")->getValueAsString("Name");
    if (!R->getValue("FieldName")) {
      if (Kind != "Input" && Kind != "Unknown" && !R->getValue("AliasTarget"))
        PrintFatalError(R->getLoc(), "an option of an OptionsStruct must be "
                                     "declared with BoolField, ValueField or "
                                     "AliasOf");
      continue;
    }
    if (Kind != "FlagOrEq" && Kind != "SeparateOrEq")
      PrintFatalError(R->getLoc(),
                      "a member is set by a FlagOrEq or SeparateOrEq");
    StringRef Type = R->getValueAsString("FieldType");
    if (Kind == "FlagOrEq" && Type != "bool" && Type != "llvm::BoolOrDefault" &&
        !R->getValue("BareValue"))
      PrintFatalError(R->getLoc(), "a FlagOrEq sets a bool or has a BareValue");
    Fields.push_back(R);
  }
  // Members in declaration order.
  std::vector<const Record *> ByID = Fields;
  llvm::sort(ByID, [](const Record *A, const Record *B) {
    return A->getID() < B->getID();
  });
  StringRef Prefix = Struct.getValueAsString("MemberPrefix");
  std::vector<Member> Members;
  StringMap<StringRef> MemberSpelling;
  for (const Record *R : ByID) {
    Member M{getMemberName(*R, Prefix), R->getValueAsString("FieldType"),
             R->getValueAsString("FieldDefault"), R->getValueAsString("Name")};
    auto [It, Inserted] = MemberSpelling.try_emplace(M.Name, M.Spelling);
    if (!Inserted)
      PrintFatalError(R->getLoc(),
                      "member '" + M.Name + "' is also set by -" + It->second);
    Members.push_back(M);
  }

  StringRef Name = Struct.getName();
  OS << "\n#ifdef OPTIONS_STRUCT_DECL\n#undef OPTIONS_STRUCT_DECL\n";
  OS << "#include \"llvm/ADT/ArrayRef.h\"\n";
  OS << "#include \"llvm/ADT/BoolOrDefault.h\"\n";
  OS << "#include \"llvm/ADT/StringRef.h\"\n";
  OS << "#include \"llvm/Support/Allocator.h\"\n";
  bool PerContext = Struct.getValueAsBit("PerContext");
  if (PerContext)
    OS << "#include \"llvm/Support/LibraryOptionsContext.h\"\n";
  OS << "\n";
  StringRef Namespace = Struct.getValueAsString("Namespace");
  OS << "namespace llvm {\nnamespace opt {\nclass Arg;\n";
  if (PerContext)
    OS << "class LibraryOptionsParser;\n";
  OS << "class OptTable;\n} // namespace opt\n} // namespace llvm\n\n";
  OS << "namespace " << Namespace << " {\n";
  OS << "struct " << Name << " {\n";
  if (Namespace != "llvm")
    OS << "  using StringRef = llvm::StringRef;\n";
  for (auto [R, M] : llvm::zip_equal(ByID, Members)) {
    ConditionScope CS(OS, *R);
    OS << "  " << M.Type << " " << M.Name << "{" << M.Default << "};\n";
  }
  OS << "\n  static constexpr bool PerContext = "
     << (PerContext ? "true" : "false") << ";\n";
  OS << "  static const llvm::opt::OptTable &optTable();\n";
  OS << "  /// Sets the member that \\p A names, allocating a list from \\p "
        "Alloc.\n  /// Returns false if the value is invalid.\n";
  OS << "  bool apply(const llvm::opt::Arg &A, llvm::BumpPtrAllocator "
        "&Alloc);\n";
  if (PerContext)
    OS << "\nprivate:\n  friend class llvm::cl::LibraryOptionsContext;\n"
          "  friend class llvm::opt::LibraryOptionsParser;\n";
  OS << "\n  static " << Name << " Global;\n";
  OS << "  static const " << Name << " Default;\n";
  OS << "};\n} // namespace " << Namespace << "\n";
  OS << "#endif // OPTIONS_STRUCT_DECL\n";

  std::string Qualified = (Namespace + "::" + Name).str();
  OS << "\n#ifdef OPTIONS_STRUCT_DEFS\n#undef OPTIONS_STRUCT_DEFS\n";
  OS << Qualified << " " << Qualified << "::Global;\n";
  OS << "LLVM_REQUIRE_CONSTANT_INITIALIZATION const " << Qualified << " "
     << Qualified << "::Default;\n\n";
  OS << "const llvm::opt::OptTable &" << Qualified << "::optTable() {\n";
  OS << "  static const llvm::opt::LibraryOptTable T(optionTables());\n";
  OS << "  return T;\n}\n\n";
  OS << "bool " << Qualified
     << "::apply(const llvm::opt::Arg &A, llvm::BumpPtrAllocator &Alloc) {\n";
  OS << "  switch (A.getOption().getID()) {\n";
  for (const Record *R : Fields) {
    ConditionScope CS(OS, *R);
    OS << "  case OPT_" << getStructOptionID(*R) << ":\n";
    std::string Member = getMemberName(*R, Prefix);
    if (R->getValue("BareValue"))
      OS << "    if (!A.getNumValues()) { " << Member << " = "
         << R->getValueAsString("BareValue") << "; return true; }\n";
    if (!isa<UnsetInit>(R->getValueInit("NormalizedValues"))) {
      SmallVector<StringRef> Values;
      R->getValueAsString("Values").split(Values, ',');
      std::vector<StringRef> Enumerators =
          R->getValueAsListOfStrings("NormalizedValues");
      if (Values.size() != Enumerators.size())
        PrintFatalError(R->getLoc(), "an EnumField needs one enumerator per "
                                     "value");
      // The generic lambda sets a scalar, a std::optional, or a list element.
      OS << "    return llvm::opt::parseArgValue(A.getValue(), " << Member
         << ", Alloc, [](llvm::StringRef V, auto &X) {\n";
      for (auto [Value, Enumerator] : llvm::zip_equal(Values, Enumerators))
        OS << "      if (V == \"" << Value
           << "\") {\n        X = " << Enumerator
           << ";\n        return true;\n      }\n";
      OS << "      return false;\n    });\n";
      continue;
    }
    // A FlagOrEq without a value means =true.
    StringRef Value =
        R->getValueAsDef("Kind")->getValueAsString("Name") == "FlagOrEq"
            ? "A.getNumValues() ? A.getValue() : \"true\""
            : "A.getValue()";
    OS << "    return llvm::opt::parseArgValue(" << Value << ", " << Member
       << ", Alloc);\n";
  }
  OS << "  }\n  llvm_unreachable(\"option without a member\");\n}\n";
  OS << "#endif // OPTIONS_STRUCT_DEFS\n";
}

/// 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");

  ArrayRef<const Record *> Structs =
      Records.getAllDerivedDefinitionsIfDefined("OptionsStruct");
  if (Structs.size() > 1)
    PrintFatalError(Structs[1]->getLoc(), "only one OptionsStruct is allowed");

  StringMap<const Record *> Members;
  for (const Record *R : Opts)
    if (R->getValue("FieldName"))
      Members[R->getValueAsString("Name")] = R;
  DenseMap<const Record *, const Record *> AliasTargets;
  for (const Record *R : Opts) {
    if (!R->getValue("AliasTarget"))
      continue;
    StringRef Target = R->getValueAsString("AliasTarget");
    const Record *T = Members.lookup(Target);
    if (!T)
      PrintFatalError(R->getLoc(),
                      "'-" + Target +
                          "' is not an option of the OptionsStruct");
    if (!getCondition(*T).empty())
      PrintFatalError(R->getLoc(), "an alias cannot refer to an option with a "
                                   "Condition");
    AliasTargets[R] = T;
  }

  emitSourceFileHeader("Option Parsing Definitions", OS);

  // Generate prefix groups.
  using PrefixKeyT = SmallVector<SmallString<2>, 2>;
  using PrefixesT = std::map<PrefixKeyT, unsigned>;
  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.
  using SubCommandKeyT = SmallVector<StringRef, 2>;
  using SubCommandIDsT = std::map<SubCommandKeyT, unsigned>;
  SubCommandIDsT SubCommandIDs;

  auto GetSubCommandIDsOffset = [&SubCommandIDs](const Record &R) {
    SubCommandKeyT SubCommandKey;
    for (const Record *SubCommand : R.getValueAsListOfDefs("SubCommands"))
      SubCommandKey.push_back(SubCommand->getName());
    return SubCommandIDs[SubCommandKey];
  };

  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);
  }

  llvm::StringToOffsetTable Table;
  for (const auto &[PrefixSet, _] : Prefixes)
    for (const auto &Prefix : PrefixSet)
      Table.GetOrAddStringOffset(Prefix);
  for (const Record &R : llvm::make_pointee_range(Groups)) {
    Table.GetOrAddStringOffset(R.getValueAsString("Name"));
    Table.GetOrAddStringOffset(getHelpText(R));
  }
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    Table.GetOrAddStringOffset(getOptionPrefixedName(R));
    Table.GetOrAddStringOffset(getHelpText(R));
    Table.GetOrAddStringOffset(getOptionalString(R, "MetaVarName"));
    Table.GetOrAddStringOffset(getOptionalString(R, "Values"));
    Table.GetOrAddStringOffset(getAliasArgsBlob(R));
    for (const Record *V : R.getValueAsListOfDefs("HelpTextsForVariants"))
      Table.GetOrAddStringOffset(V->getValueAsString("Text"));
  }

  // Flags and Visibility name enumerators of the including tool. An option
  // inherits its group's. Names are sorted so that equal masks share an
  // InfoExtra row.
  auto GetMask = [](const Record &R, StringRef Field) {
    std::set<StringRef> Names;
    for (const Init *I : *R.getValueAsListInit(Field))
      Names.insert(cast<DefInit>(I)->getDef()->getName());
    if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
      for (const Init *I : *DI->getDef()->getValueAsListInit(Field))
        Names.insert(cast<DefInit>(I)->getDef()->getName());
    std::string Mask;
    raw_string_ostream MaskOS(Mask);
    ListSeparator Sep(" | ");
    for (StringRef Name : Names)
      MaskOS << Sep << "static_cast<unsigned>(" << Name << ")";
    return Mask.empty() ? std::string("0") : Mask;
  };

  // IDs are 1-based positions in the table, which lists groups first.
  DenseMap<const Record *, unsigned> OptionID;
  for (const Record &R : llvm::make_pointee_range(Groups))
    OptionID.try_emplace(&R, OptionID.size() + 1);
  for (const Record &R : llvm::make_pointee_range(Opts))
    OptionID.try_emplace(&R, OptionID.size() + 1);
  // An OptionsStruct's rows name the IDs, since a false Condition omits a row
  // and shifts the IDs after it.
  auto GetRefID = [&](const Record &R, StringRef Field) -> std::string {
    const Record *Ref = Field == "Alias" ? AliasTargets.lookup(&R) : nullptr;
    if (const auto *DI = dyn_cast<DefInit>(R.getValueInit(Field)))
      Ref = DI->getDef();
    if (!Ref)
      return "0";
    if (Structs.empty())
      return utostr(OptionID.lookup(Ref));
    return "OPT_" + getStructOptionID(*Ref);
  };

  OS << "/////////\n";
  OS << "// Tables\n\n";
  // An OptionsStruct's definitions use the tables.
  OS << (Structs.empty()
             ? "#ifdef OPTTABLE_CODE\n"
             : "#if defined(OPTTABLE_CODE) || defined(OPTIONS_STRUCT_DEFS)\n");
  if (!Structs.empty())
    emitStructOptionIDs(Groups, Opts, OS);
  // A function rather than an object: the object needs dynamic relocations.
  OS << "static llvm::opt::OptTable::Tables optionTables() {\n";
  // An OptionsStruct's .cpp has no using-directive for llvm::opt.
  if (!Structs.empty())
    OS << "  using llvm::opt::DefaultVis, llvm::opt::HelpHidden,\n"
          "      llvm::opt::RenderAsInput, llvm::opt::RenderJoined,\n"
          "      llvm::opt::RenderSeparate;\n";
  Table.EmitStringTableDef(OS, "OptionStrTable");
  OS << "\n";

  // Dump prefixes.
  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;
      if (PrefixIndex > 255)
        PrintFatalError("too many distinct prefix sets");
      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\n";

  // Dump help text variants. Each option's variants form a run ended by a zero
  // row; offset 0 is the empty run.
  OS << "  static constexpr llvm::opt::OptTable::HelpTextVariant "
        "OptionHelpTextVariantsTable[] = {\n";
  DenseMap<const Record *, unsigned> HelpTextVariantsOffset;
  unsigned NumVariantRows = 1;
  OS << "    {0, 0},\n";
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    std::vector<const Record *> Variants =
        R.getValueAsListOfDefs("HelpTextsForVariants");
    if (Variants.empty())
      continue;
    HelpTextVariantsOffset[&R] = NumVariantRows;
    NumVariantRows += Variants.size() + 1;
    for (const Record *V : Variants) {
      const ListInit *Vis = V->getValueAsListInit("Visibilities");
      if (Vis->empty())
        PrintFatalError(V->getLoc(), "HelpTextVariant needs a visibility");
      OS << "    {";
      ListSeparator Sep(" | ");
      for (const Init *I : *Vis)
        OS << Sep << I->getAsUnquotedString();
      OS << ", ";
      writeStrTableOffset(OS, Table, V->getValueAsString("Text"));
      OS << "},\n";
    }
    OS << "    {0, 0},\n";
  }
  OS << "  };\n\n";

  // Dump subcommands.
  if (!SubCommands.empty()) {
    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\n";
  }

  // Dump subcommand IDs.
  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 = llvm::find_if(SubCommands, [&](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\n";

  // Fields that are rarely set or take few distinct values, in
  // OptTable::InfoExtra order. Options with equal values share a row; row 0 is
  // all zero.
  OS << "  static constexpr llvm::opt::OptTable::InfoExtra "
        "OptionInfoExtrasTable[] = {\n    {0, 0, 0, 0, 0, 0, 0, 0},\n";
  std::map<std::array<std::string, 8>, unsigned> ExtraRows;
  ExtraRows.try_emplace({"0", "0", "0", "0", "0", "0", "0", "0"}, 0);
  DenseMap<const Record *, unsigned> ExtraOffset;
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    int64_t NumArgs = R.getValueAsInt("NumArgs");
    if (NumArgs < 0 || NumArgs > 255)
      PrintFatalError(R.getLoc(), "NumArgs must be in [0, 255]");
    std::array<std::string, 8> Row = {
        utostr(*Table.GetStringOffset(getOptionalString(R, "MetaVarName"))),
        utostr(*Table.GetStringOffset(getAliasArgsBlob(R))),
        utostr(*Table.GetStringOffset(getOptionalString(R, "Values"))),
        GetMask(R, "Flags"),
        GetMask(R, "Visibility"),
        utostr(HelpTextVariantsOffset.lookup(&R)),
        utostr(GetSubCommandIDsOffset(R)),
        utostr(NumArgs)};
    auto [It, Inserted] = ExtraRows.try_emplace(Row, ExtraRows.size());
    if (Inserted) {
      OS << "    {";
      interleaveComma(Row, OS);
      OS << "},\n";
    }
    ExtraOffset[&R] = It->second;
  }
  OS << "  };\n\n";

  // Dump the option table in OptTable::Info field order.
  OS << "  static constexpr llvm::opt::OptTable::Info OptionInfoTable[] = {\n";
  for (const Record &R : llvm::make_pointee_range(Groups)) {
    OS << "    {";
    writeStrTableOffset(OS, Table, R.getValueAsString("Name"),
                        /*EmitComment=*/true);
    OS << ", ";
    writeStrTableOffset(OS, Table, getHelpText(R));
    OS << ", " << GetRefID(R, "Group")
       << ", 0, 0, 0, llvm::opt::Option::GroupClass},\n";
  }
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    ConditionScope CS(OS, R);
    OS << "    {";
    writeStrTableOffset(OS, Table, getOptionPrefixedName(R),
                        /*EmitComment=*/true);
    OS << ", ";
    writeStrTableOffset(OS, Table, getHelpText(R));
    OS << ", " << GetRefID(R, "Group") << ", " << GetRefID(R, "Alias");
    OS << ", " << ExtraOffset.lookup(&R);
    std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
    OS << ", " << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())];
    // An AliasOf without AliasArgs takes its target's kind.
    const Record *KindR = AliasTargets.lookup(&R);
    if (!KindR || !R.getValueAsListOfStrings("AliasArgs").empty())
      KindR = &R;
    OS << ", llvm::opt::Option::"
       << KindR->getValueAsDef("Kind")->getValueAsString("Name") << "Class},\n";
  }
  OS << "  };\n\n";

  OS << "  return {OptionStrTable, OptionPrefixesTable,\n";
  OS << "          OptionInfoTable, OptionInfoExtrasTable, "
        "OptionHelpTextVariantsTable, "
     << (SubCommands.empty() ? "{}" : "OptionSubCommands")
     << ", OptionSubCommandIDsTable};\n";
  OS << "}\n";
  OS << "#undef OPTTABLE_CODE\n";
  OS << (Structs.empty()
             ? "#endif // OPTTABLE_CODE\n\n"
             : "#endif // OPTTABLE_CODE || OPTIONS_STRUCT_DEFS\n\n");

  if (!Structs.empty())
    emitOptionsStruct(*Structs[0], Groups, Opts, OS);

  // Dump ValuesCode.
  OS << "/////////\n";
  OS << "// ValuesCode\n\n";
  OS << "#ifdef OPTTABLE_VALUES_CODE\n";
  std::vector<const Record *> ValuesCodeOpts;
  for (const Record &R : llvm::make_pointee_range(Opts)) {
    // The option values, if any;
    if (!isa<UnsetInit>(R.getValueInit("ValuesCode"))) {
      if (!isa<UnsetInit>(R.getValueInit("Values")))
        PrintFatalError(R.getLoc(), "cannot set both Values and ValuesCode");
      ValuesCodeOpts.push_back(&R);
      OS << "#define VALUES_CODE " << getOptionName(R) << "_Values\n";
      OS << R.getValueAsString("ValuesCode") << "\n";
      OS << "#undef VALUES_CODE\n";
    }
  }
  // A function keeps these strings out of a relocated table. It names OPT_ IDs,
  // so include this block after the option enum; a table that uses a different
  // ID prefix cannot use ValuesCode.
  OS << "static llvm::StringRef getOptionValuesCode(unsigned ID) {\n";
  OS << "  switch (ID) {\n";
  for (const Record *R : ValuesCodeOpts)
    OS << "  case OPT_" << getOptionName(*R) << ": return " << getOptionName(*R)
       << "_Values;\n";
  OS << "  }\n  return {};\n}\n";
  OS << "#undef OPTTABLE_VALUES_CODE\n";
  OS << "#endif // OPTTABLE_VALUES_CODE\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"),
                        /*EmitComment=*/true);

    // 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, 0, 0, 0, 0";

    // The option help text.
    OS << ", ";
    writeStrTableOffset(OS, Table, getHelpText(R));

    // Groups have no help text variants.
    OS << ", 0";

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

    // The option Values and SubCommandIDsOffset (unused for groups).
    OS << ", 0, 0)\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),
                        /*EmitComment=*/true);

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

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

    // 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 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).
    OS << ", ";
    writeStrTableOffset(OS, Table, getAliasArgsBlob(R));

    // "Flags" for the option, such as HelpHidden and Render*
    OS << ", " << GetMask(R, "Flags");

    // Option visibility, for sharing options between drivers.
    OS << ", " << GetMask(R, "Visibility");

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

    // The option help text.
    OS << ", ";
    writeStrTableOffset(OS, Table, getHelpText(R));

    // The option help text variants.
    OS << ", " << HelpTextVariantsOffset.lookup(&R);

    // The option meta-variable name.
    OS << ", ";
    writeStrTableOffset(OS, Table, getOptionalString(R, "MetaVarName"));

    // The option Values. Used for shell autocompletion.
    OS << ", ";
    writeStrTableOffset(OS, Table, getOptionalString(R, "Values"));

    // The option SubCommandIDsOffset.
    OS << ", " << GetSubCommandIDsOffset(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)) {
    ConditionScope CS(OS, R);
    // 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";
}

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