//===- DirectiveEmitter.cpp - Directive Language Emitter ------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// DirectiveEmitter uses the descriptions of directives and clauses to construct
// common code declarations to be used in Frontends.
//
//===----------------------------------------------------------------------===//

#include "llvm/TableGen/DirectiveEmitter.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"

#include <numeric>
#include <vector>

using namespace llvm;

namespace {
// Simple RAII helper for defining ifdef-undef-endif scopes.
class IfDefScope {
public:
  IfDefScope(StringRef Name, raw_ostream &OS) : Name(Name), OS(OS) {
    OS << "#ifdef " << Name << "\n"
       << "#undef " << Name << "\n";
  }

  ~IfDefScope() { OS << "\n#endif // " << Name << "\n\n"; }

private:
  StringRef Name;
  raw_ostream &OS;
};
} // namespace

// Generate enum class. Entries are emitted in the order in which they appear
// in the `Records` vector.
static void generateEnumClass(ArrayRef<const Record *> Records, raw_ostream &OS,
                              StringRef Enum, StringRef Prefix,
                              const DirectiveLanguage &DirLang,
                              bool ExportEnums) {
  OS << "\n";
  OS << "enum class " << Enum << " {\n";
  for (const auto &R : Records) {
    BaseRecord Rec(R);
    OS << "  " << Prefix << Rec.getFormattedName() << ",\n";
  }
  OS << "};\n";
  OS << "\n";
  OS << "static constexpr std::size_t " << Enum
     << "_enumSize = " << Records.size() << ";\n";

  // Make the enum values available in the defined namespace. This allows us to
  // write something like Enum_X if we have a `using namespace <CppNamespace>`.
  // At the same time we do not loose the strong type guarantees of the enum
  // class, that is we cannot pass an unsigned as Directive without an explicit
  // cast.
  if (ExportEnums) {
    OS << "\n";
    for (const auto &R : Records) {
      BaseRecord Rec(R);
      OS << "constexpr auto " << Prefix << Rec.getFormattedName() << " = "
         << "llvm::" << DirLang.getCppNamespace() << "::" << Enum
         << "::" << Prefix << Rec.getFormattedName() << ";\n";
    }
  }
}

// Generate enums for values that clauses can take.
// Also generate function declarations for get<Enum>Name(StringRef Str).
static void generateEnumClauseVal(ArrayRef<const Record *> Records,
                                  raw_ostream &OS,
                                  const DirectiveLanguage &DirLang,
                                  std::string &EnumHelperFuncs) {
  for (const auto &R : Records) {
    Clause C(R);
    const auto &ClauseVals = C.getClauseVals();
    if (ClauseVals.size() <= 0)
      continue;

    const auto &EnumName = C.getEnumName();
    if (EnumName.empty()) {
      PrintError("enumClauseValue field not set in Clause" +
                 C.getFormattedName() + ".");
      return;
    }

    OS << "\n";
    OS << "enum class " << EnumName << " {\n";
    for (const ClauseVal CVal : ClauseVals)
      OS << "  " << CVal.getRecordName() << "=" << CVal.getValue() << ",\n";
    OS << "};\n";

    if (DirLang.hasMakeEnumAvailableInNamespace()) {
      OS << "\n";
      for (const auto &CV : ClauseVals) {
        OS << "constexpr auto " << CV->getName() << " = "
           << "llvm::" << DirLang.getCppNamespace() << "::" << EnumName
           << "::" << CV->getName() << ";\n";
      }
      EnumHelperFuncs += (Twine("LLVM_ABI ") + Twine(EnumName) + Twine(" get") +
                          Twine(EnumName) + Twine("(StringRef);\n"))
                             .str();

      EnumHelperFuncs +=
          (Twine("LLVM_ABI llvm::StringRef get") + Twine(DirLang.getName()) +
           Twine(EnumName) + Twine("Name(") + Twine(EnumName) + Twine(");\n"))
              .str();
    }
  }
}

static bool hasDuplicateClauses(ArrayRef<const Record *> Clauses,
                                const Directive &Directive,
                                StringSet<> &CrtClauses) {
  bool HasError = false;
  for (const VersionedClause VerClause : Clauses) {
    const auto InsRes = CrtClauses.insert(VerClause.getClause().getName());
    if (!InsRes.second) {
      PrintError("Clause " + VerClause.getClause().getRecordName() +
                 " already defined on directive " + Directive.getRecordName());
      HasError = true;
    }
  }
  return HasError;
}

// Check for duplicate clauses in lists. Clauses cannot appear twice in the
// three allowed list. Also, since required implies allowed, clauses cannot
// appear in both the allowedClauses and requiredClauses lists.
static bool
hasDuplicateClausesInDirectives(ArrayRef<const Record *> Directives) {
  bool HasDuplicate = false;
  for (const Directive Dir : Directives) {
    StringSet<> Clauses;
    // Check for duplicates in the three allowed lists.
    if (hasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) ||
        hasDuplicateClauses(Dir.getAllowedOnceClauses(), Dir, Clauses) ||
        hasDuplicateClauses(Dir.getAllowedExclusiveClauses(), Dir, Clauses)) {
      HasDuplicate = true;
    }
    // Check for duplicate between allowedClauses and required
    Clauses.clear();
    if (hasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) ||
        hasDuplicateClauses(Dir.getRequiredClauses(), Dir, Clauses)) {
      HasDuplicate = true;
    }
    if (HasDuplicate)
      PrintFatalError("One or more clauses are defined multiple times on"
                      " directive " +
                      Dir.getRecordName());
  }

  return HasDuplicate;
}

// Check consitency of records. Return true if an error has been detected.
// Return false if the records are valid.
bool DirectiveLanguage::HasValidityErrors() const {
  if (getDirectiveLanguages().size() != 1) {
    PrintFatalError("A single definition of DirectiveLanguage is needed.");
    return true;
  }

  return hasDuplicateClausesInDirectives(getDirectives());
}

// Count the maximum number of leaf constituents per construct.
static size_t getMaxLeafCount(const DirectiveLanguage &DirLang) {
  size_t MaxCount = 0;
  for (const Directive D : DirLang.getDirectives())
    MaxCount = std::max(MaxCount, D.getLeafConstructs().size());
  return MaxCount;
}

// Generate the declaration section for the enumeration in the directive
// language.
static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
  const auto DirLang = DirectiveLanguage(Records);
  if (DirLang.HasValidityErrors())
    return;

  OS << "#ifndef LLVM_" << DirLang.getName() << "_INC\n";
  OS << "#define LLVM_" << DirLang.getName() << "_INC\n";
  OS << "\n#include \"llvm/ADT/ArrayRef.h\"\n";

  if (DirLang.hasEnableBitmaskEnumInNamespace())
    OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";

  OS << "#include \"llvm/Support/Compiler.h\"\n";
  OS << "#include <cstddef>\n"; // for size_t
  OS << "\n";
  OS << "namespace llvm {\n";
  OS << "class StringRef;\n";

  // Open namespaces defined in the directive language
  SmallVector<StringRef, 2> Namespaces;
  SplitString(DirLang.getCppNamespace(), Namespaces, "::");
  for (auto Ns : Namespaces)
    OS << "namespace " << Ns << " {\n";

  if (DirLang.hasEnableBitmaskEnumInNamespace())
    OS << "\nLLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n";

  // Emit Directive associations
  std::vector<const Record *> Associations;
  copy_if(DirLang.getAssociations(), std::back_inserter(Associations),
          // Skip the "special" value
          [](const Record *Def) { return Def->getName() != "AS_FromLeaves"; });
  generateEnumClass(Associations, OS, "Association",
                    /*Prefix=*/"", DirLang, /*ExportEnums=*/false);

  generateEnumClass(DirLang.getCategories(), OS, "Category", /*Prefix=*/"",
                    DirLang, /*ExportEnums=*/false);

  // Emit Directive enumeration
  generateEnumClass(DirLang.getDirectives(), OS, "Directive",
                    DirLang.getDirectivePrefix(), DirLang,
                    DirLang.hasMakeEnumAvailableInNamespace());

  // Emit Clause enumeration
  generateEnumClass(DirLang.getClauses(), OS, "Clause",
                    DirLang.getClausePrefix(), DirLang,
                    DirLang.hasMakeEnumAvailableInNamespace());

  // Emit ClauseVal enumeration
  std::string EnumHelperFuncs;
  generateEnumClauseVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs);

  // Generic function signatures
  OS << "\n";
  OS << "// Enumeration helper functions\n";
  OS << "LLVM_ABI Directive get" << DirLang.getName()
     << "DirectiveKind(llvm::StringRef Str);\n";
  OS << "\n";
  OS << "LLVM_ABI llvm::StringRef get" << DirLang.getName()
     << "DirectiveName(Directive D);\n";
  OS << "\n";
  OS << "LLVM_ABI Clause get" << DirLang.getName()
     << "ClauseKind(llvm::StringRef Str);\n";
  OS << "\n";
  OS << "LLVM_ABI llvm::StringRef get" << DirLang.getName()
     << "ClauseName(Clause C);\n";
  OS << "\n";
  OS << "/// Return true if \\p C is a valid clause for \\p D in version \\p "
     << "Version.\n";
  OS << "LLVM_ABI bool isAllowedClauseForDirective(Directive D, "
     << "Clause C, unsigned Version);\n";
  OS << "\n";
  OS << "constexpr std::size_t getMaxLeafCount() { return "
     << getMaxLeafCount(DirLang) << "; }\n";
  OS << "LLVM_ABI Association getDirectiveAssociation(Directive D);\n";
  OS << "LLVM_ABI Category getDirectiveCategory(Directive D);\n";
  if (EnumHelperFuncs.length() > 0) {
    OS << EnumHelperFuncs;
    OS << "\n";
  }

  // Closing namespaces
  for (auto Ns : reverse(Namespaces))
    OS << "} // namespace " << Ns << "\n";

  OS << "} // namespace llvm\n";

  OS << "#endif // LLVM_" << DirLang.getName() << "_INC\n";
}

// Generate function implementation for get<Enum>Name(StringRef Str)
static void generateGetName(ArrayRef<const Record *> Records, raw_ostream &OS,
                            StringRef Enum, const DirectiveLanguage &DirLang,
                            StringRef Prefix) {
  OS << "\n";
  OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
     << DirLang.getName() << Enum << "Name(" << Enum << " Kind) {\n";
  OS << "  switch (Kind) {\n";
  for (const BaseRecord Rec : Records) {
    OS << "    case " << Prefix << Rec.getFormattedName() << ":\n";
    OS << "      return \"";
    if (Rec.getAlternativeName().empty())
      OS << Rec.getName();
    else
      OS << Rec.getAlternativeName();
    OS << "\";\n";
  }
  OS << "  }\n"; // switch
  OS << "  llvm_unreachable(\"Invalid " << DirLang.getName() << " " << Enum
     << " kind\");\n";
  OS << "}\n";
}

// Generate function implementation for get<Enum>Kind(StringRef Str)
static void generateGetKind(ArrayRef<const Record *> Records, raw_ostream &OS,
                            StringRef Enum, const DirectiveLanguage &DirLang,
                            StringRef Prefix, bool ImplicitAsUnknown) {

  const auto *DefaultIt = find_if(
      Records, [](const Record *R) { return R->getValueAsBit("isDefault"); });

  if (DefaultIt == Records.end()) {
    PrintError("At least one " + Enum + " must be defined as default.");
    return;
  }

  BaseRecord DefaultRec(*DefaultIt);

  OS << "\n";
  OS << Enum << " llvm::" << DirLang.getCppNamespace() << "::get"
     << DirLang.getName() << Enum << "Kind(llvm::StringRef Str) {\n";
  OS << "  return llvm::StringSwitch<" << Enum << ">(Str)\n";

  for (const auto &R : Records) {
    BaseRecord Rec(R);
    if (ImplicitAsUnknown && R->getValueAsBit("isImplicit")) {
      OS << "    .Case(\"" << Rec.getName() << "\"," << Prefix
         << DefaultRec.getFormattedName() << ")\n";
    } else {
      OS << "    .Case(\"" << Rec.getName() << "\"," << Prefix
         << Rec.getFormattedName() << ")\n";
    }
  }
  OS << "    .Default(" << Prefix << DefaultRec.getFormattedName() << ");\n";
  OS << "}\n";
}

// Generate function implementation for get<ClauseVal>Kind(StringRef Str)
static void generateGetKindClauseVal(const DirectiveLanguage &DirLang,
                                     raw_ostream &OS) {
  for (const Clause C : DirLang.getClauses()) {
    const auto &ClauseVals = C.getClauseVals();
    if (ClauseVals.size() <= 0)
      continue;

    auto DefaultIt = find_if(ClauseVals, [](const Record *CV) {
      return CV->getValueAsBit("isDefault");
    });

    if (DefaultIt == ClauseVals.end()) {
      PrintError("At least one val in Clause " + C.getFormattedName() +
                 " must be defined as default.");
      return;
    }
    const auto DefaultName = (*DefaultIt)->getName();

    const auto &EnumName = C.getEnumName();
    if (EnumName.empty()) {
      PrintError("enumClauseValue field not set in Clause" +
                 C.getFormattedName() + ".");
      return;
    }

    OS << "\n";
    OS << EnumName << " llvm::" << DirLang.getCppNamespace() << "::get"
       << EnumName << "(llvm::StringRef Str) {\n";
    OS << "  return llvm::StringSwitch<" << EnumName << ">(Str)\n";
    for (const auto &CV : ClauseVals) {
      ClauseVal CVal(CV);
      OS << "    .Case(\"" << CVal.getFormattedName() << "\"," << CV->getName()
         << ")\n";
    }
    OS << "    .Default(" << DefaultName << ");\n";
    OS << "}\n";

    OS << "\n";
    OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
       << DirLang.getName() << EnumName
       << "Name(llvm::" << DirLang.getCppNamespace() << "::" << EnumName
       << " x) {\n";
    OS << "  switch (x) {\n";
    for (const auto &CV : ClauseVals) {
      ClauseVal CVal(CV);
      OS << "    case " << CV->getName() << ":\n";
      OS << "      return \"" << CVal.getFormattedName() << "\";\n";
    }
    OS << "  }\n"; // switch
    OS << "  llvm_unreachable(\"Invalid " << DirLang.getName() << " "
       << EnumName << " kind\");\n";
    OS << "}\n";
  }
}

static void generateCaseForVersionedClauses(ArrayRef<const Record *> Clauses,
                                            raw_ostream &OS,
                                            StringRef DirectiveName,
                                            const DirectiveLanguage &DirLang,
                                            StringSet<> &Cases) {
  for (const VersionedClause VerClause : Clauses) {
    const auto ClauseFormattedName = VerClause.getClause().getFormattedName();

    if (Cases.insert(ClauseFormattedName).second) {
      OS << "        case " << DirLang.getClausePrefix() << ClauseFormattedName
         << ":\n";
      OS << "          return " << VerClause.getMinVersion()
         << " <= Version && " << VerClause.getMaxVersion() << " >= Version;\n";
    }
  }
}

static std::string getDirectiveName(const DirectiveLanguage &DirLang,
                                    const Record *Rec) {
  Directive Dir(Rec);
  return (Twine("llvm::") + DirLang.getCppNamespace() +
          "::" + DirLang.getDirectivePrefix() + Dir.getFormattedName())
      .str();
}

static std::string getDirectiveType(const DirectiveLanguage &DirLang) {
  return (Twine("llvm::") + DirLang.getCppNamespace() + "::Directive").str();
}

// Generate the isAllowedClauseForDirective function implementation.
static void generateIsAllowedClause(const DirectiveLanguage &DirLang,
                                    raw_ostream &OS) {
  OS << "\n";
  OS << "bool llvm::" << DirLang.getCppNamespace()
     << "::isAllowedClauseForDirective("
     << "Directive D, Clause C, unsigned Version) {\n";
  OS << "  assert(unsigned(D) <= llvm::" << DirLang.getCppNamespace()
     << "::Directive_enumSize);\n";
  OS << "  assert(unsigned(C) <= llvm::" << DirLang.getCppNamespace()
     << "::Clause_enumSize);\n";

  OS << "  switch (D) {\n";

  for (const Directive Dir : DirLang.getDirectives()) {
    OS << "    case " << DirLang.getDirectivePrefix() << Dir.getFormattedName()
       << ":\n";
    if (Dir.getAllowedClauses().empty() &&
        Dir.getAllowedOnceClauses().empty() &&
        Dir.getAllowedExclusiveClauses().empty() &&
        Dir.getRequiredClauses().empty()) {
      OS << "      return false;\n";
    } else {
      OS << "      switch (C) {\n";

      StringSet<> Cases;

      generateCaseForVersionedClauses(Dir.getAllowedClauses(), OS,
                                      Dir.getName(), DirLang, Cases);

      generateCaseForVersionedClauses(Dir.getAllowedOnceClauses(), OS,
                                      Dir.getName(), DirLang, Cases);

      generateCaseForVersionedClauses(Dir.getAllowedExclusiveClauses(), OS,
                                      Dir.getName(), DirLang, Cases);

      generateCaseForVersionedClauses(Dir.getRequiredClauses(), OS,
                                      Dir.getName(), DirLang, Cases);

      OS << "        default:\n";
      OS << "          return false;\n";
      OS << "      }\n"; // End of clauses switch
    }
    OS << "      break;\n";
  }

  OS << "  }\n"; // End of directives switch
  OS << "  llvm_unreachable(\"Invalid " << DirLang.getName()
     << " Directive kind\");\n";
  OS << "}\n"; // End of function isAllowedClauseForDirective
}

static void emitLeafTable(const DirectiveLanguage &DirLang, raw_ostream &OS,
                          StringRef TableName) {
  // The leaf constructs are emitted in a form of a 2D table, where each
  // row corresponds to a directive (and there is a row for each directive).
  //
  // Each row consists of
  // - the id of the directive itself,
  // - number of leaf constructs that will follow (0 for leafs),
  // - ids of the leaf constructs (none if the directive is itself a leaf).
  // The total number of these entries is at most MaxLeafCount+2. If this
  // number is less than that, it is padded to occupy exactly MaxLeafCount+2
  // entries in memory.
  //
  // The rows are stored in the table in the lexicographical order. This
  // is intended to enable binary search when mapping a sequence of leafs
  // back to the compound directive.
  // The consequence of that is that in order to find a row corresponding
  // to the given directive, we'd need to scan the first element of each
  // row. To avoid this, an auxiliary ordering table is created, such that
  //   row for Dir_A = table[auxiliary[Dir_A]].

  ArrayRef<const Record *> Directives = DirLang.getDirectives();
  DenseMap<const Record *, int> DirId; // Record * -> llvm::omp::Directive

  for (auto [Idx, Rec] : enumerate(Directives))
    DirId.insert(std::make_pair(Rec, Idx));

  using LeafList = std::vector<int>;
  int MaxLeafCount = getMaxLeafCount(DirLang);

  // The initial leaf table, rows order is same as directive order.
  std::vector<LeafList> LeafTable(Directives.size());
  for (auto [Idx, Rec] : enumerate(Directives)) {
    Directive Dir(Rec);
    std::vector<const Record *> Leaves = Dir.getLeafConstructs();

    auto &List = LeafTable[Idx];
    List.resize(MaxLeafCount + 2);
    List[0] = Idx;           // The id of the directive itself.
    List[1] = Leaves.size(); // The number of leaves to follow.

    for (int I = 0; I != MaxLeafCount; ++I)
      List[I + 2] =
          static_cast<size_t>(I) < Leaves.size() ? DirId.at(Leaves[I]) : -1;
  }

  // Some Fortran directives are delimited, i.e. they have the form of
  // "directive"---"end directive". If "directive" is a compound construct,
  // then the set of leaf constituents will be nonempty and the same for
  // both directives. Given this set of leafs, looking up the corresponding
  // compound directive should return "directive", and not "end directive".
  // To avoid this problem, gather all "end directives" at the end of the
  // leaf table, and only do the search on the initial segment of the table
  // that excludes the "end directives".
  // It's safe to find all directives whose names begin with "end ". The
  // problem only exists for compound directives, like "end do simd".
  // All existing directives with names starting with "end " are either
  // "end directives" for an existing "directive", or leaf directives
  // (such as "end declare target").
  DenseSet<int> EndDirectives;
  for (auto [Rec, Id] : DirId) {
    if (Directive(Rec).getName().starts_with_insensitive("end "))
      EndDirectives.insert(Id);
  }

  // Avoid sorting the vector<vector> array, instead sort an index array.
  // It will also be useful later to create the auxiliary indexing array.
  std::vector<int> Ordering(Directives.size());
  std::iota(Ordering.begin(), Ordering.end(), 0);

  sort(Ordering, [&](int A, int B) {
    auto &LeavesA = LeafTable[A];
    auto &LeavesB = LeafTable[B];
    int DirA = LeavesA[0], DirB = LeavesB[0];
    // First of all, end directives compare greater than non-end directives.
    int IsEndA = EndDirectives.count(DirA), IsEndB = EndDirectives.count(DirB);
    if (IsEndA != IsEndB)
      return IsEndA < IsEndB;
    if (LeavesA[1] == 0 && LeavesB[1] == 0)
      return DirA < DirB;
    return std::lexicographical_compare(&LeavesA[2], &LeavesA[2] + LeavesA[1],
                                        &LeavesB[2], &LeavesB[2] + LeavesB[1]);
  });

  // Emit the table

  // The directives are emitted into a scoped enum, for which the underlying
  // type is `int` (by default). The code above uses `int` to store directive
  // ids, so make sure that we catch it when something changes in the
  // underlying type.
  std::string DirectiveType = getDirectiveType(DirLang);
  OS << "\nstatic_assert(sizeof(" << DirectiveType << ") == sizeof(int));\n";

  OS << "[[maybe_unused]] static const " << DirectiveType << ' ' << TableName
     << "[][" << MaxLeafCount + 2 << "] = {\n";
  for (size_t I = 0, E = Directives.size(); I != E; ++I) {
    auto &Leaves = LeafTable[Ordering[I]];
    OS << "    {" << getDirectiveName(DirLang, Directives[Leaves[0]]);
    OS << ", static_cast<" << DirectiveType << ">(" << Leaves[1] << "),";
    for (size_t I = 2, E = Leaves.size(); I != E; ++I) {
      int Idx = Leaves[I];
      if (Idx >= 0)
        OS << ' ' << getDirectiveName(DirLang, Directives[Leaves[I]]) << ',';
      else
        OS << " static_cast<" << DirectiveType << ">(-1),";
    }
    OS << "},\n";
  }
  OS << "};\n\n";

  // Emit a marker where the first "end directive" is.
  auto FirstE = find_if(Ordering, [&](int RowIdx) {
    return EndDirectives.count(LeafTable[RowIdx][0]);
  });
  OS << "[[maybe_unused]] static auto " << TableName
     << "EndDirective = " << TableName << " + "
     << std::distance(Ordering.begin(), FirstE) << ";\n\n";

  // Emit the auxiliary index table: it's the inverse of the `Ordering`
  // table above.
  OS << "[[maybe_unused]] static const int " << TableName << "Ordering[] = {\n";
  OS << "   ";
  std::vector<int> Reverse(Ordering.size());
  for (int I = 0, E = Ordering.size(); I != E; ++I)
    Reverse[Ordering[I]] = I;
  for (int Idx : Reverse)
    OS << ' ' << Idx << ',';
  OS << "\n};\n";
}

static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang,
                                            raw_ostream &OS) {
  enum struct Association {
    None = 0, // None should be the smallest value.
    Block,    // The values of the rest don't matter.
    Declaration,
    Delimited,
    Loop,
    Separating,
    FromLeaves,
    Invalid,
  };

  ArrayRef<const Record *> Associations = DirLang.getAssociations();

  auto GetAssocValue = [](StringRef Name) -> Association {
    return StringSwitch<Association>(Name)
        .Case("AS_Block", Association::Block)
        .Case("AS_Declaration", Association::Declaration)
        .Case("AS_Delimited", Association::Delimited)
        .Case("AS_Loop", Association::Loop)
        .Case("AS_None", Association::None)
        .Case("AS_Separating", Association::Separating)
        .Case("AS_FromLeaves", Association::FromLeaves)
        .Default(Association::Invalid);
  };

  auto GetAssocName = [&](Association A) -> StringRef {
    if (A != Association::Invalid && A != Association::FromLeaves) {
      const auto *F = find_if(Associations, [&](const Record *R) {
        return GetAssocValue(R->getName()) == A;
      });
      if (F != Associations.end())
        return (*F)->getValueAsString("name"); // enum name
    }
    llvm_unreachable("Unexpected association value");
  };

  auto ErrorPrefixFor = [&](Directive D) -> std::string {
    return (Twine("Directive '") + D.getName() + "' in namespace '" +
            DirLang.getCppNamespace() + "' ")
        .str();
  };

  auto Reduce = [&](Association A, Association B) -> Association {
    if (A > B)
      std::swap(A, B);

    // Calculate the result using the following rules:
    //   x + x = x
    //   AS_None + x = x
    //   AS_Block + AS_Loop = AS_Loop
    if (A == Association::None || A == B)
      return B;
    if (A == Association::Block && B == Association::Loop)
      return B;
    if (A == Association::Loop && B == Association::Block)
      return A;
    return Association::Invalid;
  };

  DenseMap<const Record *, Association> AsMap;

  auto CompAssocImpl = [&](const Record *R, auto &&Self) -> Association {
    if (auto F = AsMap.find(R); F != AsMap.end())
      return F->second;

    Directive D(R);
    Association AS = GetAssocValue(D.getAssociation()->getName());
    if (AS == Association::Invalid) {
      PrintFatalError(ErrorPrefixFor(D) +
                      "has an unrecognized value for association: '" +
                      D.getAssociation()->getName() + "'");
    }
    if (AS != Association::FromLeaves) {
      AsMap.insert(std::make_pair(R, AS));
      return AS;
    }
    // Compute the association from leaf constructs.
    std::vector<const Record *> Leaves = D.getLeafConstructs();
    if (Leaves.empty()) {
      errs() << D.getName() << '\n';
      PrintFatalError(ErrorPrefixFor(D) +
                      "requests association to be computed from leaves, "
                      "but it has no leaves");
    }

    Association Result = Self(Leaves[0], Self);
    for (int I = 1, E = Leaves.size(); I < E; ++I) {
      Association A = Self(Leaves[I], Self);
      Association R = Reduce(Result, A);
      if (R == Association::Invalid) {
        PrintFatalError(ErrorPrefixFor(D) +
                        "has leaves with incompatible association values: " +
                        GetAssocName(A) + " and " + GetAssocName(R));
      }
      Result = R;
    }

    assert(Result != Association::Invalid);
    assert(Result != Association::FromLeaves);
    AsMap.insert(std::make_pair(R, Result));
    return Result;
  };

  for (const Record *R : DirLang.getDirectives())
    CompAssocImpl(R, CompAssocImpl); // Updates AsMap.

  OS << '\n';

  auto GetQualifiedName = [&](StringRef Formatted) -> std::string {
    return (Twine("llvm::") + DirLang.getCppNamespace() +
            "::Directive::" + DirLang.getDirectivePrefix() + Formatted)
        .str();
  };

  std::string DirectiveTypeName =
      "llvm::" + DirLang.getCppNamespace().str() + "::Directive";
  std::string AssociationTypeName =
      "llvm::" + DirLang.getCppNamespace().str() + "::Association";

  OS << AssociationTypeName << " llvm::" << DirLang.getCppNamespace()
     << "::getDirectiveAssociation(" << DirectiveTypeName << " Dir) {\n";
  OS << "  switch (Dir) {\n";
  for (const Record *R : DirLang.getDirectives()) {
    if (auto F = AsMap.find(R); F != AsMap.end()) {
      Directive Dir(R);
      OS << "  case " << GetQualifiedName(Dir.getFormattedName()) << ":\n";
      OS << "    return " << AssociationTypeName
         << "::" << GetAssocName(F->second) << ";\n";
    }
  }
  OS << "  } // switch (Dir)\n";
  OS << "  llvm_unreachable(\"Unexpected directive\");\n";
  OS << "}\n";
}

static void generateGetDirectiveCategory(const DirectiveLanguage &DirLang,
                                         raw_ostream &OS) {
  std::string LangNamespace = "llvm::" + DirLang.getCppNamespace().str();
  std::string CategoryTypeName = LangNamespace + "::Category";
  std::string CategoryNamespace = CategoryTypeName + "::";

  OS << '\n';
  OS << CategoryTypeName << ' ' << LangNamespace << "::getDirectiveCategory("
     << getDirectiveType(DirLang) << " Dir) {\n";
  OS << "  switch (Dir) {\n";

  for (const Record *R : DirLang.getDirectives()) {
    Directive D(R);
    OS << "  case " << getDirectiveName(DirLang, R) << ":\n";
    OS << "    return " << CategoryNamespace
       << D.getCategory()->getValueAsString("name") << ";\n";
  }
  OS << "  } // switch (Dir)\n";
  OS << "  llvm_unreachable(\"Unexpected directive\");\n";
  OS << "}\n";
}

// Generate a simple enum set with the give clauses.
static void generateClauseSet(ArrayRef<const Record *> Clauses, raw_ostream &OS,
                              StringRef ClauseSetPrefix, const Directive &Dir,
                              const DirectiveLanguage &DirLang) {

  OS << "\n";
  OS << "  static " << DirLang.getClauseEnumSetClass() << " " << ClauseSetPrefix
     << DirLang.getDirectivePrefix() << Dir.getFormattedName() << " {\n";

  for (const auto &C : Clauses) {
    VersionedClause VerClause(C);
    OS << "    llvm::" << DirLang.getCppNamespace()
       << "::Clause::" << DirLang.getClausePrefix()
       << VerClause.getClause().getFormattedName() << ",\n";
  }
  OS << "  };\n";
}

// Generate an enum set for the 4 kinds of clauses linked to a directive.
static void generateDirectiveClauseSets(const DirectiveLanguage &DirLang,
                                        raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_SETS", OS);

  OS << "\n";
  OS << "namespace llvm {\n";

  // Open namespaces defined in the directive language.
  SmallVector<StringRef, 2> Namespaces;
  SplitString(DirLang.getCppNamespace(), Namespaces, "::");
  for (auto Ns : Namespaces)
    OS << "namespace " << Ns << " {\n";

  for (const Directive Dir : DirLang.getDirectives()) {
    OS << "\n";
    OS << "  // Sets for " << Dir.getName() << "\n";

    generateClauseSet(Dir.getAllowedClauses(), OS, "allowedClauses_", Dir,
                      DirLang);
    generateClauseSet(Dir.getAllowedOnceClauses(), OS, "allowedOnceClauses_",
                      Dir, DirLang);
    generateClauseSet(Dir.getAllowedExclusiveClauses(), OS,
                      "allowedExclusiveClauses_", Dir, DirLang);
    generateClauseSet(Dir.getRequiredClauses(), OS, "requiredClauses_", Dir,
                      DirLang);
  }

  // Closing namespaces
  for (auto Ns : reverse(Namespaces))
    OS << "} // namespace " << Ns << "\n";

  OS << "} // namespace llvm\n";
}

// Generate a map of directive (key) with DirectiveClauses struct as values.
// The struct holds the 4 sets of enumeration for the 4 kinds of clauses
// allowances (allowed, allowed once, allowed exclusive and required).
static void generateDirectiveClauseMap(const DirectiveLanguage &DirLang,
                                       raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_MAP", OS);

  OS << "\n";
  OS << "{\n";

  for (const Directive Dir : DirLang.getDirectives()) {
    OS << "  {llvm::" << DirLang.getCppNamespace()
       << "::Directive::" << DirLang.getDirectivePrefix()
       << Dir.getFormattedName() << ",\n";
    OS << "    {\n";
    OS << "      llvm::" << DirLang.getCppNamespace() << "::allowedClauses_"
       << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
    OS << "      llvm::" << DirLang.getCppNamespace() << "::allowedOnceClauses_"
       << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
    OS << "      llvm::" << DirLang.getCppNamespace()
       << "::allowedExclusiveClauses_" << DirLang.getDirectivePrefix()
       << Dir.getFormattedName() << ",\n";
    OS << "      llvm::" << DirLang.getCppNamespace() << "::requiredClauses_"
       << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
    OS << "    }\n";
    OS << "  },\n";
  }

  OS << "}\n";
}

// Generate classes entry for Flang clauses in the Flang parse-tree
// If the clause as a non-generic class, no entry is generated.
// If the clause does not hold a value, an EMPTY_CLASS is used.
// If the clause class is generic then a WRAPPER_CLASS is used. When the value
// is optional, the value class is wrapped into a std::optional.
static void generateFlangClauseParserClass(const DirectiveLanguage &DirLang,
                                           raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES", OS);

  OS << "\n";

  for (const Clause Clause : DirLang.getClauses()) {
    if (!Clause.getFlangClass().empty()) {
      OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() << ", ";
      if (Clause.isValueOptional() && Clause.isValueList()) {
        OS << "std::optional<std::list<" << Clause.getFlangClass() << ">>";
      } else if (Clause.isValueOptional()) {
        OS << "std::optional<" << Clause.getFlangClass() << ">";
      } else if (Clause.isValueList()) {
        OS << "std::list<" << Clause.getFlangClass() << ">";
      } else {
        OS << Clause.getFlangClass();
      }
    } else {
      OS << "EMPTY_CLASS(" << Clause.getFormattedParserClassName();
    }
    OS << ");\n";
  }
}

// Generate a list of the different clause classes for Flang.
static void generateFlangClauseParserClassList(const DirectiveLanguage &DirLang,
                                               raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST", OS);

  OS << "\n";
  interleaveComma(DirLang.getClauses(), OS, [&](const Record *C) {
    Clause Clause(C);
    OS << Clause.getFormattedParserClassName() << "\n";
  });
}

// Generate dump node list for the clauses holding a generic class name.
static void generateFlangClauseDump(const DirectiveLanguage &DirLang,
                                    raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_DUMP_PARSE_TREE_CLAUSES", OS);

  OS << "\n";
  for (const Clause Clause : DirLang.getClauses()) {
    OS << "NODE(" << DirLang.getFlangClauseBaseClass() << ", "
       << Clause.getFormattedParserClassName() << ")\n";
  }
}

// Generate Unparse functions for clauses classes in the Flang parse-tree
// If the clause is a non-generic class, no entry is generated.
static void generateFlangClauseUnparse(const DirectiveLanguage &DirLang,
                                       raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_CLAUSE_UNPARSE", OS);

  OS << "\n";

  for (const Clause Clause : DirLang.getClauses()) {
    if (!Clause.getFlangClass().empty()) {
      if (Clause.isValueOptional() && Clause.getDefaultValue().empty()) {
        OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
           << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
        OS << "  Word(\"" << Clause.getName().upper() << "\");\n";

        OS << "  Walk(\"(\", x.v, \")\");\n";
        OS << "}\n";
      } else if (Clause.isValueOptional()) {
        OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
           << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
        OS << "  Word(\"" << Clause.getName().upper() << "\");\n";
        OS << "  Put(\"(\");\n";
        OS << "  if (x.v.has_value())\n";
        if (Clause.isValueList())
          OS << "    Walk(x.v, \",\");\n";
        else
          OS << "    Walk(x.v);\n";
        OS << "  else\n";
        OS << "    Put(\"" << Clause.getDefaultValue() << "\");\n";
        OS << "  Put(\")\");\n";
        OS << "}\n";
      } else {
        OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
           << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
        OS << "  Word(\"" << Clause.getName().upper() << "\");\n";
        OS << "  Put(\"(\");\n";
        if (Clause.isValueList())
          OS << "  Walk(x.v, \",\");\n";
        else
          OS << "  Walk(x.v);\n";
        OS << "  Put(\")\");\n";
        OS << "}\n";
      }
    } else {
      OS << "void Before(const " << DirLang.getFlangClauseBaseClass()
         << "::" << Clause.getFormattedParserClassName() << " &) { Word(\""
         << Clause.getName().upper() << "\"); }\n";
    }
  }
}

// Generate check in the Enter functions for clauses classes.
static void generateFlangClauseCheckPrototypes(const DirectiveLanguage &DirLang,
                                               raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_CLAUSE_CHECK_ENTER", OS);

  OS << "\n";
  for (const Clause Clause : DirLang.getClauses()) {
    OS << "void Enter(const parser::" << DirLang.getFlangClauseBaseClass()
       << "::" << Clause.getFormattedParserClassName() << " &);\n";
  }
}

// Generate the mapping for clauses between the parser class and the
// corresponding clause Kind
static void generateFlangClauseParserKindMap(const DirectiveLanguage &DirLang,
                                             raw_ostream &OS) {

  IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_KIND_MAP", OS);

  OS << "\n";
  for (const Clause Clause : DirLang.getClauses()) {
    OS << "if constexpr (std::is_same_v<A, parser::"
       << DirLang.getFlangClauseBaseClass()
       << "::" << Clause.getFormattedParserClassName();
    OS << ">)\n";
    OS << "  return llvm::" << DirLang.getCppNamespace()
       << "::Clause::" << DirLang.getClausePrefix() << Clause.getFormattedName()
       << ";\n";
  }

  OS << "llvm_unreachable(\"Invalid " << DirLang.getName()
     << " Parser clause\");\n";
}

static bool compareClauseName(const Record *R1, const Record *R2) {
  Clause C1(R1);
  Clause C2(R2);
  return (C1.getName() > C2.getName());
}

// Generate the parser for the clauses.
static void generateFlangClausesParser(const DirectiveLanguage &DirLang,
                                       raw_ostream &OS) {
  std::vector<const Record *> Clauses = DirLang.getClauses();
  // Sort clauses in reverse alphabetical order so with clauses with same
  // beginning, the longer option is tried before.
  sort(Clauses, compareClauseName);
  IfDefScope Scope("GEN_FLANG_CLAUSES_PARSER", OS);
  OS << "\n";
  unsigned Index = 0;
  unsigned LastClauseIndex = Clauses.size() - 1;
  OS << "TYPE_PARSER(\n";
  for (const Clause Clause : Clauses) {
    if (Clause.getAliases().empty()) {
      OS << "  \"" << Clause.getName() << "\"";
    } else {
      OS << "  ("
         << "\"" << Clause.getName() << "\"_tok";
      for (StringRef Alias : Clause.getAliases()) {
        OS << " || \"" << Alias << "\"_tok";
      }
      OS << ")";
    }

    OS << " >> construct<" << DirLang.getFlangClauseBaseClass()
       << ">(construct<" << DirLang.getFlangClauseBaseClass()
       << "::" << Clause.getFormattedParserClassName() << ">(";
    if (Clause.getFlangClass().empty()) {
      OS << "))";
      if (Index != LastClauseIndex)
        OS << " ||";
      OS << "\n";
      ++Index;
      continue;
    }

    if (Clause.isValueOptional())
      OS << "maybe(";
    OS << "parenthesized(";
    if (Clause.isValueList())
      OS << "nonemptyList(";

    if (!Clause.getPrefix().empty())
      OS << "\"" << Clause.getPrefix() << ":\" >> ";

    // The common Flang parser are used directly. Their name is identical to
    // the Flang class with first letter as lowercase. If the Flang class is
    // not a common class, we assume there is a specific Parser<>{} with the
    // Flang class name provided.
    SmallString<128> Scratch;
    StringRef Parser =
        StringSwitch<StringRef>(Clause.getFlangClass())
            .Case("Name", "name")
            .Case("ScalarIntConstantExpr", "scalarIntConstantExpr")
            .Case("ScalarIntExpr", "scalarIntExpr")
            .Case("ScalarExpr", "scalarExpr")
            .Case("ScalarLogicalExpr", "scalarLogicalExpr")
            .Default(("Parser<" + Clause.getFlangClass() + ">{}")
                         .toStringRef(Scratch));
    OS << Parser;
    if (!Clause.getPrefix().empty() && Clause.isPrefixOptional())
      OS << " || " << Parser;
    if (Clause.isValueList()) // close nonemptyList(.
      OS << ")";
    OS << ")"; // close parenthesized(.

    if (Clause.isValueOptional()) // close maybe(.
      OS << ")";
    OS << "))";
    if (Index != LastClauseIndex)
      OS << " ||";
    OS << "\n";
    ++Index;
  }
  OS << ")\n";
}

// Generate the implementation section for the enumeration in the directive
// language
static void emitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
                                    raw_ostream &OS) {
  generateDirectiveClauseSets(DirLang, OS);

  generateDirectiveClauseMap(DirLang, OS);

  generateFlangClauseParserClass(DirLang, OS);

  generateFlangClauseParserClassList(DirLang, OS);

  generateFlangClauseDump(DirLang, OS);

  generateFlangClauseUnparse(DirLang, OS);

  generateFlangClauseCheckPrototypes(DirLang, OS);

  generateFlangClauseParserKindMap(DirLang, OS);

  generateFlangClausesParser(DirLang, OS);
}

static void generateClauseClassMacro(const DirectiveLanguage &DirLang,
                                     raw_ostream &OS) {
  // Generate macros style information for legacy code in clang
  IfDefScope Scope("GEN_CLANG_CLAUSE_CLASS", OS);

  OS << "\n";

  OS << "#ifndef CLAUSE\n";
  OS << "#define CLAUSE(Enum, Str, Implicit)\n";
  OS << "#endif\n";
  OS << "#ifndef CLAUSE_CLASS\n";
  OS << "#define CLAUSE_CLASS(Enum, Str, Class)\n";
  OS << "#endif\n";
  OS << "#ifndef CLAUSE_NO_CLASS\n";
  OS << "#define CLAUSE_NO_CLASS(Enum, Str)\n";
  OS << "#endif\n";
  OS << "\n";
  OS << "#define __CLAUSE(Name, Class)                      \\\n";
  OS << "  CLAUSE(" << DirLang.getClausePrefix()
     << "##Name, #Name, /* Implicit */ false) \\\n";
  OS << "  CLAUSE_CLASS(" << DirLang.getClausePrefix()
     << "##Name, #Name, Class)\n";
  OS << "#define __CLAUSE_NO_CLASS(Name)                    \\\n";
  OS << "  CLAUSE(" << DirLang.getClausePrefix()
     << "##Name, #Name, /* Implicit */ false) \\\n";
  OS << "  CLAUSE_NO_CLASS(" << DirLang.getClausePrefix() << "##Name, #Name)\n";
  OS << "#define __IMPLICIT_CLAUSE_CLASS(Name, Str, Class)  \\\n";
  OS << "  CLAUSE(" << DirLang.getClausePrefix()
     << "##Name, Str, /* Implicit */ true)    \\\n";
  OS << "  CLAUSE_CLASS(" << DirLang.getClausePrefix()
     << "##Name, Str, Class)\n";
  OS << "#define __IMPLICIT_CLAUSE_NO_CLASS(Name, Str)      \\\n";
  OS << "  CLAUSE(" << DirLang.getClausePrefix()
     << "##Name, Str, /* Implicit */ true)    \\\n";
  OS << "  CLAUSE_NO_CLASS(" << DirLang.getClausePrefix() << "##Name, Str)\n";
  OS << "\n";

  for (const Clause C : DirLang.getClauses()) {
    if (C.getClangClass().empty()) { // NO_CLASS
      if (C.isImplicit()) {
        OS << "__IMPLICIT_CLAUSE_NO_CLASS(" << C.getFormattedName() << ", \""
           << C.getFormattedName() << "\")\n";
      } else {
        OS << "__CLAUSE_NO_CLASS(" << C.getFormattedName() << ")\n";
      }
    } else { // CLASS
      if (C.isImplicit()) {
        OS << "__IMPLICIT_CLAUSE_CLASS(" << C.getFormattedName() << ", \""
           << C.getFormattedName() << "\", " << C.getClangClass() << ")\n";
      } else {
        OS << "__CLAUSE(" << C.getFormattedName() << ", " << C.getClangClass()
           << ")\n";
      }
    }
  }

  OS << "\n";
  OS << "#undef __IMPLICIT_CLAUSE_NO_CLASS\n";
  OS << "#undef __IMPLICIT_CLAUSE_CLASS\n";
  OS << "#undef __CLAUSE_NO_CLASS\n";
  OS << "#undef __CLAUSE\n";
  OS << "#undef CLAUSE_NO_CLASS\n";
  OS << "#undef CLAUSE_CLASS\n";
  OS << "#undef CLAUSE\n";
}

// Generate the implemenation for the enumeration in the directive
// language. This code can be included in library.
void emitDirectivesBasicImpl(const DirectiveLanguage &DirLang,
                             raw_ostream &OS) {
  IfDefScope Scope("GEN_DIRECTIVES_IMPL", OS);

  OS << "\n#include \"llvm/Support/ErrorHandling.h\"\n";

  // getDirectiveKind(StringRef Str)
  generateGetKind(DirLang.getDirectives(), OS, "Directive", DirLang,
                  DirLang.getDirectivePrefix(), /*ImplicitAsUnknown=*/false);

  // getDirectiveName(Directive Kind)
  generateGetName(DirLang.getDirectives(), OS, "Directive", DirLang,
                  DirLang.getDirectivePrefix());

  // getClauseKind(StringRef Str)
  generateGetKind(DirLang.getClauses(), OS, "Clause", DirLang,
                  DirLang.getClausePrefix(),
                  /*ImplicitAsUnknown=*/true);

  // getClauseName(Clause Kind)
  generateGetName(DirLang.getClauses(), OS, "Clause", DirLang,
                  DirLang.getClausePrefix());

  // get<ClauseVal>Kind(StringRef Str)
  generateGetKindClauseVal(DirLang, OS);

  // isAllowedClauseForDirective(Directive D, Clause C, unsigned Version)
  generateIsAllowedClause(DirLang, OS);

  // getDirectiveAssociation(Directive D)
  generateGetDirectiveAssociation(DirLang, OS);

  // getDirectiveCategory(Directive D)
  generateGetDirectiveCategory(DirLang, OS);

  // Leaf table for getLeafConstructs, etc.
  emitLeafTable(DirLang, OS, "LeafConstructTable");
}

// Generate the implemenation section for the enumeration in the directive
// language.
static void emitDirectivesImpl(const RecordKeeper &Records, raw_ostream &OS) {
  const auto DirLang = DirectiveLanguage(Records);
  if (DirLang.HasValidityErrors())
    return;

  emitDirectivesFlangImpl(DirLang, OS);

  generateClauseClassMacro(DirLang, OS);

  emitDirectivesBasicImpl(DirLang, OS);
}

static TableGen::Emitter::Opt
    X("gen-directive-decl", emitDirectivesDecl,
      "Generate directive related declaration code (header file)");

static TableGen::Emitter::Opt
    Y("gen-directive-impl", emitDirectivesImpl,
      "Generate directive related implementation code");
