//===-- ClangAttrEmitter.cpp - Generate Clang attribute handling ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// These tablegen backends emit Clang attribute processing code
//
//===----------------------------------------------------------------------===//

#include "TableGenBackends.h"
#include "ASTTableGen.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

namespace {

class FlattenedSpelling {
  StringRef V, N, NS;
  bool K = false;
  const Record &OriginalSpelling;

public:
  FlattenedSpelling(StringRef Variety, StringRef Name, StringRef Namespace,
                    bool KnownToGCC, const Record &OriginalSpelling)
      : V(Variety), N(Name), NS(Namespace), K(KnownToGCC),
        OriginalSpelling(OriginalSpelling) {}
  explicit FlattenedSpelling(const Record &Spelling)
      : V(Spelling.getValueAsString("Variety")),
        N(Spelling.getValueAsString("Name")), OriginalSpelling(Spelling) {
    assert(V != "GCC" && V != "Clang" &&
           "Given a GCC spelling, which means this hasn't been flattened!");
    if (V == "CXX11" || V == "C23" || V == "Pragma")
      NS = Spelling.getValueAsString("Namespace");
  }

  StringRef variety() const { return V; }
  StringRef name() const { return N; }
  StringRef nameSpace() const { return NS; }
  bool knownToGCC() const { return K; }
  const Record &getSpellingRecord() const { return OriginalSpelling; }
};

struct FlattenedSpellingInfo {
  FlattenedSpellingInfo(StringRef Syntax, StringRef Scope,
                        const std::string &TargetTest, uint32_t ArgMask)
      : Syntax(Syntax), Scope(Scope), TargetTest(TargetTest), ArgMask(ArgMask) {
  }
  StringRef Syntax;
  StringRef Scope;
  std::string TargetTest;
  uint32_t ArgMask;
};
using FSIVecTy = std::vector<FlattenedSpellingInfo>;

} // end anonymous namespace

static bool GenerateTargetSpecificAttrChecks(const Record *R,
                                             std::vector<StringRef> &Arches,
                                             std::string &Test,
                                             std::string *FnName);
static bool isStringLiteralArgument(const Record *Arg);
static bool isVariadicStringLiteralArgument(const Record *Arg);

static std::vector<FlattenedSpelling>
GetFlattenedSpellings(const Record &Attr) {
  std::vector<FlattenedSpelling> Ret;

  for (const auto &Spelling : Attr.getValueAsListOfDefs("Spellings")) {
    StringRef Variety = Spelling->getValueAsString("Variety");
    StringRef Name = Spelling->getValueAsString("Name");
    if (Variety == "GCC") {
      Ret.emplace_back("GNU", Name, "", true, *Spelling);
      Ret.emplace_back("CXX11", Name, "gnu", true, *Spelling);
      if (Spelling->getValueAsBit("AllowInC"))
        Ret.emplace_back("C23", Name, "gnu", true, *Spelling);
    } else if (Variety == "Clang") {
      Ret.emplace_back("GNU", Name, "", false, *Spelling);
      Ret.emplace_back("CXX11", Name, "clang", false, *Spelling);
      if (Spelling->getValueAsBit("AllowInC"))
        Ret.emplace_back("C23", Name, "clang", false, *Spelling);
    } else if (Variety == "ClangGCC") {
      Ret.emplace_back("GNU", Name, "", false, *Spelling);
      Ret.emplace_back("CXX11", Name, "clang", false, *Spelling);
      Ret.emplace_back("CXX11", Name, "gnu", false, *Spelling);
      if (Spelling->getValueAsBit("AllowInC")) {
        Ret.emplace_back("C23", Name, "clang", false, *Spelling);
        Ret.emplace_back("C23", Name, "gnu", false, *Spelling);
      }
    } else {
      Ret.push_back(FlattenedSpelling(*Spelling));
    }
  }

  return Ret;
}

static std::string ReadPCHRecord(StringRef type) {
  return StringSwitch<std::string>(type)
      .EndsWith("Decl *", "Record.readDeclAs<" + type.drop_back().str() + ">()")
      .Case("TypeSourceInfo *", "Record.readTypeSourceInfo()")
      .Case("Expr *", "Record.readExpr()")
      .Case("IdentifierInfo *", "Record.readIdentifier()")
      .Case("StringRef", "Record.readString()")
      .Case("ParamIdx", "ParamIdx::deserialize(Record.readInt())")
      .Case("OMPTraitInfo *", "Record.readOMPTraitInfo()")
      .Default("Record.readInt()");
}

// Get a type that is suitable for storing an object of the specified type.
static StringRef getStorageType(StringRef type) {
  return StringSwitch<StringRef>(type)
    .Case("StringRef", "std::string")
    .Default(type);
}

// Assumes that the way to get the value is SA->getname()
static std::string WritePCHRecord(StringRef type, StringRef name) {
  return "Record." +
         StringSwitch<std::string>(type)
             .EndsWith("Decl *", "AddDeclRef(" + name.str() + ");\n")
             .Case("TypeSourceInfo *",
                   "AddTypeSourceInfo(" + name.str() + ");\n")
             .Case("Expr *", "AddStmt(" + name.str() + ");\n")
             .Case("IdentifierInfo *",
                   "AddIdentifierRef(" + name.str() + ");\n")
             .Case("StringRef", "AddString(" + name.str() + ");\n")
             .Case("ParamIdx", "push_back(" + name.str() + ".serialize());\n")
             .Case("OMPTraitInfo *", "writeOMPTraitInfo(" + name.str() + ");\n")
             .Default("push_back(" + name.str() + ");\n");
}

// Normalize attribute name by removing leading and trailing
// underscores. For example, __foo, foo__, __foo__ would
// become foo.
static StringRef NormalizeAttrName(StringRef AttrName) {
  AttrName.consume_front("__");
  AttrName.consume_back("__");
  return AttrName;
}

// Normalize the name by removing any and all leading and trailing underscores.
// This is different from NormalizeAttrName in that it also handles names like
// _pascal and __pascal.
static StringRef NormalizeNameForSpellingComparison(StringRef Name) {
  return Name.trim("_");
}

// Normalize the spelling of a GNU attribute (i.e. "x" in "__attribute__((x))"),
// removing "__" if it appears at the beginning and end of the attribute's name.
static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
  if (AttrSpelling.starts_with("__") && AttrSpelling.ends_with("__")) {
    AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
  }

  return AttrSpelling;
}

typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;

static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
                                       ParsedAttrMap *Dupes = nullptr,
                                       bool SemaOnly = true) {
  std::set<std::string> Seen;
  ParsedAttrMap R;
  for (const Record *Attr : Records.getAllDerivedDefinitions("Attr")) {
    if (!SemaOnly || Attr->getValueAsBit("SemaHandler")) {
      std::string AN;
      if (Attr->isSubClassOf("TargetSpecificAttr") &&
          !Attr->isValueUnset("ParseKind")) {
        AN = Attr->getValueAsString("ParseKind").str();

        // If this attribute has already been handled, it does not need to be
        // handled again.
        if (!Seen.insert(AN).second) {
          if (Dupes)
            Dupes->push_back(std::make_pair(AN, Attr));
          continue;
        }
      } else
        AN = NormalizeAttrName(Attr->getName()).str();

      R.push_back(std::make_pair(AN, Attr));
    }
  }
  return R;
}

namespace {

  class Argument {
    std::string lowerName, upperName;
    StringRef attrName;
    bool isOpt;
    bool Fake;

  public:
    Argument(StringRef Arg, StringRef Attr)
        : lowerName(Arg.str()), upperName(lowerName), attrName(Attr),
          isOpt(false), Fake(false) {
      if (!lowerName.empty()) {
        lowerName[0] = std::tolower(lowerName[0]);
        upperName[0] = std::toupper(upperName[0]);
      }
      // Work around MinGW's macro definition of 'interface' to 'struct'. We
      // have an attribute argument called 'Interface', so only the lower case
      // name conflicts with the macro definition.
      if (lowerName == "interface")
        lowerName = "interface_";
    }
    Argument(const Record &Arg, StringRef Attr)
        : Argument(Arg.getValueAsString("Name"), Attr) {}
    virtual ~Argument() = default;

    StringRef getLowerName() const { return lowerName; }
    StringRef getUpperName() const { return upperName; }
    StringRef getAttrName() const { return attrName; }

    bool isOptional() const { return isOpt; }
    void setOptional(bool set) { isOpt = set; }

    bool isFake() const { return Fake; }
    void setFake(bool fake) { Fake = fake; }

    // These functions print the argument contents formatted in different ways.
    virtual void writeAccessors(raw_ostream &OS) const = 0;
    virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
    virtual void writeASTVisitorTraversal(raw_ostream &OS) const {}
    virtual void writeCloneArgs(raw_ostream &OS) const = 0;
    virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
    virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
    virtual void writeCtorBody(raw_ostream &OS) const {}
    virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
    virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0;
    virtual void writeCtorParameters(raw_ostream &OS) const = 0;
    virtual void writeDeclarations(raw_ostream &OS) const = 0;
    virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
    virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
    virtual void writePCHWrite(raw_ostream &OS) const = 0;
    virtual std::string getIsOmitted() const { return "false"; }
    virtual void writeValue(raw_ostream &OS) const = 0;
    virtual void writeDump(raw_ostream &OS) const = 0;
    virtual void writeDumpChildren(raw_ostream &OS) const {}
    virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }

    virtual bool isEnumArg() const { return false; }
    virtual bool isVariadicEnumArg() const { return false; }
    virtual bool isVariadic() const { return false; }

    virtual void writeImplicitCtorArgs(raw_ostream &OS) const {
      OS << getUpperName();
    }
  };

  class SimpleArgument : public Argument {
    std::string type;

  public:
    SimpleArgument(const Record &Arg, StringRef Attr, std::string T)
        : Argument(Arg, Attr), type(std::move(T)) {}

    std::string getType() const { return type; }

    void writeAccessors(raw_ostream &OS) const override {
      OS << "  " << type << " get" << getUpperName() << "() const {\n";
      OS << "    return " << getLowerName() << ";\n";
      OS << "  }";
    }

    void writeCloneArgs(raw_ostream &OS) const override {
      OS << getLowerName();
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "A->get" << getUpperName() << "()";
    }

    void writeCtorInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "(" << getUpperName() << ")";
    }

    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "()";
    }

    void writeCtorParameters(raw_ostream &OS) const override {
      OS << type << " " << getUpperName();
    }

    void writeDeclarations(raw_ostream &OS) const override {
      OS << type << " " << getLowerName() << ";";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      std::string read = ReadPCHRecord(type);
      OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
    }

    void writePCHReadArgs(raw_ostream &OS) const override {
      OS << getLowerName();
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    "
         << WritePCHRecord(type, "SA->get" + getUpperName().str() + "()");
    }

    std::string getIsOmitted() const override {
      auto IsOneOf = [](StringRef subject, auto... list) {
        return ((subject == list) || ...);
      };

      if (IsOneOf(type, "IdentifierInfo *", "Expr *"))
        return "!get" + getUpperName().str() + "()";
      if (IsOneOf(type, "TypeSourceInfo *"))
        return "!get" + getUpperName().str() + "Loc()";
      if (IsOneOf(type, "ParamIdx"))
        return "!get" + getUpperName().str() + "().isValid()";

      assert(IsOneOf(type, "unsigned", "int", "bool", "FunctionDecl *",
                     "VarDecl *"));
      return "false";
    }

    void writeValue(raw_ostream &OS) const override {
      if (type == "FunctionDecl *")
        OS << "\" << get" << getUpperName()
           << "()->getNameInfo().getAsString() << \"";
      else if (type == "IdentifierInfo *")
        // Some non-optional (comma required) identifier arguments can be the
        // empty string but are then recorded as a nullptr.
        OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName()
           << "()->getName() : \"\") << \"";
      else if (type == "VarDecl *")
        OS << "\" << get" << getUpperName() << "()->getName() << \"";
      else if (type == "TypeSourceInfo *")
        OS << "\" << get" << getUpperName() << "().getAsString() << \"";
      else if (type == "ParamIdx")
        OS << "\" << get" << getUpperName() << "().getSourceIndex() << \"";
      else
        OS << "\" << get" << getUpperName() << "() << \"";
    }

    void writeDump(raw_ostream &OS) const override {
      if (StringRef(type).ends_with("Decl *")) {
        OS << "    OS << \" \";\n";
        OS << "    dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
      } else if (type == "IdentifierInfo *") {
        // Some non-optional (comma required) identifier arguments can be the
        // empty string but are then recorded as a nullptr.
        OS << "    if (SA->get" << getUpperName() << "())\n"
           << "      OS << \" \" << SA->get" << getUpperName()
           << "()->getName();\n";
      } else if (type == "TypeSourceInfo *") {
        if (isOptional())
          OS << "    if (SA->get" << getUpperName() << "Loc())";
        OS << "    OS << \" \" << SA->get" << getUpperName()
           << "().getAsString();\n";
      } else if (type == "bool") {
        OS << "    if (SA->get" << getUpperName() << "()) OS << \" "
           << getUpperName() << "\";\n";
      } else if (type == "int" || type == "unsigned") {
        OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
      } else if (type == "ParamIdx") {
        if (isOptional())
          OS << "    if (SA->get" << getUpperName() << "().isValid())\n  ";
        OS << "    OS << \" \" << SA->get" << getUpperName()
           << "().getSourceIndex();\n";
      } else if (type == "OMPTraitInfo *") {
        OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
      } else {
        llvm_unreachable("Unknown SimpleArgument type!");
      }
    }
  };

  class DefaultSimpleArgument : public SimpleArgument {
    int64_t Default;

  public:
    DefaultSimpleArgument(const Record &Arg, StringRef Attr,
                          std::string T, int64_t Default)
      : SimpleArgument(Arg, Attr, T), Default(Default) {}

    void writeAccessors(raw_ostream &OS) const override {
      SimpleArgument::writeAccessors(OS);

      OS << "\n\n  static const " << getType() << " Default" << getUpperName()
         << " = ";
      if (getType() == "bool")
        OS << (Default != 0 ? "true" : "false");
      else
        OS << Default;
      OS << ";";
    }
  };

  class StringArgument : public Argument {
  public:
    StringArgument(const Record &Arg, StringRef Attr)
      : Argument(Arg, Attr)
    {}

    void writeAccessors(raw_ostream &OS) const override {
      OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
      OS << "    return llvm::StringRef(" << getLowerName() << ", "
         << getLowerName() << "Length);\n";
      OS << "  }\n";
      OS << "  unsigned get" << getUpperName() << "Length() const {\n";
      OS << "    return " << getLowerName() << "Length;\n";
      OS << "  }\n";
      OS << "  void set" << getUpperName()
         << "(ASTContext &C, llvm::StringRef S) {\n";
      OS << "    " << getLowerName() << "Length = S.size();\n";
      OS << "    this->" << getLowerName() << " = new (C, 1) char ["
         << getLowerName() << "Length];\n";
      OS << "    if (!S.empty())\n";
      OS << "      std::memcpy(this->" << getLowerName() << ", S.data(), "
         << getLowerName() << "Length);\n";
      OS << "  }";
    }

    void writeCloneArgs(raw_ostream &OS) const override {
      OS << "get" << getUpperName() << "()";
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "A->get" << getUpperName() << "()";
    }

    void writeCtorBody(raw_ostream &OS) const override {
      OS << "    if (!" << getUpperName() << ".empty())\n";
      OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
         << ".data(), " << getLowerName() << "Length);\n";
    }

    void writeCtorInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
         << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
         << "Length])";
    }

    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "Length(0)," << getLowerName() << "(nullptr)";
    }

    void writeCtorParameters(raw_ostream &OS) const override {
      OS << "llvm::StringRef " << getUpperName();
    }

    void writeDeclarations(raw_ostream &OS) const override {
      OS << "unsigned " << getLowerName() << "Length;\n";
      OS << "char *" << getLowerName() << ";";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    std::string " << getLowerName()
         << "= Record.readString();\n";
    }

    void writePCHReadArgs(raw_ostream &OS) const override {
      OS << getLowerName();
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    Record.AddString(SA->get" << getUpperName() << "());\n";
    }

    void writeValue(raw_ostream &OS) const override {
      OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    OS << \" \\\"\" << SA->get" << getUpperName()
         << "() << \"\\\"\";\n";
    }
  };

  class AlignedArgument : public Argument {
  public:
    AlignedArgument(const Record &Arg, StringRef Attr)
      : Argument(Arg, Attr)
    {}

    void writeAccessors(raw_ostream &OS) const override {
      OS << "  bool is" << getUpperName() << "Dependent() const;\n";
      OS << "  bool is" << getUpperName() << "ErrorDependent() const;\n";

      OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";

      OS << "  bool is" << getUpperName() << "Expr() const {\n";
      OS << "    return is" << getLowerName() << "Expr;\n";
      OS << "  }\n";

      OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
      OS << "    assert(is" << getLowerName() << "Expr);\n";
      OS << "    return " << getLowerName() << "Expr;\n";
      OS << "  }\n";

      OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
      OS << "    assert(!is" << getLowerName() << "Expr);\n";
      OS << "    return " << getLowerName() << "Type;\n";
      OS << "  }";

      OS << "  std::optional<unsigned> getCached" << getUpperName()
         << "Value() const {\n";
      OS << "    return " << getLowerName() << "Cache;\n";
      OS << "  }";

      OS << "  void setCached" << getUpperName()
         << "Value(unsigned AlignVal) {\n";
      OS << "    " << getLowerName() << "Cache = AlignVal;\n";
      OS << "  }";
    }

    void writeAccessorDefinitions(raw_ostream &OS) const override {
      OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
         << "Dependent() const {\n";
      OS << "  if (is" << getLowerName() << "Expr)\n";
      OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
         << "Expr->isValueDependent() || " << getLowerName()
         << "Expr->isTypeDependent());\n";
      OS << "  else\n";
      OS << "    return " << getLowerName()
         << "Type->getType()->isDependentType();\n";
      OS << "}\n";

      OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
         << "ErrorDependent() const {\n";
      OS << "  if (is" << getLowerName() << "Expr)\n";
      OS << "    return " << getLowerName() << "Expr && " << getLowerName()
         << "Expr->containsErrors();\n";
      OS << "  return " << getLowerName()
         << "Type->getType()->containsErrors();\n";
      OS << "}\n";
    }

    void writeASTVisitorTraversal(raw_ostream &OS) const override {
      StringRef Name = getUpperName();
      OS << "  if (A->is" << Name << "Expr()) {\n"
         << "    if (!getDerived().TraverseStmt(A->get" << Name << "Expr()))\n"
         << "      return false;\n"
         << "  } else if (auto *TSI = A->get" << Name << "Type()) {\n"
         << "    if (!getDerived().TraverseTypeLoc(TSI->getTypeLoc()))\n"
         << "      return false;\n"
         << "  }\n";
    }

    void writeCloneArgs(raw_ostream &OS) const override {
      OS << "is" << getLowerName() << "Expr, is" << getLowerName()
         << "Expr ? static_cast<void*>(" << getLowerName()
         << "Expr) : " << getLowerName()
         << "Type";
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      // FIXME: move the definition in Sema::InstantiateAttrs to here.
      // In the meantime, aligned attributes are cloned.
    }

    void writeCtorBody(raw_ostream &OS) const override {
      OS << "    if (is" << getLowerName() << "Expr)\n";
      OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
         << getUpperName() << ");\n";
      OS << "    else\n";
      OS << "       " << getLowerName()
         << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
         << ");\n";
    }

    void writeCtorInitializers(raw_ostream &OS) const override {
      OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
    }

    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
      OS << "is" << getLowerName() << "Expr(false)";
    }

    void writeCtorParameters(raw_ostream &OS) const override {
      OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
    }

    void writeImplicitCtorArgs(raw_ostream &OS) const override {
      OS << "Is" << getUpperName() << "Expr, " << getUpperName();
    }

    void writeDeclarations(raw_ostream &OS) const override {
      OS << "bool is" << getLowerName() << "Expr;\n";
      OS << "union {\n";
      OS << "Expr *" << getLowerName() << "Expr;\n";
      OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
      OS << "};\n";
      OS << "std::optional<unsigned> " << getLowerName() << "Cache;\n";
    }

    void writePCHReadArgs(raw_ostream &OS) const override {
      OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    bool is" << getLowerName() << "Expr = Record.readInt();\n";
      OS << "    void *" << getLowerName() << "Ptr;\n";
      OS << "    if (is" << getLowerName() << "Expr)\n";
      OS << "      " << getLowerName() << "Ptr = Record.readExpr();\n";
      OS << "    else\n";
      OS << "      " << getLowerName()
         << "Ptr = Record.readTypeSourceInfo();\n";
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
      OS << "    if (SA->is" << getUpperName() << "Expr())\n";
      OS << "      Record.AddStmt(SA->get" << getUpperName() << "Expr());\n";
      OS << "    else\n";
      OS << "      Record.AddTypeSourceInfo(SA->get" << getUpperName()
         << "Type());\n";
    }

    std::string getIsOmitted() const override {
      return "!((is" + getLowerName().str() + "Expr && " +
             getLowerName().str() + "Expr) || (!is" + getLowerName().str() +
             "Expr && " + getLowerName().str() + "Type))";
    }

    void writeValue(raw_ostream &OS) const override {
      OS << "\";\n";
      OS << "    if (is" << getLowerName() << "Expr && " << getLowerName()
         << "Expr)";
      OS << "      " << getLowerName()
         << "Expr->printPretty(OS, nullptr, Policy);\n";
      OS << "    if (!is" << getLowerName() << "Expr && " << getLowerName()
         << "Type)";
      OS << "      " << getLowerName()
         << "Type->getType().print(OS, Policy);\n";
      OS << "    OS << \"";
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    if (!SA->is" << getUpperName() << "Expr())\n";
      OS << "      dumpType(SA->get" << getUpperName()
         << "Type()->getType());\n";
    }

    void writeDumpChildren(raw_ostream &OS) const override {
      OS << "    if (SA->is" << getUpperName() << "Expr())\n";
      OS << "      Visit(SA->get" << getUpperName() << "Expr());\n";
    }

    void writeHasChildren(raw_ostream &OS) const override {
      OS << "SA->is" << getUpperName() << "Expr()";
    }
  };

  class VariadicArgument : public Argument {
    std::string Type, ArgName, ArgSizeName, RangeName;

  protected:
    // Assumed to receive a parameter: raw_ostream OS.
    virtual void writeValueImpl(raw_ostream &OS) const {
      OS << "    OS << Val;\n";
    }
    // Assumed to receive a parameter: raw_ostream OS.
    virtual void writeDumpImpl(raw_ostream &OS) const {
      OS << "      OS << \" \" << Val;\n";
    }

  public:
    VariadicArgument(const Record &Arg, StringRef Attr, std::string T)
        : Argument(Arg, Attr), Type(std::move(T)),
          ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"),
          RangeName(getLowerName().str()) {}

    VariadicArgument(StringRef Arg, StringRef Attr, std::string T)
        : Argument(Arg, Attr), Type(std::move(T)),
          ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"),
          RangeName(getLowerName().str()) {}

    const std::string &getType() const { return Type; }
    const std::string &getArgName() const { return ArgName; }
    const std::string &getArgSizeName() const { return ArgSizeName; }
    bool isVariadic() const override { return true; }

    void writeAccessors(raw_ostream &OS) const override {
      std::string IteratorType = getLowerName().str() + "_iterator";
      std::string BeginFn = getLowerName().str() + "_begin()";
      std::string EndFn = getLowerName().str() + "_end()";

      OS << "  typedef " << Type << "* " << IteratorType << ";\n";
      OS << "  " << IteratorType << " " << BeginFn << " const {"
         << " return " << ArgName << "; }\n";
      OS << "  " << IteratorType << " " << EndFn << " const {"
         << " return " << ArgName << " + " << ArgSizeName << "; }\n";
      OS << "  unsigned " << getLowerName() << "_size() const {"
         << " return " << ArgSizeName << "; }\n";
      OS << "  llvm::iterator_range<" << IteratorType << "> " << RangeName
         << "() const { return llvm::make_range(" << BeginFn << ", " << EndFn
         << "); }\n";
    }

    void writeSetter(raw_ostream &OS) const {
      OS << "  void set" << getUpperName() << "(ASTContext &Ctx, ";
      writeCtorParameters(OS);
      OS << ") {\n";
      OS << "    " << ArgSizeName << " = " << getUpperName() << "Size;\n";
      OS << "    " << ArgName << " = new (Ctx, 16) " << getType() << "["
         << ArgSizeName << "];\n";
      OS << "  ";
      writeCtorBody(OS);
      OS << "  }\n";
    }

    void writeCloneArgs(raw_ostream &OS) const override {
      OS << ArgName << ", " << ArgSizeName;
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      // This isn't elegant, but we have to go through public methods...
      OS << "A->" << getLowerName() << "_begin(), "
         << "A->" << getLowerName() << "_size()";
    }

    void writeASTVisitorTraversal(raw_ostream &OS) const override {
      // FIXME: Traverse the elements.
    }

    void writeCtorBody(raw_ostream &OS) const override {
      OS << "  std::copy(" << getUpperName() << ", " << getUpperName() << " + "
         << ArgSizeName << ", " << ArgName << ");\n";
    }

    void writeCtorInitializers(raw_ostream &OS) const override {
      OS << ArgSizeName << "(" << getUpperName() << "Size), "
         << ArgName << "(new (Ctx, 16) " << getType() << "["
         << ArgSizeName << "])";
    }

    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
      OS << ArgSizeName << "(0), " << ArgName << "(nullptr)";
    }

    void writeCtorParameters(raw_ostream &OS) const override {
      OS << getType() << " *" << getUpperName() << ", unsigned "
         << getUpperName() << "Size";
    }

    void writeImplicitCtorArgs(raw_ostream &OS) const override {
      OS << getUpperName() << ", " << getUpperName() << "Size";
    }

    void writeDeclarations(raw_ostream &OS) const override {
      OS << "  unsigned " << ArgSizeName << ";\n";
      OS << "  " << getType() << " *" << ArgName << ";";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    unsigned " << getLowerName() << "Size = Record.readInt();\n";
      OS << "    SmallVector<" << getType() << ", 4> "
         << getLowerName() << ";\n";
      OS << "    " << getLowerName() << ".reserve(" << getLowerName()
         << "Size);\n";

      // If we can't store the values in the current type (if it's something
      // like StringRef), store them in a different type and convert the
      // container afterwards.
      std::string StorageType = getStorageType(getType()).str();
      std::string StorageName = getLowerName().str();
      if (StorageType != getType()) {
        StorageName += "Storage";
        OS << "    SmallVector<" << StorageType << ", 4> "
           << StorageName << ";\n";
        OS << "    " << StorageName << ".reserve(" << getLowerName()
           << "Size);\n";
      }

      OS << "    for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
      std::string read = ReadPCHRecord(Type);
      OS << "      " << StorageName << ".push_back(" << read << ");\n";

      if (StorageType != getType()) {
        OS << "    for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
        OS << "      " << getLowerName() << ".push_back("
           << StorageName << "[i]);\n";
      }
    }

    void writePCHReadArgs(raw_ostream &OS) const override {
      OS << getLowerName() << ".data(), " << getLowerName() << "Size";
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
      OS << "    for (auto &Val : SA->" << RangeName << "())\n";
      OS << "      " << WritePCHRecord(Type, "Val");
    }

    void writeValue(raw_ostream &OS) const override {
      OS << "\";\n";
      OS << "  for (const auto &Val : " << RangeName << "()) {\n"
         << "    DelimitAttributeArgument(OS, IsFirstArgument);\n";
      writeValueImpl(OS);
      OS << "  }\n";
      OS << "  OS << \"";
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    for (const auto &Val : SA->" << RangeName << "())\n";
      writeDumpImpl(OS);
    }
  };

  class VariadicOMPInteropInfoArgument : public VariadicArgument {
  public:
    VariadicOMPInteropInfoArgument(const Record &Arg, StringRef Attr)
        : VariadicArgument(Arg, Attr, "OMPInteropInfo") {}

    void writeDump(raw_ostream &OS) const override {
      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
         << getLowerName() << "_end(); I != E; ++I) {\n";
      OS << "      if (I->IsTarget && I->IsTargetSync)\n";
      OS << "        OS << \" Target_TargetSync\";\n";
      OS << "      else if (I->IsTarget)\n";
      OS << "        OS << \" Target\";\n";
      OS << "      else\n";
      OS << "        OS << \" TargetSync\";\n";
      OS << "    }\n";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    unsigned " << getLowerName() << "Size = Record.readInt();\n";
      OS << "    SmallVector<OMPInteropInfo, 4> " << getLowerName() << ";\n";
      OS << "    " << getLowerName() << ".reserve(" << getLowerName()
         << "Size);\n";
      OS << "    for (unsigned I = 0, E = " << getLowerName() << "Size; ";
      OS << "I != E; ++I) {\n";
      OS << "      bool IsTarget = Record.readBool();\n";
      OS << "      bool IsTargetSync = Record.readBool();\n";
      OS << "      " << getLowerName()
         << ".emplace_back(IsTarget, IsTargetSync);\n";
      OS << "    }\n";
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
         << getLowerName() << "_end(); I != E; ++I) {\n";
      OS << "      Record.writeBool(I->IsTarget);\n";
      OS << "      Record.writeBool(I->IsTargetSync);\n";
      OS << "    }\n";
    }
  };

  class VariadicParamIdxArgument : public VariadicArgument {
  public:
    VariadicParamIdxArgument(const Record &Arg, StringRef Attr)
        : VariadicArgument(Arg, Attr, "ParamIdx") {}

  public:
    void writeValueImpl(raw_ostream &OS) const override {
      OS << "    OS << Val.getSourceIndex();\n";
    }

    void writeDumpImpl(raw_ostream &OS) const override {
      OS << "      OS << \" \" << Val.getSourceIndex();\n";
    }
  };

  struct VariadicParamOrParamIdxArgument : public VariadicArgument {
    VariadicParamOrParamIdxArgument(const Record &Arg, StringRef Attr)
        : VariadicArgument(Arg, Attr, "int") {}
  };

  // Unique the enums, but maintain the original declaration ordering.
  std::vector<StringRef>
  uniqueEnumsInOrder(const std::vector<StringRef> &enums) {
    std::vector<StringRef> uniques;
    SmallDenseSet<StringRef, 8> unique_set;
    for (const auto &i : enums) {
      if (unique_set.insert(i).second)
        uniques.push_back(i);
    }
    return uniques;
  }

  class EnumArgument : public Argument {
    std::string fullType;
    StringRef shortType;
    std::vector<StringRef> values, enums, uniques;
    bool isExternal;
    bool isCovered;

  public:
    EnumArgument(const Record &Arg, StringRef Attr)
        : Argument(Arg, Attr), values(Arg.getValueAsListOfStrings("Values")),
          enums(Arg.getValueAsListOfStrings("Enums")),
          uniques(uniqueEnumsInOrder(enums)),
          isExternal(Arg.getValueAsBit("IsExternalType")),
          isCovered(Arg.getValueAsBit("IsCovered")) {
      StringRef Type = Arg.getValueAsString("Type");
      shortType = isExternal ? Type.rsplit("::").second : Type;
      // If shortType didn't contain :: at all rsplit will give us an empty
      // string.
      if (shortType.empty())
        shortType = Type;
      fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();

      // FIXME: Emit a proper error
      assert(!uniques.empty());
    }

    bool isEnumArg() const override { return true; }

    void writeAccessors(raw_ostream &OS) const override {
      OS << "  " << fullType << " get" << getUpperName() << "() const {\n";
      OS << "    return " << getLowerName() << ";\n";
      OS << "  }";
    }

    void writeCloneArgs(raw_ostream &OS) const override {
      OS << getLowerName();
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "A->get" << getUpperName() << "()";
    }
    void writeCtorInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "(" << getUpperName() << ")";
    }
    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "(" << fullType << "(0))";
    }
    void writeCtorParameters(raw_ostream &OS) const override {
      OS << fullType << " " << getUpperName();
    }
    void writeDeclarations(raw_ostream &OS) const override {
      if (!isExternal) {
        auto i = uniques.cbegin(), e = uniques.cend();
        // The last one needs to not have a comma.
        --e;

        OS << "public:\n";
        OS << "  enum " << shortType << " {\n";
        for (; i != e; ++i)
          OS << "    " << *i << ",\n";
        OS << "    " << *e << "\n";
        OS << "  };\n";
      }

      OS << "private:\n";
      OS << "  " << fullType << " " << getLowerName() << ";";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    " << fullType << " " << getLowerName() << "(static_cast<"
         << fullType << ">(Record.readInt()));\n";
    }

    void writePCHReadArgs(raw_ostream &OS) const override {
      OS << getLowerName();
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "Record.push_back(static_cast<uint64_t>(SA->get" << getUpperName()
         << "()));\n";
    }

    void writeValue(raw_ostream &OS) const override {
      // FIXME: this isn't 100% correct -- some enum arguments require printing
      // as a string literal, while others require printing as an identifier.
      // Tablegen currently does not distinguish between the two forms.
      OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << shortType
         << "ToStr(get" << getUpperName() << "()) << \"\\\"";
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    switch(SA->get" << getUpperName() << "()) {\n";
      for (const auto &I : uniques) {
        OS << "    case " << fullType << "::" << I << ":\n";
        OS << "      OS << \" " << I << "\";\n";
        OS << "      break;\n";
      }
      if (!isCovered) {
        OS << "    default:\n";
        OS << "      llvm_unreachable(\"Invalid attribute value\");\n";
      }
      OS << "    }\n";
    }

    void writeConversion(raw_ostream &OS, bool Header) const {
      if (Header) {
        OS << "  static bool ConvertStrTo" << shortType << "(StringRef Val, "
           << fullType << " &Out);\n";
        OS << "  static const char *Convert" << shortType << "ToStr("
           << fullType << " Val);\n";
        return;
      }

      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType
         << "(StringRef Val, " << fullType << " &Out) {\n";
      OS << "  std::optional<" << fullType << "> "
         << "R = llvm::StringSwitch<std::optional<" << fullType << ">>(Val)\n";
      for (size_t I = 0; I < enums.size(); ++I) {
        OS << "    .Case(\"" << values[I] << "\", ";
        OS << fullType << "::" << enums[I] << ")\n";
      }
      OS << "    .Default(std::optional<" << fullType << ">());\n";
      OS << "  if (R) {\n";
      OS << "    Out = *R;\n      return true;\n    }\n";
      OS << "  return false;\n";
      OS << "}\n\n";

      // Mapping from enumeration values back to enumeration strings isn't
      // trivial because some enumeration values have multiple named
      // enumerators, such as type_visibility(internal) and
      // type_visibility(hidden) both mapping to TypeVisibilityAttr::Hidden.
      OS << "const char *" << getAttrName() << "Attr::Convert" << shortType
         << "ToStr(" << fullType << " Val) {\n"
         << "  switch(Val) {\n";
      SmallDenseSet<StringRef, 8> Uniques;
      for (size_t I = 0; I < enums.size(); ++I) {
        if (Uniques.insert(enums[I]).second)
          OS << "  case " << fullType << "::" << enums[I] << ": return \""
             << values[I] << "\";\n";
      }
      if (!isCovered) {
        OS << "  default: llvm_unreachable(\"Invalid attribute value\");\n";
      }
      OS << "  }\n"
         << "  llvm_unreachable(\"No enumerator with that value\");\n"
         << "}\n";
    }
  };

  class VariadicEnumArgument: public VariadicArgument {
    std::string fullType;
    StringRef shortType;
    std::vector<StringRef> values, enums, uniques;
    bool isExternal;
    bool isCovered;

  protected:
    void writeValueImpl(raw_ostream &OS) const override {
      // FIXME: this isn't 100% correct -- some enum arguments require printing
      // as a string literal, while others require printing as an identifier.
      // Tablegen currently does not distinguish between the two forms.
      OS << "    OS << \"\\\"\" << " << getAttrName() << "Attr::Convert"
         << shortType << "ToStr(Val)"
         << "<< \"\\\"\";\n";
    }

  public:
    VariadicEnumArgument(const Record &Arg, StringRef Attr)
        : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type").str()),
          values(Arg.getValueAsListOfStrings("Values")),
          enums(Arg.getValueAsListOfStrings("Enums")),
          uniques(uniqueEnumsInOrder(enums)),
          isExternal(Arg.getValueAsBit("IsExternalType")),
          isCovered(Arg.getValueAsBit("IsCovered")) {
      StringRef Type = Arg.getValueAsString("Type");
      shortType = isExternal ? Type.rsplit("::").second : Type;
      // If shortType didn't contain :: at all rsplit will give us an empty
      // string.
      if (shortType.empty())
        shortType = Type;
      fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();

      // FIXME: Emit a proper error
      assert(!uniques.empty());
    }

    bool isVariadicEnumArg() const override { return true; }

    void writeDeclarations(raw_ostream &OS) const override {
      if (!isExternal) {
        auto i = uniques.cbegin(), e = uniques.cend();
        // The last one needs to not have a comma.
        --e;

        OS << "public:\n";
        OS << "  enum " << shortType << " {\n";
        for (; i != e; ++i)
          OS << "    " << *i << ",\n";
        OS << "    " << *e << "\n";
        OS << "  };\n";
      }
      OS << "private:\n";

      VariadicArgument::writeDeclarations(OS);
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
         << getLowerName() << "_end(); I != E; ++I) {\n";
      OS << "      switch(*I) {\n";
      for (const auto &UI : uniques) {
        OS << "    case " << fullType << "::" << UI << ":\n";
        OS << "      OS << \" " << UI << "\";\n";
        OS << "      break;\n";
      }
      if (!isCovered) {
        OS << "    default:\n";
        OS << "      llvm_unreachable(\"Invalid attribute value\");\n";
      }
      OS << "      }\n";
      OS << "    }\n";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    unsigned " << getLowerName() << "Size = Record.readInt();\n";
      OS << "    SmallVector<" << fullType << ", 4> " << getLowerName()
         << ";\n";
      OS << "    " << getLowerName() << ".reserve(" << getLowerName()
         << "Size);\n";
      OS << "    for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
      OS << "      " << getLowerName() << ".push_back("
         << "static_cast<" << fullType << ">(Record.readInt()));\n";
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
         << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
         << getLowerName() << "_end(); i != e; ++i)\n";
      OS << "      " << WritePCHRecord(fullType, "(*i)");
    }

    void writeConversion(raw_ostream &OS, bool Header) const {
      if (Header) {
        OS << "  static bool ConvertStrTo" << shortType << "(StringRef Val, "
           << fullType << " &Out);\n";
        OS << "  static const char *Convert" << shortType << "ToStr("
           << fullType << " Val);\n";
        return;
      }

      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType
         << "(StringRef Val, ";
      OS << fullType << " &Out) {\n";
      OS << "  std::optional<" << fullType
         << "> R = llvm::StringSwitch<std::optional<";
      OS << fullType << ">>(Val)\n";
      for (size_t I = 0; I < enums.size(); ++I) {
        OS << "    .Case(\"" << values[I] << "\", ";
        OS << fullType << "::" << enums[I] << ")\n";
      }
      OS << "    .Default(std::optional<" << fullType << ">());\n";
      OS << "  if (R) {\n";
      OS << "    Out = *R;\n      return true;\n    }\n";
      OS << "  return false;\n";
      OS << "}\n\n";

      OS << "const char *" << getAttrName() << "Attr::Convert" << shortType
         << "ToStr(" << fullType << " Val) {\n"
         << "  switch(Val) {\n";
      SmallDenseSet<StringRef, 8> Uniques;
      for (size_t I = 0; I < enums.size(); ++I) {
        if (Uniques.insert(enums[I]).second)
          OS << "  case " << fullType << "::" << enums[I] << ": return \""
             << values[I] << "\";\n";
      }
      if (!isCovered) {
        OS << "  default: llvm_unreachable(\"Invalid attribute value\");\n";
      }
      OS << "  }\n"
         << "  llvm_unreachable(\"No enumerator with that value\");\n"
         << "}\n";
    }
  };

  class VersionArgument : public Argument {
  public:
    VersionArgument(const Record &Arg, StringRef Attr)
      : Argument(Arg, Attr)
    {}

    void writeAccessors(raw_ostream &OS) const override {
      OS << "  VersionTuple get" << getUpperName() << "() const {\n";
      OS << "    return " << getLowerName() << ";\n";
      OS << "  }\n";
      OS << "  void set" << getUpperName()
         << "(ASTContext &C, VersionTuple V) {\n";
      OS << "    " << getLowerName() << " = V;\n";
      OS << "  }";
    }

    void writeCloneArgs(raw_ostream &OS) const override {
      OS << "get" << getUpperName() << "()";
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "A->get" << getUpperName() << "()";
    }

    void writeCtorInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "(" << getUpperName() << ")";
    }

    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
      OS << getLowerName() << "()";
    }

    void writeCtorParameters(raw_ostream &OS) const override {
      OS << "VersionTuple " << getUpperName();
    }

    void writeDeclarations(raw_ostream &OS) const override {
      OS << "VersionTuple " << getLowerName() << ";\n";
    }

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    VersionTuple " << getLowerName()
         << "= Record.readVersionTuple();\n";
    }

    void writePCHReadArgs(raw_ostream &OS) const override {
      OS << getLowerName();
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    Record.AddVersionTuple(SA->get" << getUpperName() << "());\n";
    }

    void writeValue(raw_ostream &OS) const override {
      OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
    }
  };

  class ExprArgument : public SimpleArgument {
  public:
    ExprArgument(const Record &Arg, StringRef Attr)
      : SimpleArgument(Arg, Attr, "Expr *")
    {}

    void writeASTVisitorTraversal(raw_ostream &OS) const override {
      OS << "  if (!"
         << "getDerived().TraverseStmt(A->get" << getUpperName() << "()))\n";
      OS << "    return false;\n";
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "tempInst" << getUpperName();
    }

    void writeTemplateInstantiation(raw_ostream &OS) const override {
      OS << "      " << getType() << " tempInst" << getUpperName() << ";\n";
      OS << "      {\n";
      OS << "        EnterExpressionEvaluationContext "
         << "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n";
      OS << "        ExprResult " << "Result = S.SubstExpr("
         << "A->get" << getUpperName() << "(), TemplateArgs);\n";
      OS << "        if (Result.isInvalid())\n";
      OS << "          return nullptr;\n";
      OS << "        tempInst" << getUpperName() << " = Result.get();\n";
      OS << "      }\n";
    }

    void writeValue(raw_ostream &OS) const override {
      OS << "\";\n";
      OS << "    get" << getUpperName()
         << "()->printPretty(OS, nullptr, Policy);\n";
      OS << "    OS << \"";
    }

    void writeDump(raw_ostream &OS) const override {}

    void writeDumpChildren(raw_ostream &OS) const override {
      OS << "    Visit(SA->get" << getUpperName() << "());\n";
    }

    void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
  };

  class VariadicExprArgument : public VariadicArgument {
  public:
    VariadicExprArgument(const Record &Arg, StringRef Attr)
      : VariadicArgument(Arg, Attr, "Expr *")
    {}

    VariadicExprArgument(StringRef ArgName, StringRef Attr)
        : VariadicArgument(ArgName, Attr, "Expr *") {}

    void writeASTVisitorTraversal(raw_ostream &OS) const override {
      OS << "  {\n";
      OS << "    " << getType() << " *I = A->" << getLowerName()
         << "_begin();\n";
      OS << "    " << getType() << " *E = A->" << getLowerName()
         << "_end();\n";
      OS << "    for (; I != E; ++I) {\n";
      OS << "      if (!getDerived().TraverseStmt(*I))\n";
      OS << "        return false;\n";
      OS << "    }\n";
      OS << "  }\n";
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "tempInst" << getUpperName() << ", "
         << "numTempInst" << getUpperName();
    }

    void writeTemplateInstantiation(raw_ostream &OS) const override {
      OS << "      size_t numTempInst" << getUpperName() << ";\n";
      OS << "      " << getType() << "*tempInst" << getUpperName() << ";\n";
      OS << "      {\n";
      OS << "        EnterExpressionEvaluationContext "
         << "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n";
      OS << "        ArrayRef<" << getType() << "> ArgsToInstantiate(A->"
         << getLowerName() << "_begin(), A->" << getLowerName() << "_end());\n";
      OS << "        SmallVector<" << getType() << ", 4> InstArgs;\n";
      OS << "        if (S.SubstExprs(ArgsToInstantiate, /*IsCall=*/false, "
            "TemplateArgs, InstArgs))\n";
      OS << "          return nullptr;\n";
      OS << "        numTempInst" << getUpperName() << " = InstArgs.size();\n";
      OS << "        tempInst" << getUpperName() << " = new (C, 16) "
         << getType() << "[numTempInst" << getUpperName() << "];\n";
      OS << "        std::copy(InstArgs.begin(), InstArgs.end(), tempInst"
         << getUpperName() << ");\n";
      OS << "      }\n";
    }

    void writeDump(raw_ostream &OS) const override {}

    void writeDumpChildren(raw_ostream &OS) const override {
      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
         << getLowerName() << "_end(); I != E; ++I)\n";
      OS << "      Visit(*I);\n";
    }

    void writeHasChildren(raw_ostream &OS) const override {
      OS << "SA->" << getLowerName() << "_begin() != "
         << "SA->" << getLowerName() << "_end()";
    }
  };

  class VariadicIdentifierArgument : public VariadicArgument {
  public:
    VariadicIdentifierArgument(const Record &Arg, StringRef Attr)
      : VariadicArgument(Arg, Attr, "IdentifierInfo *")
    {}
  };

  class VariadicStringArgument : public VariadicArgument {
  public:
    VariadicStringArgument(const Record &Arg, StringRef Attr)
      : VariadicArgument(Arg, Attr, "StringRef")
    {}

    void writeCtorBody(raw_ostream &OS) const override {
      OS << "  for (size_t I = 0, E = " << getArgSizeName() << "; I != E;\n"
            "       ++I) {\n"
            "    StringRef Ref = " << getUpperName() << "[I];\n"
            "    if (!Ref.empty()) {\n"
            "      char *Mem = new (Ctx, 1) char[Ref.size()];\n"
            "      std::memcpy(Mem, Ref.data(), Ref.size());\n"
            "      " << getArgName() << "[I] = StringRef(Mem, Ref.size());\n"
            "    }\n"
            "  }\n";
    }

    void writeValueImpl(raw_ostream &OS) const override {
      OS << "    OS << \"\\\"\" << Val << \"\\\"\";\n";
    }
  };

  class TypeArgument : public SimpleArgument {
  public:
    TypeArgument(const Record &Arg, StringRef Attr)
      : SimpleArgument(Arg, Attr, "TypeSourceInfo *")
    {}

    void writeAccessors(raw_ostream &OS) const override {
      OS << "  QualType get" << getUpperName() << "() const {\n";
      OS << "    return " << getLowerName() << "->getType();\n";
      OS << "  }";
      OS << "  " << getType() << " get" << getUpperName() << "Loc() const {\n";
      OS << "    return " << getLowerName() << ";\n";
      OS << "  }";
    }

    void writeASTVisitorTraversal(raw_ostream &OS) const override {
      OS << "  if (auto *TSI = A->get" << getUpperName() << "Loc())\n";
      OS << "    if (!getDerived().TraverseTypeLoc(TSI->getTypeLoc()))\n";
      OS << "      return false;\n";
    }

    void writeTemplateInstantiation(raw_ostream &OS) const override {
      OS << "      " << getType() << " tempInst" << getUpperName() << " =\n";
      OS << "        S.SubstType(A->get" << getUpperName() << "Loc(), "
         << "TemplateArgs, A->getLoc(), A->getAttrName());\n";
      OS << "      if (!tempInst" << getUpperName() << ")\n";
      OS << "        return nullptr;\n";
    }

    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "tempInst" << getUpperName();
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    "
         << WritePCHRecord(getType(),
                           "SA->get" + getUpperName().str() + "Loc()");
    }
  };

  class WrappedAttr : public SimpleArgument {
  public:
    WrappedAttr(const Record &Arg, StringRef Attr)
        : SimpleArgument(Arg, Attr, "Attr *") {}

    void writePCHReadDecls(raw_ostream &OS) const override {
      OS << "    Attr *" << getLowerName() << " = Record.readAttr();";
    }

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "    AddAttr(SA->get" << getUpperName() << "());";
    }

    void writeDump(raw_ostream &OS) const override {}

    void writeDumpChildren(raw_ostream &OS) const override {
      OS << "    Visit(SA->get" << getUpperName() << "());\n";
    }

    void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
  };

  } // end anonymous namespace

static std::unique_ptr<Argument>
createArgument(const Record &Arg, StringRef Attr,
               const Record *Search = nullptr) {
  if (!Search)
    Search = &Arg;

  std::unique_ptr<Argument> Ptr;
  StringRef ArgName = Search->getName();

  if (ArgName == "AlignedArgument")
    Ptr = std::make_unique<AlignedArgument>(Arg, Attr);
  else if (ArgName == "EnumArgument")
    Ptr = std::make_unique<EnumArgument>(Arg, Attr);
  else if (ArgName == "ExprArgument")
    Ptr = std::make_unique<ExprArgument>(Arg, Attr);
  else if (ArgName == "DeclArgument")
    Ptr = std::make_unique<SimpleArgument>(
        Arg, Attr, (Arg.getValueAsDef("Kind")->getName() + "Decl *").str());
  else if (ArgName == "IdentifierArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "IdentifierInfo *");
  else if (ArgName == "DefaultBoolArgument")
    Ptr = std::make_unique<DefaultSimpleArgument>(
        Arg, Attr, "bool", Arg.getValueAsBit("Default"));
  else if (ArgName == "BoolArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "bool");
  else if (ArgName == "DefaultIntArgument")
    Ptr = std::make_unique<DefaultSimpleArgument>(
        Arg, Attr, "int", Arg.getValueAsInt("Default"));
  else if (ArgName == "IntArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "int");
  else if (ArgName == "StringArgument")
    Ptr = std::make_unique<StringArgument>(Arg, Attr);
  else if (ArgName == "TypeArgument")
    Ptr = std::make_unique<TypeArgument>(Arg, Attr);
  else if (ArgName == "UnsignedArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "unsigned");
  else if (ArgName == "VariadicUnsignedArgument")
    Ptr = std::make_unique<VariadicArgument>(Arg, Attr, "unsigned");
  else if (ArgName == "VariadicStringArgument")
    Ptr = std::make_unique<VariadicStringArgument>(Arg, Attr);
  else if (ArgName == "VariadicEnumArgument")
    Ptr = std::make_unique<VariadicEnumArgument>(Arg, Attr);
  else if (ArgName == "VariadicExprArgument")
    Ptr = std::make_unique<VariadicExprArgument>(Arg, Attr);
  else if (ArgName == "VariadicParamIdxArgument")
    Ptr = std::make_unique<VariadicParamIdxArgument>(Arg, Attr);
  else if (ArgName == "VariadicParamOrParamIdxArgument")
    Ptr = std::make_unique<VariadicParamOrParamIdxArgument>(Arg, Attr);
  else if (ArgName == "ParamIdxArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx");
  else if (ArgName == "VariadicIdentifierArgument")
    Ptr = std::make_unique<VariadicIdentifierArgument>(Arg, Attr);
  else if (ArgName == "VersionArgument")
    Ptr = std::make_unique<VersionArgument>(Arg, Attr);
  else if (ArgName == "WrappedAttr")
    Ptr = std::make_unique<WrappedAttr>(Arg, Attr);
  else if (ArgName == "OMPTraitInfoArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "OMPTraitInfo *");
  else if (ArgName == "VariadicOMPInteropInfoArgument")
    Ptr = std::make_unique<VariadicOMPInteropInfoArgument>(Arg, Attr);

  if (!Ptr) {
    // Search in reverse order so that the most-derived type is handled first.
    std::vector<const Record *> SCs = Search->getSuperClasses();
    for (const Record *Base : reverse(SCs)) {
      if ((Ptr = createArgument(Arg, Attr, Base)))
        break;
    }
  }

  if (Ptr && Arg.getValueAsBit("Optional"))
    Ptr->setOptional(true);

  if (Ptr && Arg.getValueAsBit("Fake"))
    Ptr->setFake(true);

  return Ptr;
}

static void writeAvailabilityValue(raw_ostream &OS) {
  OS << "\" << getPlatform()->getName();\n"
     << "  if (getStrict()) OS << \", strict\";\n"
     << "  if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
     << "  if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
     << "  if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
     << "  if (getUnavailable()) OS << \", unavailable\";\n"
     << "  OS << \"";
}

static void writeDeprecatedAttrValue(raw_ostream &OS, StringRef Variety) {
  OS << "\\\"\" << getMessage() << \"\\\"\";\n";
  // Only GNU deprecated has an optional fixit argument at the second position.
  if (Variety == "GNU")
     OS << "    if (!getReplacement().empty()) OS << \", \\\"\""
           " << getReplacement() << \"\\\"\";\n";
  OS << "    OS << \"";
}

static void writeGetSpellingFunction(const Record &R, raw_ostream &OS) {
  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);

  OS << "const char *" << R.getName() << "Attr::getSpelling() const {\n";
  if (Spellings.empty()) {
    OS << "  return \"(No spelling)\";\n}\n\n";
    return;
  }

  OS << "  switch (getAttributeSpellingListIndex()) {\n"
        "  default:\n"
        "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
        "    return \"(No spelling)\";\n";

  for (const auto &[Idx, S] : enumerate(Spellings)) {
    // clang-format off
    OS << "  case " << Idx << ":\n"
          "    return \"" << S.name() << "\";\n";
    // clang-format on
  }
  // End of the switch statement.
  OS << "  }\n";
  // End of the getSpelling function.
  OS << "}\n\n";
}

static void
writePrettyPrintFunction(const Record &R,
                         const std::vector<std::unique_ptr<Argument>> &Args,
                         raw_ostream &OS) {
  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);

  OS << "void " << R.getName() << "Attr::printPretty("
    << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";

  if (Spellings.empty()) {
    OS << "}\n\n";
    return;
  }

  OS << "  bool IsFirstArgument = true; (void)IsFirstArgument;\n"
     << "  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;\n"
     << "  switch (getAttributeSpellingListIndex()) {\n"
     << "  default:\n"
     << "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
     << "    break;\n";

  for (const auto &[Idx, S] : enumerate(Spellings)) {
    SmallString<16> Prefix;
    SmallString<8> Suffix;
    // The actual spelling of the name and namespace (if applicable)
    // of an attribute without considering prefix and suffix.
    SmallString<64> Spelling;
    StringRef Name = S.name();
    StringRef Variety = S.variety();

    if (Variety == "GNU") {
      Prefix = "__attribute__((";
      Suffix = "))";
    } else if (Variety == "CXX11" || Variety == "C23") {
      Prefix = "[[";
      Suffix = "]]";
      StringRef Namespace = S.nameSpace();
      if (!Namespace.empty()) {
        Spelling += Namespace;
        Spelling += "::";
      }
    } else if (Variety == "Declspec") {
      Prefix = "__declspec(";
      Suffix = ")";
    } else if (Variety == "Microsoft") {
      Prefix = "[";
      Suffix = "]";
    } else if (Variety == "Keyword") {
      Prefix = "";
      Suffix = "";
    } else if (Variety == "Pragma") {
      Prefix = "#pragma ";
      Suffix = "\n";
      StringRef Namespace = S.nameSpace();
      if (!Namespace.empty()) {
        Spelling += Namespace;
        Spelling += " ";
      }
    } else if (Variety == "HLSLAnnotation") {
      Prefix = ":";
      Suffix = "";
    } else {
      llvm_unreachable("Unknown attribute syntax variety!");
    }

    Spelling += Name;

    OS << "  case " << Idx << " : {\n"
       << "    OS << \"" << Prefix << Spelling << "\";\n";

    if (Variety == "Pragma") {
      OS << "    printPrettyPragma(OS, Policy);\n";
      OS << "    OS << \"\\n\";";
      OS << "    break;\n";
      OS << "  }\n";
      continue;
    }

    if (Spelling == "availability") {
      OS << "    OS << \"(";
      writeAvailabilityValue(OS);
      OS << ")\";\n";
    } else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") {
      OS << "    OS << \"(";
      writeDeprecatedAttrValue(OS, Variety);
      OS << ")\";\n";
    } else {
      // To avoid printing parentheses around an empty argument list or
      // printing spurious commas at the end of an argument list, we need to
      // determine where the last provided non-fake argument is.
      bool FoundNonOptArg = false;
      for (const auto &arg : reverse(Args)) {
        if (arg->isFake())
          continue;
        if (FoundNonOptArg)
          continue;
        // FIXME: arg->getIsOmitted() == "false" means we haven't implemented
        // any way to detect whether the argument was omitted.
        if (!arg->isOptional() || arg->getIsOmitted() == "false") {
          FoundNonOptArg = true;
          continue;
        }
        OS << "    if (" << arg->getIsOmitted() << ")\n"
           << "      ++TrailingOmittedArgs;\n";
      }
      unsigned ArgIndex = 0;
      for (const auto &arg : Args) {
        if (arg->isFake())
          continue;
        std::string IsOmitted = arg->getIsOmitted();
        if (arg->isOptional() && IsOmitted != "false")
          OS << "    if (!(" << IsOmitted << ")) {\n";
        // Variadic arguments print their own leading comma.
        if (!arg->isVariadic())
          OS << "    DelimitAttributeArgument(OS, IsFirstArgument);\n";
        OS << "    OS << \"";
        arg->writeValue(OS);
        OS << "\";\n";
        if (arg->isOptional() && IsOmitted != "false")
          OS << "    }\n";
        ++ArgIndex;
      }
      if (ArgIndex != 0)
        OS << "    if (!IsFirstArgument)\n"
           << "      OS << \")\";\n";
    }
    OS << "    OS << \"" << Suffix << "\";\n"
       << "    break;\n"
       << "  }\n";
  }

  // End of the switch statement.
  OS << "}\n";
  // End of the print function.
  OS << "}\n\n";
}

/// Return the index of a spelling in a spelling list.
static unsigned getSpellingListIndex(ArrayRef<FlattenedSpelling> SpellingList,
                                     const FlattenedSpelling &Spelling) {
  assert(!SpellingList.empty() && "Spelling list is empty!");

  for (const auto &[Index, S] : enumerate(SpellingList)) {
    if (S.variety() == Spelling.variety() &&
        S.nameSpace() == Spelling.nameSpace() && S.name() == Spelling.name())
      return Index;
  }

  PrintFatalError("Unknown spelling: " + Spelling.name());
}

static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
  std::vector<const Record *> Accessors = R.getValueAsListOfDefs("Accessors");
  if (Accessors.empty())
    return;

  const std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R);
  assert(!SpellingList.empty() &&
         "Attribute with empty spelling list can't have accessors!");
  for (const auto *Accessor : Accessors) {
    const StringRef Name = Accessor->getValueAsString("Name");
    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Accessor);

    OS << "  bool " << Name
       << "() const { return getAttributeSpellingListIndex() == ";
    for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
      OS << getSpellingListIndex(SpellingList, Spellings[Index]);
      if (Index != Spellings.size() - 1)
        OS << " ||\n    getAttributeSpellingListIndex() == ";
      else
        OS << "; }\n";
    }
  }
}

static bool
SpellingNamesAreCommon(const std::vector<FlattenedSpelling>& Spellings) {
  assert(!Spellings.empty() && "An empty list of spellings was provided");
  StringRef FirstName =
      NormalizeNameForSpellingComparison(Spellings.front().name());
  for (const auto &Spelling : drop_begin(Spellings)) {
    StringRef Name = NormalizeNameForSpellingComparison(Spelling.name());
    if (Name != FirstName)
      return false;
  }
  return true;
}

typedef std::map<unsigned, std::string> SemanticSpellingMap;
static std::string
CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings,
                        SemanticSpellingMap &Map) {
  // The enumerants are automatically generated based on the variety,
  // namespace (if present) and name for each attribute spelling. However,
  // care is taken to avoid trampling on the reserved namespace due to
  // underscores.
  std::string Ret("  enum Spelling {\n");
  std::set<std::string> Uniques;
  unsigned Idx = 0;

  // If we have a need to have this many spellings we likely need to add an
  // extra bit to the SpellingIndex in AttributeCommonInfo, then increase the
  // value of SpellingNotCalculated there and here.
  assert(Spellings.size() < 15 &&
         "Too many spellings, would step on SpellingNotCalculated in "
         "AttributeCommonInfo");
  for (auto I = Spellings.begin(), E = Spellings.end(); I != E; ++I, ++Idx) {
    const FlattenedSpelling &S = *I;
    StringRef Variety = S.variety();
    StringRef Spelling = S.name();
    StringRef Namespace = S.nameSpace();
    std::string EnumName;

    EnumName += Variety;
    EnumName += "_";
    if (!Namespace.empty())
      EnumName += NormalizeNameForSpellingComparison(Namespace).str() + "_";
    EnumName += NormalizeNameForSpellingComparison(Spelling);

    // Even if the name is not unique, this spelling index corresponds to a
    // particular enumerant name that we've calculated.
    Map[Idx] = EnumName;

    // Since we have been stripping underscores to avoid trampling on the
    // reserved namespace, we may have inadvertently created duplicate
    // enumerant names. These duplicates are not considered part of the
    // semantic spelling, and can be elided.
    if (!Uniques.insert(EnumName).second)
      continue;

    if (I != Spellings.begin())
      Ret += ",\n";
    // Duplicate spellings are not considered part of the semantic spelling
    // enumeration, but the spelling index and semantic spelling values are
    // meant to be equivalent, so we must specify a concrete value for each
    // enumerator.
    Ret += "    " + EnumName + " = " + utostr(Idx);
  }
  Ret += ",\n  SpellingNotCalculated = 15\n";
  Ret += "\n  };\n\n";
  return Ret;
}

static void WriteSemanticSpellingSwitch(StringRef VarName,
                                        const SemanticSpellingMap &Map,
                                        raw_ostream &OS) {
  OS << "  switch (" << VarName << ") {\n    default: "
    << "llvm_unreachable(\"Unknown spelling list index\");\n";
  for (const auto &I : Map)
    OS << "    case " << I.first << ": return " << I.second << ";\n";
  OS << "  }\n";
}

// Note: these values need to match the values used by LateAttrParseKind in
// `Attr.td`
enum class LateAttrParseKind { Never = 0, Standard = 1, ExperimentalExt = 2 };

static LateAttrParseKind getLateAttrParseKind(const Record *Attr) {
  // This function basically does
  // `Attr->getValueAsDef("LateParsed")->getValueAsInt("Kind")` but does a bunch
  // of sanity checking to ensure that `LateAttrParseMode` in `Attr.td` is in
  // sync with the `LateAttrParseKind` enum in this source file.

  static constexpr StringRef LateParsedStr = "LateParsed";
  static constexpr StringRef LateAttrParseKindStr = "LateAttrParseKind";
  static constexpr StringRef KindFieldStr = "Kind";

  auto *LAPK = Attr->getValueAsDef(LateParsedStr);

  // Typecheck the `LateParsed` field.
  if (LAPK->getDirectSuperClasses().size() != 1)
    PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) +
                              "`should only have one super class");

  const Record *SuperClass = LAPK->getDirectSuperClasses()[0].first;
  if (SuperClass->getName() != LateAttrParseKindStr)
    PrintFatalError(
        Attr, "Field `" + Twine(LateParsedStr) + "`should only have type `" +
                  Twine(LateAttrParseKindStr) + "` but found type `" +
                  SuperClass->getName() + "`");

  // Get Kind and verify the enum name matches the name in `Attr.td`.
  unsigned Kind = LAPK->getValueAsInt(KindFieldStr);
  switch (LateAttrParseKind(Kind)) {
#define CASE(X)                                                                \
  case LateAttrParseKind::X:                                                   \
    if (LAPK->getName().compare("LateAttrParse" #X) != 0) {                    \
      PrintFatalError(                                                         \
          Attr,                                                                \
          "Field `" + Twine(LateParsedStr) + "` set to `" + LAPK->getName() +  \
              "` but this converts to `LateAttrParseKind::" + Twine(#X) +      \
              "`");                                                            \
    }                                                                          \
    return LateAttrParseKind::X;

    CASE(Never)
    CASE(Standard)
    CASE(ExperimentalExt)
#undef CASE
  }

  // The Kind value is completely invalid
  auto KindValueStr = utostr(Kind);
  PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) + "` set to `" +
                            LAPK->getName() + "` has unexpected `" +
                            Twine(KindFieldStr) + "` value of " + KindValueStr);
}

// Emits the LateParsed property for attributes.
static void emitClangAttrLateParsedListImpl(const RecordKeeper &Records,
                                            raw_ostream &OS,
                                            LateAttrParseKind LateParseMode) {
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    if (LateAttrParseKind LateParsed = getLateAttrParseKind(Attr);
        LateParsed != LateParseMode)
      continue;

    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);

    // FIXME: Handle non-GNU attributes
    for (const auto &I : Spellings) {
      if (I.variety() != "GNU")
        continue;
      OS << ".Case(\"" << I.name() << "\", 1)\n";
    }
  }
}

static void emitClangAttrLateParsedList(const RecordKeeper &Records,
                                        raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n";
  emitClangAttrLateParsedListImpl(Records, OS, LateAttrParseKind::Standard);
  OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
}

static void emitClangAttrLateParsedExperimentalList(const RecordKeeper &Records,
                                                    raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST)\n";
  emitClangAttrLateParsedListImpl(Records, OS,
                                  LateAttrParseKind::ExperimentalExt);
  OS << "#endif // CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST\n\n";
}

static bool hasGNUorCXX11Spelling(const Record &Attribute) {
  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
  for (const auto &I : Spellings) {
    if (I.variety() == "GNU" || I.variety() == "CXX11")
      return true;
  }
  return false;
}

namespace {

struct AttributeSubjectMatchRule {
  const Record *MetaSubject;
  const Record *Constraint;

  AttributeSubjectMatchRule(const Record *MetaSubject, const Record *Constraint)
      : MetaSubject(MetaSubject), Constraint(Constraint) {
    assert(MetaSubject && "Missing subject");
  }

  bool isSubRule() const { return Constraint != nullptr; }

  std::vector<const Record *> getSubjects() const {
    return (Constraint ? Constraint : MetaSubject)
        ->getValueAsListOfDefs("Subjects");
  }

  std::vector<const Record *> getLangOpts() const {
    if (Constraint) {
      // Lookup the options in the sub-rule first, in case the sub-rule
      // overrides the rules options.
      std::vector<const Record *> Opts =
          Constraint->getValueAsListOfDefs("LangOpts");
      if (!Opts.empty())
        return Opts;
    }
    return MetaSubject->getValueAsListOfDefs("LangOpts");
  }

  // Abstract rules are used only for sub-rules
  bool isAbstractRule() const { return getSubjects().empty(); }

  StringRef getName() const {
    return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name");
  }

  bool isNegatedSubRule() const {
    assert(isSubRule() && "Not a sub-rule");
    return Constraint->getValueAsBit("Negated");
  }

  std::string getSpelling() const {
    std::string Result = MetaSubject->getValueAsString("Name").str();
    if (isSubRule()) {
      Result += '(';
      if (isNegatedSubRule())
        Result += "unless(";
      Result += getName();
      if (isNegatedSubRule())
        Result += ')';
      Result += ')';
    }
    return Result;
  }

  std::string getEnumValueName() const {
    SmallString<128> Result;
    Result += "SubjectMatchRule_";
    Result += MetaSubject->getValueAsString("Name");
    if (isSubRule()) {
      Result += "_";
      if (isNegatedSubRule())
        Result += "not_";
      Result += Constraint->getValueAsString("Name");
    }
    if (isAbstractRule())
      Result += "_abstract";
    return std::string(Result);
  }

  std::string getEnumValue() const { return "attr::" + getEnumValueName(); }

  static const char *EnumName;
};

const char *AttributeSubjectMatchRule::EnumName = "attr::SubjectMatchRule";

struct PragmaClangAttributeSupport {
  std::vector<AttributeSubjectMatchRule> Rules;

  class RuleOrAggregateRuleSet {
    std::vector<AttributeSubjectMatchRule> Rules;
    bool IsRule;
    RuleOrAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules,
                           bool IsRule)
        : Rules(Rules), IsRule(IsRule) {}

  public:
    bool isRule() const { return IsRule; }

    const AttributeSubjectMatchRule &getRule() const {
      assert(IsRule && "not a rule!");
      return Rules[0];
    }

    ArrayRef<AttributeSubjectMatchRule> getAggregateRuleSet() const {
      return Rules;
    }

    static RuleOrAggregateRuleSet
    getRule(const AttributeSubjectMatchRule &Rule) {
      return RuleOrAggregateRuleSet(Rule, /*IsRule=*/true);
    }
    static RuleOrAggregateRuleSet
    getAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules) {
      return RuleOrAggregateRuleSet(Rules, /*IsRule=*/false);
    }
  };
  DenseMap<const Record *, RuleOrAggregateRuleSet> SubjectsToRules;

  PragmaClangAttributeSupport(const RecordKeeper &Records);

  bool isAttributedSupported(const Record &Attribute);

  void emitMatchRuleList(raw_ostream &OS);

  void generateStrictConformsTo(const Record &Attr, raw_ostream &OS);

  void generateParsingHelpers(raw_ostream &OS);
};

} // end anonymous namespace

static bool isSupportedPragmaClangAttributeSubject(const Record &Subject) {
  // FIXME: #pragma clang attribute does not currently support statement
  // attributes, so test whether the subject is one that appertains to a
  // declaration node. However, it may be reasonable for support for statement
  // attributes to be added.
  if (Subject.isSubClassOf("DeclNode") || Subject.isSubClassOf("DeclBase") ||
      Subject.getName() == "DeclBase")
    return true;

  if (Subject.isSubClassOf("SubsetSubject"))
    return isSupportedPragmaClangAttributeSubject(
        *Subject.getValueAsDef("Base"));

  return false;
}

static bool doesDeclDeriveFrom(const Record *D, const Record *Base) {
  const Record *CurrentBase = D->getValueAsOptionalDef(BaseFieldName);
  if (!CurrentBase)
    return false;
  if (CurrentBase == Base)
    return true;
  return doesDeclDeriveFrom(CurrentBase, Base);
}

PragmaClangAttributeSupport::PragmaClangAttributeSupport(
    const RecordKeeper &Records) {
  auto MapFromSubjectsToRules = [this](const Record *SubjectContainer,
                                       const Record *MetaSubject,
                                       const Record *Constraint) {
    Rules.emplace_back(MetaSubject, Constraint);
    for (const Record *Subject :
         SubjectContainer->getValueAsListOfDefs("Subjects")) {
      bool Inserted =
          SubjectsToRules
              .try_emplace(Subject, RuleOrAggregateRuleSet::getRule(
                                        AttributeSubjectMatchRule(MetaSubject,
                                                                  Constraint)))
              .second;
      if (!Inserted) {
        PrintFatalError("Attribute subject match rules should not represent"
                        "same attribute subjects.");
      }
    }
  };
  for (const auto *MetaSubject :
       Records.getAllDerivedDefinitions("AttrSubjectMatcherRule")) {
    MapFromSubjectsToRules(MetaSubject, MetaSubject, /*Constraints=*/nullptr);
    for (const Record *Constraint :
         MetaSubject->getValueAsListOfDefs("Constraints"))
      MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
  }

  ArrayRef<const Record *> DeclNodes =
      Records.getAllDerivedDefinitions(DeclNodeClassName);
  for (const auto *Aggregate :
       Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule")) {
    const Record *SubjectDecl = Aggregate->getValueAsDef("Subject");

    // Gather sub-classes of the aggregate subject that act as attribute
    // subject rules.
    std::vector<AttributeSubjectMatchRule> Rules;
    for (const auto *D : DeclNodes) {
      if (doesDeclDeriveFrom(D, SubjectDecl)) {
        auto It = SubjectsToRules.find(D);
        if (It == SubjectsToRules.end())
          continue;
        if (!It->second.isRule() || It->second.getRule().isSubRule())
          continue; // Assume that the rule will be included as well.
        Rules.push_back(It->second.getRule());
      }
    }

    bool Inserted =
        SubjectsToRules
            .try_emplace(SubjectDecl,
                         RuleOrAggregateRuleSet::getAggregateRuleSet(Rules))
            .second;
    if (!Inserted) {
      PrintFatalError("Attribute subject match rules should not represent"
                      "same attribute subjects.");
    }
  }
}

static PragmaClangAttributeSupport &
getPragmaAttributeSupport(const RecordKeeper &Records) {
  static PragmaClangAttributeSupport Instance(Records);
  return Instance;
}

void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) {
  OS << "#ifndef ATTR_MATCH_SUB_RULE\n";
  OS << "#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, "
        "IsNegated) "
     << "ATTR_MATCH_RULE(Value, Spelling, IsAbstract)\n";
  OS << "#endif\n";
  for (const auto &Rule : Rules) {
    OS << (Rule.isSubRule() ? "ATTR_MATCH_SUB_RULE" : "ATTR_MATCH_RULE") << '(';
    OS << Rule.getEnumValueName() << ", \"" << Rule.getSpelling() << "\", "
       << Rule.isAbstractRule();
    if (Rule.isSubRule())
      OS << ", "
         << AttributeSubjectMatchRule(Rule.MetaSubject, nullptr).getEnumValue()
         << ", " << Rule.isNegatedSubRule();
    OS << ")\n";
  }
  OS << "#undef ATTR_MATCH_SUB_RULE\n";
}

bool PragmaClangAttributeSupport::isAttributedSupported(
    const Record &Attribute) {
  // If the attribute explicitly specified whether to support #pragma clang
  // attribute, use that setting.
  bool Unset;
  bool SpecifiedResult =
    Attribute.getValueAsBitOrUnset("PragmaAttributeSupport", Unset);
  if (!Unset)
    return SpecifiedResult;

  // Opt-out rules:

  // An attribute requires delayed parsing (LateParsed is on).
  switch (getLateAttrParseKind(&Attribute)) {
  case LateAttrParseKind::Never:
    break;
  case LateAttrParseKind::Standard:
    return false;
  case LateAttrParseKind::ExperimentalExt:
    // This is only late parsed in certain parsing contexts when
    // `LangOpts.ExperimentalLateParseAttributes` is true. Information about the
    // parsing context and `LangOpts` is not available in this method so just
    // opt this attribute out.
    return false;
  }

  // An attribute has no GNU/CXX11 spelling
  if (!hasGNUorCXX11Spelling(Attribute))
    return false;
  // An attribute subject list has a subject that isn't covered by one of the
  // subject match rules or has no subjects at all.
  if (Attribute.isValueUnset("Subjects"))
    return false;
  const Record *SubjectObj = Attribute.getValueAsDef("Subjects");
  bool HasAtLeastOneValidSubject = false;
  for (const auto *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) {
    if (!isSupportedPragmaClangAttributeSubject(*Subject))
      continue;
    if (!SubjectsToRules.contains(Subject))
      return false;
    HasAtLeastOneValidSubject = true;
  }
  return HasAtLeastOneValidSubject;
}

static std::string GenerateTestExpression(ArrayRef<const Record *> LangOpts) {
  std::string Test;

  for (auto *E : LangOpts) {
    if (!Test.empty())
      Test += " || ";

    const StringRef Code = E->getValueAsString("CustomCode");
    if (!Code.empty()) {
      Test += "(";
      Test += Code;
      Test += ")";
      if (!E->getValueAsString("Name").empty()) {
        PrintWarning(
            E->getLoc(),
            "non-empty 'Name' field ignored because 'CustomCode' was supplied");
      }
    } else {
      Test += "LangOpts.";
      Test += E->getValueAsString("Name");
    }
  }

  if (Test.empty())
    return "true";

  return Test;
}

void
PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
                                                      raw_ostream &OS) {
  if (!isAttributedSupported(Attr) || Attr.isValueUnset("Subjects"))
    return;
  // Generate a function that constructs a set of matching rules that describe
  // to which declarations the attribute should apply to.
  OS << "void getPragmaAttributeMatchRules("
     << "llvm::SmallVectorImpl<std::pair<"
     << AttributeSubjectMatchRule::EnumName
     << ", bool>> &MatchRules, const LangOptions &LangOpts) const override {\n";
  const Record *SubjectObj = Attr.getValueAsDef("Subjects");
  for (const auto *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) {
    if (!isSupportedPragmaClangAttributeSubject(*Subject))
      continue;
    auto It = SubjectsToRules.find(Subject);
    assert(It != SubjectsToRules.end() &&
           "This attribute is unsupported by #pragma clang attribute");
    for (const auto &Rule : It->getSecond().getAggregateRuleSet()) {
      // The rule might be language specific, so only subtract it from the given
      // rules if the specific language options are specified.
      std::vector<const Record *> LangOpts = Rule.getLangOpts();
      OS << "  MatchRules.push_back(std::make_pair(" << Rule.getEnumValue()
         << ", /*IsSupported=*/" << GenerateTestExpression(LangOpts)
         << "));\n";
    }
  }
  OS << "}\n\n";
}

void PragmaClangAttributeSupport::generateParsingHelpers(raw_ostream &OS) {
  // Generate routines that check the names of sub-rules.
  OS << "std::optional<attr::SubjectMatchRule> "
        "defaultIsAttributeSubjectMatchSubRuleFor(StringRef, bool) {\n";
  OS << "  return std::nullopt;\n";
  OS << "}\n\n";

  MapVector<const Record *, std::vector<AttributeSubjectMatchRule>>
      SubMatchRules;
  for (const auto &Rule : Rules) {
    if (!Rule.isSubRule())
      continue;
    SubMatchRules[Rule.MetaSubject].push_back(Rule);
  }

  for (const auto &SubMatchRule : SubMatchRules) {
    OS << "std::optional<attr::SubjectMatchRule> "
          "isAttributeSubjectMatchSubRuleFor_"
       << SubMatchRule.first->getValueAsString("Name")
       << "(StringRef Name, bool IsUnless) {\n";
    OS << "  if (IsUnless)\n";
    OS << "    return "
          "llvm::StringSwitch<std::optional<attr::SubjectMatchRule>>(Name).\n";
    for (const auto &Rule : SubMatchRule.second) {
      if (Rule.isNegatedSubRule())
        OS << "    Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
           << ").\n";
    }
    OS << "    Default(std::nullopt);\n";
    OS << "  return "
          "llvm::StringSwitch<std::optional<attr::SubjectMatchRule>>(Name).\n";
    for (const auto &Rule : SubMatchRule.second) {
      if (!Rule.isNegatedSubRule())
        OS << "  Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
           << ").\n";
    }
    OS << "  Default(std::nullopt);\n";
    OS << "}\n\n";
  }

  // Generate the function that checks for the top-level rules.
  OS << "std::pair<std::optional<attr::SubjectMatchRule>, "
        "std::optional<attr::SubjectMatchRule> (*)(StringRef, "
        "bool)> isAttributeSubjectMatchRule(StringRef Name) {\n";
  OS << "  return "
        "llvm::StringSwitch<std::pair<std::optional<attr::SubjectMatchRule>, "
        "std::optional<attr::SubjectMatchRule> (*) (StringRef, "
        "bool)>>(Name).\n";
  for (const auto &Rule : Rules) {
    if (Rule.isSubRule())
      continue;
    std::string SubRuleFunction;
    if (SubMatchRules.count(Rule.MetaSubject))
      SubRuleFunction =
          ("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str();
    else
      SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor";
    OS << "  Case(\"" << Rule.getName() << "\", std::make_pair("
       << Rule.getEnumValue() << ", " << SubRuleFunction << ")).\n";
  }
  OS << "  Default(std::make_pair(std::nullopt, "
        "defaultIsAttributeSubjectMatchSubRuleFor));\n";
  OS << "}\n\n";

  // Generate the function that checks for the submatch rules.
  OS << "const char *validAttributeSubjectMatchSubRules("
     << AttributeSubjectMatchRule::EnumName << " Rule) {\n";
  OS << "  switch (Rule) {\n";
  for (const auto &SubMatchRule : SubMatchRules) {
    OS << "  case "
       << AttributeSubjectMatchRule(SubMatchRule.first, nullptr).getEnumValue()
       << ":\n";
    OS << "  return \"'";
    bool IsFirst = true;
    for (const auto &Rule : SubMatchRule.second) {
      if (!IsFirst)
        OS << ", '";
      IsFirst = false;
      if (Rule.isNegatedSubRule())
        OS << "unless(";
      OS << Rule.getName();
      if (Rule.isNegatedSubRule())
        OS << ')';
      OS << "'";
    }
    OS << "\";\n";
  }
  OS << "  default: return nullptr;\n";
  OS << "  }\n";
  OS << "}\n\n";
}

template <typename Fn> static void forEachSpelling(const Record &Attr, Fn &&F) {
  for (const FlattenedSpelling &S : GetFlattenedSpellings(Attr)) {
    F(S);
  }
}

static std::map<StringRef, std::vector<const Record *>> NameToAttrsMap;

/// Build a map from the attribute name to the Attrs that use that name. If more
/// than one Attr use a name, the arguments could be different so a more complex
/// check is needed in the generated switch.
static void generateNameToAttrsMap(const RecordKeeper &Records) {
  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    for (const FlattenedSpelling &S : GetFlattenedSpellings(*A)) {
      auto [It, Inserted] = NameToAttrsMap.try_emplace(S.name());
      if (Inserted || !is_contained(It->second, A))
        It->second.emplace_back(A);
    }
  }
}

/// Generate the info needed to produce the case values in case more than one
/// attribute has the same name. Store the info in a map that can be processed
/// after all attributes are seen.
static void generateFlattenedSpellingInfo(const Record &Attr,
                                          std::map<StringRef, FSIVecTy> &Map,
                                          uint32_t ArgMask = 0) {
  std::string TargetTest;
  if (Attr.isSubClassOf("TargetSpecificAttr") &&
      !Attr.isValueUnset("ParseKind")) {
    const Record *T = Attr.getValueAsDef("Target");
    std::vector<StringRef> Arches = T->getValueAsListOfStrings("Arches");
    (void)GenerateTargetSpecificAttrChecks(T, Arches, TargetTest, nullptr);
  }

  forEachSpelling(Attr, [&](const FlattenedSpelling &S) {
    Map[S.name()].emplace_back(S.variety(), S.nameSpace(), TargetTest, ArgMask);
  });
}

static bool nameAppliesToOneAttribute(StringRef Name) {
  auto It = NameToAttrsMap.find(Name);
  assert(It != NameToAttrsMap.end());
  return It->second.size() == 1;
}

static bool emitIfSimpleValue(StringRef Name, uint32_t ArgMask,
                              raw_ostream &OS) {
  if (nameAppliesToOneAttribute(Name)) {
    OS << ".Case(\"" << Name << "\", ";
    if (ArgMask != 0)
      OS << ArgMask << ")\n";
    else
      OS << "true)\n";
    return true;
  }
  return false;
}

static void emitSingleCondition(const FlattenedSpellingInfo &FSI,
                                raw_ostream &OS) {
  OS << "(Syntax==AttributeCommonInfo::AS_" << FSI.Syntax << " && ";
  if (!FSI.Scope.empty())
    OS << "ScopeName && ScopeName->getName()==\"" << FSI.Scope << "\"";
  else
    OS << "!ScopeName";
  if (!FSI.TargetTest.empty())
    OS << " && " << FSI.TargetTest;
  OS << ")";
}

static void emitStringSwitchCases(std::map<StringRef, FSIVecTy> &Map,
                                  raw_ostream &OS) {
  for (const auto &[Name, Vec] : Map) {
    if (emitIfSimpleValue(Name, Vec[0].ArgMask, OS))
      continue;

    // Not simple, build expressions for each case.
    OS << ".Case(\"" << Name << "\", ";
    for (unsigned I = 0, E = Vec.size(); I < E; ++I) {
      emitSingleCondition(Vec[I], OS);
      uint32_t ArgMask = Vec[I].ArgMask;
      if (E == 1 && ArgMask == 0)
        continue;

      // More than one or it's the Mask form. Create a conditional expression.
      uint32_t SuccessValue = ArgMask != 0 ? ArgMask : 1;
      OS << " ? " << SuccessValue << " : ";
      if (I == E - 1)
        OS << 0;
    }
    OS << ")\n";
  }
}

static bool isTypeArgument(const Record *Arg) {
  return !Arg->getDirectSuperClasses().empty() &&
         Arg->getDirectSuperClasses().back().first->getName() == "TypeArgument";
}

/// Emits the first-argument-is-type property for attributes.
static void emitClangAttrTypeArgList(const RecordKeeper &Records,
                                     raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    // Determine whether the first argument is a type.
    std::vector<const Record *> Args = Attr->getValueAsListOfDefs("Args");
    if (Args.empty())
      continue;

    if (!isTypeArgument(Args[0]))
      continue;
    generateFlattenedSpellingInfo(*Attr, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
}

/// Emits the parse-arguments-in-unevaluated-context property for
/// attributes.
static void emitClangAttrArgContextList(const RecordKeeper &Records,
                                        raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n";
  std::map<StringRef, FSIVecTy> FSIMap;
  ParsedAttrMap Attrs = getParsedAttrList(Records);
  for (const auto &I : Attrs) {
    const Record &Attr = *I.second;

    if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
      continue;
    generateFlattenedSpellingInfo(Attr, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
}

static bool isIdentifierArgument(const Record *Arg) {
  return !Arg->getDirectSuperClasses().empty() &&
         StringSwitch<bool>(
             Arg->getDirectSuperClasses().back().first->getName())
             .Case("IdentifierArgument", true)
             .Case("EnumArgument", true)
             .Case("VariadicEnumArgument", true)
             .Default(false);
}

static bool isVariadicIdentifierArgument(const Record *Arg) {
  return !Arg->getDirectSuperClasses().empty() &&
         StringSwitch<bool>(
             Arg->getDirectSuperClasses().back().first->getName())
             .Case("VariadicIdentifierArgument", true)
             .Case("VariadicParamOrParamIdxArgument", true)
             .Default(false);
}

static bool isVariadicExprArgument(const Record *Arg) {
  return !Arg->getDirectSuperClasses().empty() &&
         StringSwitch<bool>(
             Arg->getDirectSuperClasses().back().first->getName())
             .Case("VariadicExprArgument", true)
             .Default(false);
}

static bool isStringLiteralArgument(const Record *Arg) {
  if (Arg->getDirectSuperClasses().empty())
    return false;
  StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName();
  if (ArgKind == "EnumArgument")
    return Arg->getValueAsBit("IsString");
  return ArgKind == "StringArgument";
}

static bool isVariadicStringLiteralArgument(const Record *Arg) {
  if (Arg->getDirectSuperClasses().empty())
    return false;
  StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName();
  if (ArgKind == "VariadicEnumArgument")
    return Arg->getValueAsBit("IsString");
  return ArgKind == "VariadicStringArgument";
}

static void emitClangAttrVariadicIdentifierArgList(const RecordKeeper &Records,
                                                   raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST)\n";
  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    // Determine whether the first argument is a variadic identifier.
    std::vector<const Record *> Args = A->getValueAsListOfDefs("Args");
    if (Args.empty() || !isVariadicIdentifierArgument(Args[0]))
      continue;
    generateFlattenedSpellingInfo(*A, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST\n\n";
}

// Emits the list of arguments that should be parsed as unevaluated string
// literals for each attribute.
static void
emitClangAttrUnevaluatedStringLiteralList(const RecordKeeper &Records,
                                          raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n";

  auto MakeMask = [](ArrayRef<const Record *> Args) {
    uint32_t Bits = 0;
    assert(Args.size() <= 32 && "unsupported number of arguments in attribute");
    for (uint32_t N = 0; N < Args.size(); ++N) {
      Bits |= (isStringLiteralArgument(Args[N]) << N);
      // If we have a variadic string argument, set all the remaining bits to 1
      if (isVariadicStringLiteralArgument(Args[N])) {
        Bits |= maskTrailingZeros<decltype(Bits)>(N);
        break;
      }
    }
    return Bits;
  };

  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    // Determine whether there are any string arguments.
    uint32_t ArgMask = MakeMask(Attr->getValueAsListOfDefs("Args"));
    if (!ArgMask)
      continue;
    generateFlattenedSpellingInfo(*Attr, FSIMap, ArgMask);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_STRING_LITERAL_ARG_LIST\n\n";
}

// Emits the first-argument-is-identifier property for attributes.
static void emitClangAttrIdentifierArgList(const RecordKeeper &Records,
                                           raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n";
  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    // Determine whether the first argument is an identifier.
    std::vector<const Record *> Args = Attr->getValueAsListOfDefs("Args");
    if (Args.empty() || !isIdentifierArgument(Args[0]))
      continue;
    generateFlattenedSpellingInfo(*Attr, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
}

// Emits the list for attributes having StrictEnumParameters.
static void emitClangAttrStrictIdentifierArgList(const RecordKeeper &Records,
                                                 raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST)\n";
  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    if (!Attr->getValueAsBit("StrictEnumParameters"))
      continue;
    // Check that there is really an identifier argument.
    std::vector<const Record *> Args = Attr->getValueAsListOfDefs("Args");
    if (none_of(Args, [&](const Record *R) { return isIdentifierArgument(R); }))
      continue;
    generateFlattenedSpellingInfo(*Attr, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST\n\n";
}

static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
  return !Arg->getDirectSuperClasses().empty() &&
         StringSwitch<bool>(
             Arg->getDirectSuperClasses().back().first->getName())
             .Case("VariadicParamOrParamIdxArgument", true)
             .Default(false);
}

static void emitClangAttrThisIsaIdentifierArgList(const RecordKeeper &Records,
                                                  raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST)\n";
  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    // Determine whether the first argument is a variadic identifier.
    std::vector<const Record *> Args = A->getValueAsListOfDefs("Args");
    if (Args.empty() || !keywordThisIsaIdentifierInArgument(Args[0]))
      continue;
    generateFlattenedSpellingInfo(*A, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST\n\n";
}

static void emitClangAttrAcceptsExprPack(const RecordKeeper &Records,
                                         raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_ACCEPTS_EXPR_PACK)\n";
  ParsedAttrMap Attrs = getParsedAttrList(Records);
  std::map<StringRef, FSIVecTy> FSIMap;
  for (const auto &I : Attrs) {
    const Record &Attr = *I.second;

    if (!Attr.getValueAsBit("AcceptsExprPack"))
      continue;
    generateFlattenedSpellingInfo(Attr, FSIMap);
  }
  emitStringSwitchCases(FSIMap, OS);
  OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
}

static bool isRegularKeywordAttribute(const FlattenedSpelling &S) {
  return (S.variety() == "Keyword" &&
          !S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
}

static void emitFormInitializer(raw_ostream &OS,
                                const FlattenedSpelling &Spelling,
                                StringRef SpellingIndex) {
  bool IsAlignas =
      (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
  OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
     << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
     << " /*IsAlignas*/, "
     << (isRegularKeywordAttribute(Spelling) ? "true" : "false")
     << " /*IsRegularKeywordAttribute*/}";
}

static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,
                           bool Header) {
  ParsedAttrMap AttrMap = getParsedAttrList(Records);

  // Helper to print the starting character of an attribute argument. If there
  // hasn't been an argument yet, it prints an opening parenthese; otherwise it
  // prints a comma.
  OS << "static inline void DelimitAttributeArgument("
     << "raw_ostream& OS, bool& IsFirst) {\n"
     << "  if (IsFirst) {\n"
     << "    IsFirst = false;\n"
     << "    OS << \"(\";\n"
     << "  } else\n"
     << "    OS << \", \";\n"
     << "}\n";

  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    const Record &R = *Attr;

    // FIXME: Currently, documentation is generated as-needed due to the fact
    // that there is no way to allow a generated project "reach into" the docs
    // directory (for instance, it may be an out-of-tree build). However, we want
    // to ensure that every attribute has a Documentation field, and produce an
    // error if it has been neglected. Otherwise, the on-demand generation which
    // happens server-side will fail. This code is ensuring that functionality,
    // even though this Emitter doesn't technically need the documentation.
    // When attribute documentation can be generated as part of the build
    // itself, this code can be removed.
    (void)R.getValueAsListOfDefs("Documentation");

    if (!R.getValueAsBit("ASTNode"))
      continue;

    std::vector<const Record *> Supers = R.getSuperClasses();
    assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
    std::string SuperName;
    bool Inheritable = false;
    bool HLSLSemantic = false;
    for (const Record *R : reverse(Supers)) {
      if (R->getName() != "TargetSpecificAttr" &&
          R->getName() != "DeclOrTypeAttr" && SuperName.empty())
        SuperName = R->getName().str();
      if (R->getName() == "InheritableAttr")
        Inheritable = true;
      if (R->getName() == "HLSLSemanticAttr")
        HLSLSemantic = true;
    }

    if (Header)
      OS << "class CLANG_ABI " << R.getName() << "Attr : public " << SuperName
         << " {\n";
    else
      OS << "\n// " << R.getName() << "Attr implementation\n\n";

    std::vector<const Record *> ArgRecords = R.getValueAsListOfDefs("Args");
    std::vector<std::unique_ptr<Argument>> Args;
    Args.reserve(ArgRecords.size());

    bool AttrAcceptsExprPack = Attr->getValueAsBit("AcceptsExprPack");
    if (AttrAcceptsExprPack) {
      for (size_t I = 0; I < ArgRecords.size(); ++I) {
        const Record *ArgR = ArgRecords[I];
        if (isIdentifierArgument(ArgR) || isVariadicIdentifierArgument(ArgR) ||
            isTypeArgument(ArgR))
          PrintFatalError(Attr->getLoc(),
                          "Attributes accepting packs cannot also "
                          "have identifier or type arguments.");
        // When trying to determine if value-dependent expressions can populate
        // the attribute without prior instantiation, the decision is made based
        // on the assumption that only the last argument is ever variadic.
        if (I < (ArgRecords.size() - 1) && isVariadicExprArgument(ArgR))
          PrintFatalError(Attr->getLoc(),
                          "Attributes accepting packs can only have the last "
                          "argument be variadic.");
      }
    }

    bool HasOptArg = false;
    bool HasFakeArg = false;
    for (const auto *ArgRecord : ArgRecords) {
      Args.emplace_back(createArgument(*ArgRecord, R.getName()));
      if (Header) {
        Args.back()->writeDeclarations(OS);
        OS << "\n\n";
      }

      // For these purposes, fake takes priority over optional.
      if (Args.back()->isFake()) {
        HasFakeArg = true;
      } else if (Args.back()->isOptional()) {
        HasOptArg = true;
      }
    }

    std::unique_ptr<VariadicExprArgument> DelayedArgs = nullptr;
    if (AttrAcceptsExprPack) {
      DelayedArgs =
          std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName());
      if (Header) {
        DelayedArgs->writeDeclarations(OS);
        OS << "\n\n";
      }
    }

    if (Header)
      OS << "public:\n";

    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);

    // If there are zero or one spellings, all spelling-related functionality
    // can be elided. If all of the spellings share the same name, the spelling
    // functionality can also be elided.
    bool ElideSpelling = (Spellings.size() <= 1) ||
                         SpellingNamesAreCommon(Spellings);

    // This maps spelling index values to semantic Spelling enumerants.
    SemanticSpellingMap SemanticToSyntacticMap;

    std::string SpellingEnum;
    if (Spellings.size() > 1)
      SpellingEnum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
    if (Header)
      OS << SpellingEnum;

    const auto &ParsedAttrSpellingItr =
        find_if(AttrMap, [R](const std::pair<std::string, const Record *> &P) {
          return &R == P.second;
        });

    // Emit CreateImplicit factory methods.
    auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly, bool emitFake) {
      if (Header)
        OS << "  static ";
      OS << R.getName() << "Attr *";
      if (!Header)
        OS << R.getName() << "Attr::";
      OS << "Create";
      if (Implicit)
        OS << "Implicit";
      if (DelayedArgsOnly)
        OS << "WithDelayedArgs";
      OS << "(";
      OS << "ASTContext &Ctx";
      if (!DelayedArgsOnly) {
        for (auto const &ai : Args) {
          if (ai->isFake() && !emitFake)
            continue;
          OS << ", ";
          ai->writeCtorParameters(OS);
        }
      } else {
        OS << ", ";
        DelayedArgs->writeCtorParameters(OS);
      }
      OS << ", const AttributeCommonInfo &CommonInfo";
      OS << ")";
      if (Header) {
        OS << ";\n";
        return;
      }

      OS << " {\n";
      OS << "  auto *A = new (Ctx) " << R.getName();
      OS << "Attr(Ctx, CommonInfo";

      if (!DelayedArgsOnly) {
        for (auto const &ai : Args) {
          if (ai->isFake() && !emitFake)
            continue;
          OS << ", ";
          ai->writeImplicitCtorArgs(OS);
        }
      }
      OS << ");\n";
      if (Implicit) {
        OS << "  A->setImplicit(true);\n";
      }
      if (Implicit || ElideSpelling) {
        OS << "  if (!A->isAttributeSpellingListCalculated() && "
              "!A->getAttrName())\n";
        OS << "    A->setAttributeSpellingListIndex(0);\n";
      }
      if (DelayedArgsOnly) {
        OS << "  A->setDelayedArgs(Ctx, ";
        DelayedArgs->writeImplicitCtorArgs(OS);
        OS << ");\n";
      }
      OS << "  return A;\n}\n\n";
    };

    auto emitCreateNoCI = [&](bool Implicit, bool DelayedArgsOnly,
                              bool emitFake) {
      if (Header)
        OS << "  static ";
      OS << R.getName() << "Attr *";
      if (!Header)
        OS << R.getName() << "Attr::";
      OS << "Create";
      if (Implicit)
        OS << "Implicit";
      if (DelayedArgsOnly)
        OS << "WithDelayedArgs";
      OS << "(";
      OS << "ASTContext &Ctx";
      if (!DelayedArgsOnly) {
        for (auto const &ai : Args) {
          if (ai->isFake() && !emitFake)
            continue;
          OS << ", ";
          ai->writeCtorParameters(OS);
        }
      } else {
        OS << ", ";
        DelayedArgs->writeCtorParameters(OS);
      }
      OS << ", SourceRange Range";
      if (Header)
        OS << " = {}";
      if (Spellings.size() > 1) {
        OS << ", Spelling S";
        if (Header)
          OS << " = " << SemanticToSyntacticMap[0];
      }
      OS << ")";
      if (Header) {
        OS << ";\n";
        return;
      }

      OS << " {\n";
      OS << "  AttributeCommonInfo I(Range, ";

      if (ParsedAttrSpellingItr != std::end(AttrMap))
        OS << "AT_" << ParsedAttrSpellingItr->first;
      else
        OS << "NoSemaHandlerAttribute";

      if (Spellings.size() == 0) {
        OS << ", AttributeCommonInfo::Form::Implicit()";
      } else if (Spellings.size() == 1) {
        OS << ", ";
        emitFormInitializer(OS, Spellings[0], "0");
      } else {
        OS << ", [&]() {\n";
        OS << "    switch (S) {\n";
        std::set<std::string> Uniques;
        unsigned Idx = 0;
        for (auto I = Spellings.begin(), E = Spellings.end(); I != E;
             ++I, ++Idx) {
          const FlattenedSpelling &S = *I;
          const auto &Name = SemanticToSyntacticMap[Idx];
          if (Uniques.insert(Name).second) {
            OS << "    case " << Name << ":\n";
            OS << "      return AttributeCommonInfo::Form";
            emitFormInitializer(OS, S, Name);
            OS << ";\n";
          }
        }
        OS << "    default:\n";
        OS << "      llvm_unreachable(\"Unknown attribute spelling!\");\n"
           << "      return AttributeCommonInfo::Form";
        emitFormInitializer(OS, Spellings[0], "0");
        OS << ";\n"
           << "    }\n"
           << "  }()";
      }

      OS << ");\n";
      OS << "  return Create";
      if (Implicit)
        OS << "Implicit";
      if (DelayedArgsOnly)
        OS << "WithDelayedArgs";
      OS << "(Ctx";
      if (!DelayedArgsOnly) {
        for (auto const &ai : Args) {
          if (ai->isFake() && !emitFake)
            continue;
          OS << ", ";
          ai->writeImplicitCtorArgs(OS);
        }
      } else {
        OS << ", ";
        DelayedArgs->writeImplicitCtorArgs(OS);
      }
      OS << ", I);\n";
      OS << "}\n\n";
    };

    auto emitCreates = [&](bool DelayedArgsOnly, bool emitFake) {
      emitCreate(true, DelayedArgsOnly, emitFake);
      emitCreate(false, DelayedArgsOnly, emitFake);
      emitCreateNoCI(true, DelayedArgsOnly, emitFake);
      emitCreateNoCI(false, DelayedArgsOnly, emitFake);
    };

    if (Header)
      OS << "  // Factory methods\n";

    // Emit a CreateImplicit that takes all the arguments.
    emitCreates(false, true);

    // Emit a CreateImplicit that takes all the non-fake arguments.
    if (HasFakeArg)
      emitCreates(false, false);

    // Emit a CreateWithDelayedArgs that takes only the dependent argument
    // expressions.
    if (DelayedArgs)
      emitCreates(true, false);

    // Emit constructors.
    auto emitCtor = [&](bool emitOpt, bool emitFake, bool emitNoArgs) {
      auto shouldEmitArg = [=](const std::unique_ptr<Argument> &arg) {
        if (emitNoArgs)
          return false;
        if (arg->isFake())
          return emitFake;
        if (arg->isOptional())
          return emitOpt;
        return true;
      };
      if (Header)
        OS << "  ";
      else
        OS << R.getName() << "Attr::";
      OS << R.getName()
         << "Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo";
      OS << '\n';
      for (auto const &ai : Args) {
        if (!shouldEmitArg(ai))
          continue;
        OS << "              , ";
        ai->writeCtorParameters(OS);
        OS << "\n";
      }

      OS << "             )";
      if (Header) {
        OS << ";\n";
        return;
      }
      OS << "\n  : " << SuperName << "(Ctx, CommonInfo, ";
      OS << "attr::" << R.getName() << ", ";

      // Handle different late parsing modes.
      OS << "/*IsLateParsed=*/";
      switch (getLateAttrParseKind(&R)) {
      case LateAttrParseKind::Never:
        OS << "false";
        break;
      case LateAttrParseKind::ExperimentalExt:
        // Currently no clients need to know the distinction between `Standard`
        // and `ExperimentalExt` so treat `ExperimentalExt` just like
        // `Standard` for now.
      case LateAttrParseKind::Standard:
        // Note: This is misleading. `IsLateParsed` doesn't mean the
        // attribute was actually late parsed. Instead it means the attribute in
        // `Attr.td` is marked as being late parsed. Maybe it should be called
        // `IsLateParseable`?
        OS << "true";
        break;
      }

      if (Inheritable) {
        OS << ", "
           << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
                                                              : "false");
      }
      if (HLSLSemantic)
        OS << ", " << (R.getValueAsBit("SemanticIndexable") ? "true" : "false");
      OS << ")\n";

      for (auto const &ai : Args) {
        OS << "              , ";
        if (!shouldEmitArg(ai)) {
          ai->writeCtorDefaultInitializers(OS);
        } else {
          ai->writeCtorInitializers(OS);
        }
        OS << "\n";
      }
      if (DelayedArgs) {
        OS << "              , ";
        DelayedArgs->writeCtorDefaultInitializers(OS);
        OS << "\n";
      }

      OS << "  {\n";

      // The generator puts the arguments for each attribute in the child class,
      // even if those are set in the inherited attribute class (in the TD
      // file). This means I cannot access those from the parent class, and have
      // to do this weirdness. Maybe the generator should be changed to
      // arguments are put in the class they are declared in inside the TD file?
      if (HLSLSemantic) {
        OS << "  if (SemanticExplicitIndex)\n";
        OS << "    setSemanticIndex(SemanticIndex);\n";
        OS << "  setTargetDecl(Target);\n";
      }

      for (auto const &ai : Args) {
        if (!shouldEmitArg(ai))
          continue;
        ai->writeCtorBody(OS);
      }
      OS << "}\n\n";
    };

    if (Header)
      OS << "\n  // Constructors\n";

    // Emit a constructor that includes all the arguments.
    // This is necessary for cloning.
    emitCtor(true, true, false);

    // Emit a constructor that takes all the non-fake arguments.
    if (HasFakeArg)
      emitCtor(true, false, false);

    // Emit a constructor that takes all the non-fake, non-optional arguments.
    if (HasOptArg)
      emitCtor(false, false, false);

    // Emit constructors that takes no arguments if none already exists.
    // This is used for delaying arguments.
    bool HasRequiredArgs =
        count_if(Args, [=](const std::unique_ptr<Argument> &arg) {
          return !arg->isFake() && !arg->isOptional();
        });
    if (DelayedArgs && HasRequiredArgs)
      emitCtor(false, false, true);

    if (Header) {
      OS << '\n';
      OS << "  " << R.getName() << "Attr *clone(ASTContext &C) const;\n";
      OS << "  void printPretty(raw_ostream &OS,\n"
         << "                   const PrintingPolicy &Policy) const;\n";
      OS << "  const char *getSpelling() const;\n";
    }

    if (!ElideSpelling) {
      assert(!SemanticToSyntacticMap.empty() && "Empty semantic mapping list");
      if (Header)
        OS << "  Spelling getSemanticSpelling() const;\n";
      else {
        OS << R.getName() << "Attr::Spelling " << R.getName()
           << "Attr::getSemanticSpelling() const {\n";
        WriteSemanticSpellingSwitch("getAttributeSpellingListIndex()",
                                    SemanticToSyntacticMap, OS);
        OS << "}\n";
      }
    }

    if (Header)
      writeAttrAccessorDefinition(R, OS);

    for (auto const &ai : Args) {
      if (Header) {
        ai->writeAccessors(OS);
      } else {
        ai->writeAccessorDefinitions(OS);
      }
      OS << "\n\n";

      // Don't write conversion routines for fake arguments.
      if (ai->isFake()) continue;

      if (ai->isEnumArg())
        static_cast<const EnumArgument *>(ai.get())->writeConversion(OS,
                                                                     Header);
      else if (ai->isVariadicEnumArg())
        static_cast<const VariadicEnumArgument *>(ai.get())->writeConversion(
            OS, Header);
    }

    if (Header) {
      if (DelayedArgs) {
        DelayedArgs->writeAccessors(OS);
        DelayedArgs->writeSetter(OS);
      }

      OS << R.getValueAsString("AdditionalMembers");
      OS << "\n\n";

      OS << "  static bool classof(const Attr *A) { return A->getKind() == "
         << "attr::" << R.getName() << "; }\n";

      OS << "};\n\n";
    } else {
      if (DelayedArgs)
        DelayedArgs->writeAccessorDefinitions(OS);

      OS << R.getName() << "Attr *" << R.getName()
         << "Attr::clone(ASTContext &C) const {\n";
      OS << "  auto *A = new (C) " << R.getName() << "Attr(C, *this";
      for (auto const &ai : Args) {
        OS << ", ";
        ai->writeCloneArgs(OS);
      }
      OS << ");\n";
      OS << "  A->Inherited = Inherited;\n";
      OS << "  A->IsPackExpansion = IsPackExpansion;\n";
      OS << "  A->setImplicit(Implicit);\n";
      if (DelayedArgs) {
        OS << "  A->setDelayedArgs(C, ";
        DelayedArgs->writeCloneArgs(OS);
        OS << ");\n";
      }
      OS << "  return A;\n}\n\n";

      writePrettyPrintFunction(R, Args, OS);
      writeGetSpellingFunction(R, OS);
    }
  }
}
// Emits the class definitions for attributes.
void clang::EmitClangAttrClass(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute classes' definitions", OS, Records);

  OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
  OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n";

  emitAttributes(Records, OS, true);

  OS << "#endif // LLVM_CLANG_ATTR_CLASSES_INC\n";
}

// Emits the class method definitions for attributes.
void clang::EmitClangAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute classes' member function definitions", OS,
                       Records);

  emitAttributes(Records, OS, false);

  // Instead of relying on virtual dispatch we just create a huge dispatch
  // switch. This is both smaller and faster than virtual functions.
  auto EmitFunc = [&](const char *Method) {
    OS << "  switch (getKind()) {\n";
    for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
      const Record &R = *Attr;
      if (!R.getValueAsBit("ASTNode"))
        continue;

      OS << "  case attr::" << R.getName() << ":\n";
      OS << "    return cast<" << R.getName() << "Attr>(this)->" << Method
         << ";\n";
    }
    OS << "  }\n";
    OS << "  llvm_unreachable(\"Unexpected attribute kind!\");\n";
    OS << "}\n\n";
  };

  OS << "const char *Attr::getSpelling() const {\n";
  EmitFunc("getSpelling()");

  OS << "Attr *Attr::clone(ASTContext &C) const {\n";
  EmitFunc("clone(C)");

  OS << "void Attr::printPretty(raw_ostream &OS, "
        "const PrintingPolicy &Policy) const {\n";
  EmitFunc("printPretty(OS, Policy)");
}

static void emitAttrList(raw_ostream &OS, StringRef Class,
                         ArrayRef<const Record *> AttrList) {
  for (auto Cur : AttrList) {
    OS << Class << "(" << Cur->getName() << ")\n";
  }
}

// Determines if an attribute has a Pragma spelling.
static bool AttrHasPragmaSpelling(const Record *R) {
  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
  return any_of(Spellings, [](const FlattenedSpelling &S) {
    return S.variety() == "Pragma";
  });
}

namespace {

  struct AttrClassDescriptor {
    const char * const MacroName;
    const char * const TableGenName;
  };

} // end anonymous namespace

static const AttrClassDescriptor AttrClassDescriptors[] = {
    {"ATTR", "Attr"},
    {"TYPE_ATTR", "TypeAttr"},
    {"STMT_ATTR", "StmtAttr"},
    {"DECL_OR_STMT_ATTR", "DeclOrStmtAttr"},
    {"INHERITABLE_ATTR", "InheritableAttr"},
    {"DECL_OR_TYPE_ATTR", "DeclOrTypeAttr"},
    {"INHERITABLE_PARAM_ATTR", "InheritableParamAttr"},
    {"INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr"},
    {"PARAMETER_ABI_ATTR", "ParameterABIAttr"},
    {"HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"},
    {"HLSL_SEMANTIC_ATTR", "HLSLSemanticAttr"}};

static void emitDefaultDefine(raw_ostream &OS, StringRef name,
                              const char *superName) {
  OS << "#ifndef " << name << "\n";
  OS << "#define " << name << "(NAME) ";
  if (superName) OS << superName << "(NAME)";
  OS << "\n#endif\n\n";
}

namespace {

  /// A class of attributes.
  struct AttrClass {
    const AttrClassDescriptor &Descriptor;
    const Record *TheRecord;
    AttrClass *SuperClass = nullptr;
    std::vector<AttrClass*> SubClasses;
    std::vector<const Record *> Attrs;

    AttrClass(const AttrClassDescriptor &Descriptor, const Record *R)
        : Descriptor(Descriptor), TheRecord(R) {}

    void emitDefaultDefines(raw_ostream &OS) const {
      // Default the macro unless this is a root class (i.e. Attr).
      if (SuperClass) {
        emitDefaultDefine(OS, Descriptor.MacroName,
                          SuperClass->Descriptor.MacroName);
      }
    }

    void emitUndefs(raw_ostream &OS) const {
      OS << "#undef " << Descriptor.MacroName << "\n";
    }

    void emitAttrList(raw_ostream &OS) const {
      for (auto SubClass : SubClasses) {
        SubClass->emitAttrList(OS);
      }

      ::emitAttrList(OS, Descriptor.MacroName, Attrs);
    }

    void classifyAttrOnRoot(const Record *Attr) {
      bool result = classifyAttr(Attr);
      assert(result && "failed to classify on root"); (void) result;
    }

    void emitAttrRange(raw_ostream &OS) const {
      OS << "ATTR_RANGE(" << Descriptor.TableGenName
         << ", " << getFirstAttr()->getName()
         << ", " << getLastAttr()->getName() << ")\n";
    }

  private:
    bool classifyAttr(const Record *Attr) {
      // Check all the subclasses.
      for (auto SubClass : SubClasses) {
        if (SubClass->classifyAttr(Attr))
          return true;
      }

      // It's not more specific than this class, but it might still belong here.
      if (Attr->isSubClassOf(TheRecord)) {
        Attrs.push_back(Attr);
        return true;
      }

      return false;
    }

    const Record *getFirstAttr() const {
      if (!SubClasses.empty())
        return SubClasses.front()->getFirstAttr();
      return Attrs.front();
    }

    const Record *getLastAttr() const {
      if (!Attrs.empty())
        return Attrs.back();
      return SubClasses.back()->getLastAttr();
    }
  };

  /// The entire hierarchy of attribute classes.
  class AttrClassHierarchy {
    std::vector<std::unique_ptr<AttrClass>> Classes;

  public:
    AttrClassHierarchy(const RecordKeeper &Records) {
      // Find records for all the classes.
      for (auto &Descriptor : AttrClassDescriptors) {
        const Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
        AttrClass *Class = new AttrClass(Descriptor, ClassRecord);
        Classes.emplace_back(Class);
      }

      // Link up the hierarchy.
      for (auto &Class : Classes) {
        if (AttrClass *SuperClass = findSuperClass(Class->TheRecord)) {
          Class->SuperClass = SuperClass;
          SuperClass->SubClasses.push_back(Class.get());
        }
      }

#ifndef NDEBUG
      for (auto i = Classes.begin(), e = Classes.end(); i != e; ++i) {
        assert((i == Classes.begin()) == ((*i)->SuperClass == nullptr) &&
               "only the first class should be a root class!");
      }
#endif
    }

    void emitDefaultDefines(raw_ostream &OS) const {
      for (auto &Class : Classes) {
        Class->emitDefaultDefines(OS);
      }
    }

    void emitUndefs(raw_ostream &OS) const {
      for (auto &Class : Classes) {
        Class->emitUndefs(OS);
      }
    }

    void emitAttrLists(raw_ostream &OS) const {
      // Just start from the root class.
      Classes[0]->emitAttrList(OS);
    }

    void emitAttrRanges(raw_ostream &OS) const {
      for (auto &Class : Classes)
        Class->emitAttrRange(OS);
    }

    void classifyAttr(const Record *Attr) {
      // Add the attribute to the root class.
      Classes[0]->classifyAttrOnRoot(Attr);
    }

  private:
    AttrClass *findClassByRecord(const Record *R) const {
      for (auto &Class : Classes) {
        if (Class->TheRecord == R)
          return Class.get();
      }
      return nullptr;
    }

    AttrClass *findSuperClass(const Record *R) const {
      // TableGen flattens the superclass list, so we just need to walk it
      // in reverse.
      std::vector<const Record *> SuperClasses = R->getSuperClasses();
      for (const Record *R : reverse(SuperClasses)) {
        if (AttrClass *SuperClass = findClassByRecord(R))
          return SuperClass;
      }
      return nullptr;
    }
  };

} // end anonymous namespace

namespace clang {

// Emits the enumeration list for attributes.
void EmitClangAttrList(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("List of all attributes that Clang recognizes", OS,
                       Records);

  AttrClassHierarchy Hierarchy(Records);

  // Add defaulting macro definitions.
  Hierarchy.emitDefaultDefines(OS);
  emitDefaultDefine(OS, "PRAGMA_SPELLING_ATTR", nullptr);

  std::vector<const Record *> PragmaAttrs;
  for (auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    if (!Attr->getValueAsBit("ASTNode"))
      continue;

    // Add the attribute to the ad-hoc groups.
    if (AttrHasPragmaSpelling(Attr))
      PragmaAttrs.push_back(Attr);

    // Place it in the hierarchy.
    Hierarchy.classifyAttr(Attr);
  }

  // Emit the main attribute list.
  Hierarchy.emitAttrLists(OS);

  // Emit the ad hoc groups.
  emitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs);

  // Emit the attribute ranges.
  OS << "#ifdef ATTR_RANGE\n";
  Hierarchy.emitAttrRanges(OS);
  OS << "#undef ATTR_RANGE\n";
  OS << "#endif\n";

  Hierarchy.emitUndefs(OS);
  OS << "#undef PRAGMA_SPELLING_ATTR\n";
}

// Emits the enumeration list for attributes.
void EmitClangAttrSubjectMatchRuleList(const RecordKeeper &Records,
                                       raw_ostream &OS) {
  emitSourceFileHeader(
      "List of all attribute subject matching rules that Clang recognizes", OS,
      Records);
  PragmaClangAttributeSupport &PragmaAttributeSupport =
      getPragmaAttributeSupport(Records);
  emitDefaultDefine(OS, "ATTR_MATCH_RULE", nullptr);
  PragmaAttributeSupport.emitMatchRuleList(OS);
  OS << "#undef ATTR_MATCH_RULE\n";
}

// Emits the code to read an attribute from a precompiled header.
void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute deserialization code", OS, Records);

  const Record *InhClass = Records.getClass("InheritableAttr");
  std::vector<const Record *> ArgRecords;
  std::vector<std::unique_ptr<Argument>> Args;
  std::unique_ptr<VariadicExprArgument> DelayedArgs;

  OS << "  switch (Kind) {\n";
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;

    OS << "  case attr::" << R.getName() << ": {\n";
    if (R.isSubClassOf(InhClass))
      OS << "    bool isInherited = Record.readInt();\n";
    OS << "    bool isImplicit = Record.readInt();\n";
    OS << "    bool isPackExpansion = Record.readInt();\n";
    DelayedArgs = nullptr;
    if (Attr->getValueAsBit("AcceptsExprPack")) {
      DelayedArgs =
          std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName());
      DelayedArgs->writePCHReadDecls(OS);
    }
    ArgRecords = R.getValueAsListOfDefs("Args");
    Args.clear();
    for (const auto *Arg : ArgRecords) {
      Args.emplace_back(createArgument(*Arg, R.getName()));
      Args.back()->writePCHReadDecls(OS);
    }
    OS << "    New = new (Context) " << R.getName() << "Attr(Context, Info";
    for (auto const &ri : Args) {
      OS << ", ";
      ri->writePCHReadArgs(OS);
    }
    OS << ");\n";
    if (R.isSubClassOf(InhClass))
      OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
    OS << "    New->setImplicit(isImplicit);\n";
    OS << "    New->setPackExpansion(isPackExpansion);\n";
    if (DelayedArgs) {
      OS << "    cast<" << R.getName()
         << "Attr>(New)->setDelayedArgs(Context, ";
      DelayedArgs->writePCHReadArgs(OS);
      OS << ");\n";
    }

    if (Attr->getValueAsBit("HasCustomSerialization"))
      OS << "    read" << R.getName() << "Attr(cast<" << R.getName()
         << "Attr>(New));\n";

    OS << "    break;\n";
    OS << "  }\n";
  }
  OS << "  }\n";
}

// Emits the code to write an attribute to a precompiled header.
void EmitClangAttrPCHWrite(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute serialization code", OS, Records);

  const Record *InhClass = Records.getClass("InheritableAttr");
  OS << "  switch (A->getKind()) {\n";
  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;
    OS << "  case attr::" << R.getName() << ": {\n";
    std::vector<const Record *> Args = R.getValueAsListOfDefs("Args");
    if (R.isSubClassOf(InhClass) || !Args.empty())
      OS << "    const auto *SA = cast<" << R.getName()
         << "Attr>(A);\n";
    if (R.isSubClassOf(InhClass))
      OS << "    Record.push_back(SA->isInherited());\n";
    OS << "    Record.push_back(A->isImplicit());\n";
    OS << "    Record.push_back(A->isPackExpansion());\n";
    if (Attr->getValueAsBit("AcceptsExprPack"))
      VariadicExprArgument("DelayedArgs", R.getName()).writePCHWrite(OS);

    for (const auto *Arg : Args)
      createArgument(*Arg, R.getName())->writePCHWrite(OS);

    if (Attr->getValueAsBit("HasCustomSerialization"))
      OS << "    Record.Add" << R.getName() << "Attr(SA);\n";

    OS << "    break;\n";
    OS << "  }\n";
  }
  OS << "  }\n";
}

} // namespace clang

// Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test'
// parameter with only a single check type, if applicable.
static bool GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
                                            std::string *FnName,
                                            StringRef ListName,
                                            StringRef CheckAgainst,
                                            StringRef Scope) {
  if (!R->isValueUnset(ListName)) {
    Test += " && (";
    std::vector<StringRef> Items = R->getValueAsListOfStrings(ListName);
    for (auto I = Items.begin(), E = Items.end(); I != E; ++I) {
      StringRef Part = *I;
      Test += CheckAgainst;
      Test += " == ";
      Test += Scope;
      Test += Part;
      if (I + 1 != E)
        Test += " || ";
      if (FnName)
        *FnName += Part;
    }
    Test += ")";
    return true;
  }
  return false;
}

// Generate a conditional expression to check if the current target satisfies
// the conditions for a TargetSpecificAttr record, and append the code for
// those checks to the Test string. If the FnName string pointer is non-null,
// append a unique suffix to distinguish this set of target checks from other
// TargetSpecificAttr records.
static bool GenerateTargetSpecificAttrChecks(const Record *R,
                                             std::vector<StringRef> &Arches,
                                             std::string &Test,
                                             std::string *FnName) {
  bool AnyTargetChecks = false;

  // It is assumed that there will be an Triple object
  // named "T" and a TargetInfo object named "Target" within
  // scope that can be used to determine whether the attribute exists in
  // a given target.
  Test += "true";
  // If one or more architectures is specified, check those.  Arches are handled
  // differently because GenerateTargetRequirements needs to combine the list
  // with ParseKind.
  if (!Arches.empty()) {
    AnyTargetChecks = true;
    Test += " && (";
    for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) {
      StringRef Part = *I;
      Test += "T.getArch() == llvm::Triple::";
      Test += Part;
      if (I + 1 != E)
        Test += " || ";
      if (FnName)
        *FnName += Part;
    }
    Test += ")";
  }

  // If the attribute is specific to particular OSes, check those.
  AnyTargetChecks |= GenerateTargetSpecificAttrCheck(
      R, Test, FnName, "OSes", "T.getOS()", "llvm::Triple::");

  // If one or more object formats is specified, check those.
  AnyTargetChecks |=
      GenerateTargetSpecificAttrCheck(R, Test, FnName, "ObjectFormats",
                                      "T.getObjectFormat()", "llvm::Triple::");

  // If custom code is specified, emit it.
  StringRef Code = R->getValueAsString("CustomCode");
  if (!Code.empty()) {
    AnyTargetChecks = true;
    Test += " && (";
    Test += Code;
    Test += ")";
  }

  return AnyTargetChecks;
}

static void GenerateHasAttrSpellingStringSwitch(
    ArrayRef<std::pair<const Record *, FlattenedSpelling>> Attrs,
    raw_ostream &OS, StringRef Variety, StringRef Scope = "") {

  // It turns out that there are duplicate records for a given spelling. This
  // map combines matching test strings using '||'. For example, if there are
  // three conditions A, B, and C, the final result will be: A || B || C.
  llvm::StringMap<std::string> TestStringMap;

  for (const auto &[Attr, Spelling] : Attrs) {
    // C++11-style attributes have specific version information associated with
    // them. If the attribute has no scope, the version information must not
    // have the default value (1), as that's incorrect. Instead, the unscoped
    // attribute version information should be taken from the SD-6 standing
    // document, which can be found at:
    // https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
    //
    // C23-style attributes have the same kind of version information
    // associated with them. The unscoped attribute version information should
    // be taken from the specification of the attribute in the C Standard.
    //
    // Clang-specific attributes have the same kind of version information
    // associated with them. This version is typically the default value (1).
    // These version values are clang-specific and should typically be
    // incremented once the attribute changes its syntax and/or semantics in a
    // a way that is impactful to the end user.
    int Version = 1;

    assert(Spelling.variety() == Variety);
    std::string Name = "";
    if (Spelling.nameSpace().empty() || Scope == Spelling.nameSpace()) {
      Name = Spelling.name();
      Version = static_cast<int>(
          Spelling.getSpellingRecord().getValueAsInt("Version"));
      // Verify that explicitly specified CXX11 and C23 spellings (i.e.
      // not inferred from Clang/GCC spellings) have a version that's
      // different from the default (1).
      bool RequiresValidVersion =
          (Variety == "CXX11" || Variety == "C23") &&
          Spelling.getSpellingRecord().getValueAsString("Variety") == Variety;
      if (RequiresValidVersion && Scope.empty() && Version == 1)
        PrintError(Spelling.getSpellingRecord().getLoc(),
                   "Standard attributes must have "
                   "valid version information.");
    }

    std::string Test;
    if (Attr->isSubClassOf("TargetSpecificAttr")) {
      const Record *R = Attr->getValueAsDef("Target");
      std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches");
      GenerateTargetSpecificAttrChecks(R, Arches, Test, nullptr);
    } else if (!Attr->getValueAsListOfDefs("TargetSpecificSpellings").empty()) {
      // Add target checks if this spelling is target-specific.
      for (const auto &TargetSpelling :
           Attr->getValueAsListOfDefs("TargetSpecificSpellings")) {
        // Find spelling that matches current scope and name.
        for (const auto &Spelling : GetFlattenedSpellings(*TargetSpelling)) {
          if (Scope == Spelling.nameSpace() && Name == Spelling.name()) {
            const Record *Target = TargetSpelling->getValueAsDef("Target");
            std::vector<StringRef> Arches =
                Target->getValueAsListOfStrings("Arches");
            GenerateTargetSpecificAttrChecks(Target, Arches, Test,
                                             /*FnName=*/nullptr);
            break;
          }
        }
      }
    }

    std::string TestStr =
        !Test.empty() ? '(' + Test + " ? " + itostr(Version) + " : 0" + ')'
                      : '(' + itostr(Version) + ')';

    if (Scope.empty() || Scope == Spelling.nameSpace()) {
      if (TestStringMap.contains(Spelling.name()) &&
          TestStringMap[Spelling.name()] != TestStr)
        TestStringMap[Spelling.name()] += " || " + TestStr;
      else
        TestStringMap[Spelling.name()] = TestStr;
    }
  }

  // Create the actual string switch statement after all the attributes have
  // been parsed.
  for (auto &Entry : TestStringMap) {
    OS << "    .Case(\"" << Entry.getKey() << "\", " << Entry.getValue()
       << ")\n";
  }

  OS << "    .Default(0);\n";
}

namespace clang {

// Emits list of regular keyword attributes with info about their arguments.
void EmitClangRegularKeywordAttributeInfo(const RecordKeeper &Records,
                                          raw_ostream &OS) {
  emitSourceFileHeader(
      "A list of regular keyword attributes generated from the attribute"
      " definitions",
      OS);
  // Assume for now that the same token is not used in multiple regular
  // keyword attributes.
  for (auto *R : Records.getAllDerivedDefinitions("Attr"))
    for (const auto &S : GetFlattenedSpellings(*R)) {
      if (!isRegularKeywordAttribute(S))
        continue;
      std::vector<const Record *> Args = R->getValueAsListOfDefs("Args");
      bool HasArgs = any_of(
          Args, [](const Record *Arg) { return !Arg->getValueAsBit("Fake"); });

      OS << "KEYWORD_ATTRIBUTE("
         << S.getSpellingRecord().getValueAsString("Name") << ", "
         << (HasArgs ? "true" : "false") << ", )\n";
    }
  OS << "#undef KEYWORD_ATTRIBUTE\n";
}

void EmitCXX11AttributeInfo(const RecordKeeper &Records, raw_ostream &OS) {
  OS << "#if defined(CXX11_ATTR_ARGS_INFO)\n";
  for (auto *R : Records.getAllDerivedDefinitions("Attr")) {
    for (const FlattenedSpelling &SI : GetFlattenedSpellings(*R)) {
      if (SI.variety() == "CXX11" && SI.nameSpace().empty()) {
        unsigned RequiredArgs = 0;
        unsigned OptionalArgs = 0;
        for (const auto *Arg : R->getValueAsListOfDefs("Args")) {
          if (Arg->getValueAsBit("Fake"))
            continue;

          if (Arg->getValueAsBit("Optional"))
            OptionalArgs++;
          else
            RequiredArgs++;
        }
        OS << ".Case(\"" << SI.getSpellingRecord().getValueAsString("Name")
           << "\","
           << "AttributeCommonInfo::AttrArgsInfo::"
           << (RequiredArgs   ? "Required"
               : OptionalArgs ? "Optional"
                              : "None")
           << ")"
           << "\n";
      }
    }
  }
  OS << "#endif // CXX11_ATTR_ARGS_INFO\n";
}

// Emits the list of spellings for attributes.
void EmitClangAttrHasAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Code to implement the __has_attribute logic", OS,
                       Records);

  // Separate all of the attributes out into four group: generic, C++11, GNU,
  // and declspecs. Then generate a big switch statement for each of them.
  using PairTy = std::pair<const Record *, FlattenedSpelling>;
  std::vector<PairTy> Declspec, Microsoft, GNU, Pragma, HLSLAnnotation;
  std::map<StringRef, std::vector<PairTy>> CXX, C23;

  // Walk over the list of all attributes, and split them out based on the
  // spelling variety.
  for (auto *R : Records.getAllDerivedDefinitions("Attr")) {
    for (const FlattenedSpelling &SI : GetFlattenedSpellings(*R)) {
      StringRef Variety = SI.variety();
      if (Variety == "GNU")
        GNU.emplace_back(R, SI);
      else if (Variety == "Declspec")
        Declspec.emplace_back(R, SI);
      else if (Variety == "Microsoft")
        Microsoft.emplace_back(R, SI);
      else if (Variety == "CXX11")
        CXX[SI.nameSpace()].emplace_back(R, SI);
      else if (Variety == "C23")
        C23[SI.nameSpace()].emplace_back(R, SI);
      else if (Variety == "Pragma")
        Pragma.emplace_back(R, SI);
      else if (Variety == "HLSLAnnotation")
        HLSLAnnotation.emplace_back(R, SI);
    }
  }

  OS << "const llvm::Triple &T = Target.getTriple();\n";
  OS << "switch (Syntax) {\n";
  OS << "case AttributeCommonInfo::Syntax::AS_GNU:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU");
  OS << "case AttributeCommonInfo::Syntax::AS_Declspec:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
  OS << "case AttributeCommonInfo::Syntax::AS_Microsoft:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(Microsoft, OS, "Microsoft");
  OS << "case AttributeCommonInfo::Syntax::AS_Pragma:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
  OS << "case AttributeCommonInfo::Syntax::AS_HLSLAnnotation:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(HLSLAnnotation, OS, "HLSLAnnotation");
  auto fn = [&OS](StringRef Spelling,
                  const std::map<StringRef, std::vector<PairTy>> &Map) {
    OS << "case AttributeCommonInfo::Syntax::AS_" << Spelling << ": {\n";
    // C++11-style attributes are further split out based on the Scope.
    ListSeparator LS(" else ");
    for (const auto &[Scope, List] : Map) {
      OS << LS;
      OS << "if (ScopeName == \"" << Scope << "\") {\n";
      OS << "  return llvm::StringSwitch<int>(Name)\n";
      GenerateHasAttrSpellingStringSwitch(List, OS, Spelling, Scope);
      OS << "}";
    }
    OS << "\n} break;\n";
  };
  fn("CXX11", CXX);
  fn("C23", C23);
  OS << "case AttributeCommonInfo::Syntax::AS_Keyword:\n";
  OS << "case AttributeCommonInfo::Syntax::AS_ContextSensitiveKeyword:\n";
  OS << "  llvm_unreachable(\"hasAttribute not supported for keyword\");\n";
  OS << "  return 0;\n";
  OS << "case AttributeCommonInfo::Syntax::AS_Implicit:\n";
  OS << "  llvm_unreachable (\"hasAttribute not supported for "
        "AS_Implicit\");\n";
  OS << "  return 0;\n";

  OS << "}\n";
}

void EmitClangAttrSpellingListIndex(const RecordKeeper &Records,
                                    raw_ostream &OS) {
  emitSourceFileHeader("Code to translate different attribute spellings into "
                       "internal identifiers",
                       OS, Records);

  OS << "  switch (getParsedKind()) {\n";
  OS << "    case IgnoredAttribute:\n";
  OS << "    case UnknownAttribute:\n";
  OS << "    case NoSemaHandlerAttribute:\n";
  OS << "      llvm_unreachable(\"Ignored/unknown shouldn't get here\");\n";

  ParsedAttrMap Attrs = getParsedAttrList(Records);
  for (const auto &I : Attrs) {
    const Record &R = *I.second;
    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
    OS << "  case AT_" << I.first << ": {\n";

    // If there are none or one spelling to check, resort to the default
    // behavior of returning index as 0.
    if (Spellings.size() <= 1) {
      OS << "    return 0;\n"
         << "    break;\n"
         << "  }\n";
      continue;
    }

    std::vector<StringRef> Names;
    llvm::transform(Spellings, std::back_inserter(Names),
                    [](const FlattenedSpelling &FS) { return FS.name(); });
    llvm::sort(Names);
    Names.erase(llvm::unique(Names), Names.end());

    for (const auto &[Idx, FS] : enumerate(Spellings)) {
      OS << "    if (";
      if (Names.size() > 1) {
        SmallVector<StringRef, 6> SameLenNames;
        StringRef FSName = FS.name();
        llvm::copy_if(
            Names, std::back_inserter(SameLenNames),
            [&](StringRef N) { return N.size() == FSName.size(); });

        if (SameLenNames.size() == 1) {
          OS << "Name.size() == " << FS.name().size() << " && ";
        } else {
          // FIXME: We currently fall back to comparing entire strings if there
          // are 2 or more spelling names with the same length. This can be
          // optimized to check only for the the first differing character
          // between them instead.
          OS << "Name == \"" << FS.name() << "\""
             << " && ";
        }
      }

      OS << "getSyntax() == AttributeCommonInfo::AS_" << FS.variety()
         << " && ComputedScope == ";
      if (FS.nameSpace() == "")
        OS << "AttributeCommonInfo::Scope::NONE";
      else
        OS << "AttributeCommonInfo::Scope::" + FS.nameSpace().upper();

      OS << ")\n"
         << "      return " << Idx << ";\n";
    }

    OS << "    break;\n"
       << "  }\n";
  }

  OS << "  }\n"
     << "  return 0;\n";
}

// Emits code used by RecursiveASTVisitor to visit attributes
void EmitClangAttrASTVisitor(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS,
                       Records);
  // Write method declarations for Traverse* methods.
  // We emit this here because we only generate methods for attributes that
  // are declared as ASTNodes.
  OS << "#ifdef ATTR_VISITOR_DECLS_ONLY\n\n";
  ArrayRef<const Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
  for (const auto *Attr : Attrs) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;
    OS << "  bool Traverse"
       << R.getName() << "Attr(" << R.getName() << "Attr *A);\n";
    OS << "  bool Visit"
       << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
       << "    return true; \n"
       << "  }\n";
  }
  OS << "\n#else // ATTR_VISITOR_DECLS_ONLY\n\n";

  // Write individual Traverse* methods for each attribute class.
  for (const auto *Attr : Attrs) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;

    OS << "template <typename Derived>\n"
       << "bool VISITORCLASS<Derived>::Traverse"
       << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
       << "  if (!getDerived().VisitAttr(A))\n"
       << "    return false;\n"
       << "  if (!getDerived().Visit" << R.getName() << "Attr(A))\n"
       << "    return false;\n";

    for (const auto *Arg : R.getValueAsListOfDefs("Args"))
      createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS);

    if (Attr->getValueAsBit("AcceptsExprPack"))
      VariadicExprArgument("DelayedArgs", R.getName())
          .writeASTVisitorTraversal(OS);

    OS << "  return true;\n";
    OS << "}\n\n";
  }

  // Write generic Traverse routine
  OS << "template <typename Derived>\n"
     << "bool VISITORCLASS<Derived>::TraverseAttr(Attr *A) {\n"
     << "  if (!A)\n"
     << "    return true;\n"
     << "\n"
     << "  switch (A->getKind()) {\n";

  for (const auto *Attr : Attrs) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;

    OS << "    case attr::" << R.getName() << ":\n"
       << "      return getDerived().Traverse" << R.getName() << "Attr("
       << "cast<" << R.getName() << "Attr>(A));\n";
  }
  OS << "  }\n";  // end switch
  OS << "  llvm_unreachable(\"bad attribute kind\");\n";
  OS << "}\n";  // end function
  OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
}

static void
EmitClangAttrTemplateInstantiateHelper(ArrayRef<const Record *> Attrs,
                                       raw_ostream &OS, bool AppliesToDecl) {

  OS << "  switch (At->getKind()) {\n";
  for (const auto *Attr : Attrs) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;
    OS << "    case attr::" << R.getName() << ": {\n";
    bool ShouldClone = R.getValueAsBit("Clone") &&
                       (!AppliesToDecl ||
                        R.getValueAsBit("MeaningfulToClassTemplateDefinition"));

    if (!ShouldClone) {
      OS << "      return nullptr;\n";
      OS << "    }\n";
      continue;
    }

    OS << "      const auto *A = cast<"
       << R.getName() << "Attr>(At);\n";
    bool TDependent = R.getValueAsBit("TemplateDependent");

    if (!TDependent) {
      OS << "      return A->clone(C);\n";
      OS << "    }\n";
      continue;
    }

    std::vector<const Record *> ArgRecords = R.getValueAsListOfDefs("Args");
    std::vector<std::unique_ptr<Argument>> Args;
    Args.reserve(ArgRecords.size());

    for (const auto *ArgRecord : ArgRecords)
      Args.emplace_back(createArgument(*ArgRecord, R.getName()));

    for (auto const &ai : Args)
      ai->writeTemplateInstantiation(OS);

    OS << "      return new (C) " << R.getName() << "Attr(C, *A";
    for (auto const &ai : Args) {
      OS << ", ";
      ai->writeTemplateInstantiationArgs(OS);
    }
    OS << ");\n"
       << "    }\n";
  }
  OS << "  } // end switch\n"
     << "  llvm_unreachable(\"Unknown attribute!\");\n"
     << "  return nullptr;\n";
}

// Emits code to instantiate dependent attributes on templates.
void EmitClangAttrTemplateInstantiate(const RecordKeeper &Records,
                                      raw_ostream &OS) {
  emitSourceFileHeader("Template instantiation code for attributes", OS,
                       Records);

  ArrayRef<const Record *> Attrs = Records.getAllDerivedDefinitions("Attr");

  OS << "namespace clang {\n"
     << "namespace sema {\n\n"
     << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
     << "Sema &S,\n"
     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/false);
  OS << "}\n\n"
     << "Attr *instantiateTemplateAttributeForDecl(const Attr *At,\n"
     << " ASTContext &C, Sema &S,\n"
     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/true);
  OS << "}\n\n"
     << "} // end namespace sema\n"
     << "} // end namespace clang\n";
}

// Emits the list of parsed attributes.
void EmitClangAttrParsedAttrList(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("List of all attributes that Clang recognizes", OS,
                       Records);

  OS << "#ifndef PARSED_ATTR\n";
  OS << "#define PARSED_ATTR(NAME) NAME\n";
  OS << "#endif\n\n";

  ParsedAttrMap Names = getParsedAttrList(Records);
  for (const auto &I : Names) {
    OS << "PARSED_ATTR(" << I.first << ")\n";
  }
}

void EmitAttributeSpellingList(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("List of attribute names", OS, Records);

  std::set<StringRef> AttrSpellingList;
  std::set<StringRef> AttrScopeSpellingList;

  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    for (const auto &S : GetFlattenedSpellings(*A)) {
      AttrSpellingList.insert(S.name());
      if (S.nameSpace().size())
        AttrScopeSpellingList.insert(S.nameSpace());
    }
  }

  OS << "#ifndef ATTR_NAME" << "\n";
  OS << "#define ATTR_NAME(NAME) NAME" << "\n";
  OS << "#endif" << "\n" << "\n";
  for (const auto &AttrName : AttrSpellingList) {
    OS << "ATTR_NAME(\"" << AttrName << "\")\n";
  }
  OS << "\n";
  OS << "#undef ATTR_NAME" << "\n";
  OS << "\n";

  OS << "#ifndef ATTR_SCOPE_NAME" << "\n";
  OS << "#define ATTR_SCOPE_NAME(SCOPE_NAME) SCOPE_NAME" << "\n";
  OS << "#endif" << "\n" << "\n";
  for (const auto &AttrScopeName : AttrScopeSpellingList) {
    OS << "ATTR_SCOPE_NAME(\"" << AttrScopeName << "\")\n";
  }
  OS << "\n";
  OS << "#undef ATTR_SCOPE_NAME" << "\n";
  OS << "\n";
}

static bool isArgVariadic(const Record &R, StringRef AttrName) {
  return createArgument(R, AttrName)->isVariadic();
}

static void emitArgInfo(const Record &R, raw_ostream &OS) {
  // This function will count the number of arguments specified for the
  // attribute and emit the number of required arguments followed by the
  // number of optional arguments.
  unsigned ArgCount = 0, OptCount = 0, ArgMemberCount = 0;
  bool HasVariadic = false;
  for (const auto *Arg : R.getValueAsListOfDefs("Args")) {
    // If the arg is fake, it's the user's job to supply it: general parsing
    // logic shouldn't need to know anything about it.
    if (Arg->getValueAsBit("Fake"))
      continue;
    Arg->getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
    ++ArgMemberCount;
    if (!HasVariadic && isArgVariadic(*Arg, R.getName()))
      HasVariadic = true;
  }

  // If there is a variadic argument, we will set the optional argument count
  // to its largest value. Since it's currently a 4-bit number, we set it to 15.
  OS << "    /*NumArgs=*/" << ArgCount << ",\n";
  OS << "    /*OptArgs=*/" << (HasVariadic ? 15 : OptCount) << ",\n";
  OS << "    /*NumArgMembers=*/" << ArgMemberCount << ",\n";
}

static std::string GetDiagnosticSpelling(const Record &R) {
  StringRef Ret = R.getValueAsString("DiagSpelling");
  if (!Ret.empty())
    return Ret.str();

  // If we couldn't find the DiagSpelling in this object, we can check to see
  // if the object is one that has a base, and if it is, loop up to the Base
  // member recursively.
  if (auto Base = R.getValueAsOptionalDef(BaseFieldName))
    return GetDiagnosticSpelling(*Base);

  return "";
}

static std::string CalculateDiagnostic(const Record &S) {
  // If the SubjectList object has a custom diagnostic associated with it,
  // return that directly.
  const StringRef CustomDiag = S.getValueAsString("CustomDiag");
  if (!CustomDiag.empty())
    return ("\"" + Twine(CustomDiag) + "\"").str();

  std::vector<std::string> DiagList;
  for (const auto *Subject : S.getValueAsListOfDefs("Subjects")) {
    const Record &R = *Subject;
    // Get the diagnostic text from the Decl or Stmt node given.
    std::string V = GetDiagnosticSpelling(R);
    if (V.empty()) {
      PrintError(R.getLoc(),
                 "Could not determine diagnostic spelling for the node: " +
                     R.getName() + "; please add one to DeclNodes.td");
    } else {
      // The node may contain a list of elements itself, so split the elements
      // by a comma, and trim any whitespace.
      SmallVector<StringRef, 2> Frags;
      SplitString(V, Frags, ",");
      for (auto Str : Frags) {
        DiagList.push_back(Str.trim().str());
      }
    }
  }

  if (DiagList.empty()) {
    PrintFatalError(S.getLoc(),
                    "Could not deduce diagnostic argument for Attr subjects");
    return "";
  }

  // FIXME: this is not particularly good for localization purposes and ideally
  // should be part of the diagnostics engine itself with some sort of list
  // specifier.

  // A single member of the list can be returned directly.
  if (DiagList.size() == 1)
    return '"' + DiagList.front() + '"';

  if (DiagList.size() == 2)
    return '"' + DiagList[0] + " and " + DiagList[1] + '"';

  // If there are more than two in the list, we serialize the first N - 1
  // elements with a comma. This leaves the string in the state: foo, bar,
  // baz (but misses quux). We can then add ", and " for the last element
  // manually.
  std::string Diag = join(DiagList.begin(), DiagList.end() - 1, ", ");
  return '"' + Diag + ", and " + *(DiagList.end() - 1) + '"';
}

static std::string GetSubjectWithSuffix(const Record *R) {
  const std::string B = R->getName().str();
  if (B == "DeclBase")
    return "Decl";
  return B + "Decl";
}

static std::string functionNameForCustomAppertainsTo(const Record &Subject) {
  return "is" + Subject.getName().str();
}

static void GenerateCustomAppertainsTo(const Record &Subject, raw_ostream &OS) {
  std::string FnName = functionNameForCustomAppertainsTo(Subject);

  // If this code has already been generated, we don't need to do anything.
  static std::set<std::string> CustomSubjectSet;
  auto I = CustomSubjectSet.find(FnName);
  if (I != CustomSubjectSet.end())
    return;

  // This only works with non-root Decls.
  const Record *Base = Subject.getValueAsDef(BaseFieldName);

  // Not currently support custom subjects within custom subjects.
  if (Base->isSubClassOf("SubsetSubject")) {
    PrintFatalError(Subject.getLoc(),
                    "SubsetSubjects within SubsetSubjects is not supported");
    return;
  }

  OS << "static bool " << FnName << "(const Decl *D) {\n";
  OS << "  if (const auto *S = dyn_cast<";
  OS << GetSubjectWithSuffix(Base);
  OS << ">(D))\n";
  OS << "    return " << Subject.getValueAsString("CheckCode") << ";\n";
  OS << "  return false;\n";
  OS << "}\n\n";

  CustomSubjectSet.insert(FnName);
}

static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
  // If the attribute does not contain a Subjects definition, then use the
  // default appertainsTo logic.
  if (Attr.isValueUnset("Subjects"))
    return;

  const Record *SubjectObj = Attr.getValueAsDef("Subjects");
  std::vector<const Record *> Subjects =
      SubjectObj->getValueAsListOfDefs("Subjects");

  // If the list of subjects is empty, it is assumed that the attribute
  // appertains to everything.
  if (Subjects.empty())
    return;

  bool Warn = SubjectObj->getValueAsDef("Diag")->getValueAsBit("Warn");

  // Split the subjects into declaration subjects and statement subjects.
  // FIXME: subset subjects are added to the declaration list until there are
  // enough statement attributes with custom subject needs to warrant
  // the implementation effort.
  std::vector<const Record *> DeclSubjects, StmtSubjects;
  copy_if(Subjects, std::back_inserter(DeclSubjects), [](const Record *R) {
    return R->isSubClassOf("SubsetSubject") || !R->isSubClassOf("StmtNode");
  });
  copy_if(Subjects, std::back_inserter(StmtSubjects),
          [](const Record *R) { return R->isSubClassOf("StmtNode"); });

  // We should have sorted all of the subjects into two lists.
  // FIXME: this assertion will be wrong if we ever add type attribute subjects.
  assert(DeclSubjects.size() + StmtSubjects.size() == Subjects.size());

  if (DeclSubjects.empty()) {
    // If there are no decl subjects but there are stmt subjects, diagnose
    // trying to apply a statement attribute to a declaration.
    if (!StmtSubjects.empty()) {
      OS << "bool diagAppertainsToDecl(Sema &S, const ParsedAttr &AL, ";
      OS << "const Decl *D) const override {\n";
      OS << "  S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
      OS << "    << AL << AL.isRegularKeywordAttribute() << "
            "D->getLocation();\n";
      OS << "  return false;\n";
      OS << "}\n\n";
    }
  } else {
    // Otherwise, generate an appertainsTo check specific to this attribute
    // which checks all of the given subjects against the Decl passed in.
    OS << "bool diagAppertainsToDecl(Sema &S, ";
    OS << "const ParsedAttr &Attr, const Decl *D) const override {\n";
    OS << "  if (";
    for (auto I = DeclSubjects.begin(), E = DeclSubjects.end(); I != E; ++I) {
      // If the subject has custom code associated with it, use the generated
      // function for it. The function cannot be inlined into this check (yet)
      // because it requires the subject to be of a specific type, and were that
      // information inlined here, it would not support an attribute with
      // multiple custom subjects.
      if ((*I)->isSubClassOf("SubsetSubject"))
        OS << "!" << functionNameForCustomAppertainsTo(**I) << "(D)";
      else
        OS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)";

      if (I + 1 != E)
        OS << " && ";
    }
    OS << ") {\n";
    OS << "    S.Diag(Attr.getLoc(), diag::";
    OS << (Warn ? "warn_attribute_wrong_decl_type_str"
                : "err_attribute_wrong_decl_type_str");
    OS << ")\n";
    OS << "      << Attr << Attr.isRegularKeywordAttribute() << ";
    OS << CalculateDiagnostic(*SubjectObj) << ";\n";
    OS << "    return false;\n";
    OS << "  }\n";
    OS << "  return true;\n";
    OS << "}\n\n";
  }

  if (StmtSubjects.empty()) {
    // If there are no stmt subjects but there are decl subjects, diagnose
    // trying to apply a declaration attribute to a statement.
    if (!DeclSubjects.empty()) {
      OS << "bool diagAppertainsToStmt(Sema &S, const ParsedAttr &AL, ";
      OS << "const Stmt *St) const override {\n";
      OS << "  S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
      OS << "    << AL << AL.isRegularKeywordAttribute() << "
            "St->getBeginLoc();\n";
      OS << "  return false;\n";
      OS << "}\n\n";
    }
  } else {
    // Now, do the same for statements.
    OS << "bool diagAppertainsToStmt(Sema &S, ";
    OS << "const ParsedAttr &Attr, const Stmt *St) const override {\n";
    OS << "  if (";
    for (auto I = StmtSubjects.begin(), E = StmtSubjects.end(); I != E; ++I) {
      OS << "!isa<" << (*I)->getName() << ">(St)";
      if (I + 1 != E)
        OS << " && ";
    }
    OS << ") {\n";
    OS << "    S.Diag(Attr.getLoc(), diag::";
    OS << (Warn ? "warn_attribute_wrong_decl_type_str"
                : "err_attribute_wrong_decl_type_str");
    OS << ")\n";
    OS << "      << Attr << Attr.isRegularKeywordAttribute() << ";
    OS << CalculateDiagnostic(*SubjectObj) << ";\n";
    OS << "    return false;\n";
    OS << "  }\n";
    OS << "  return true;\n";
    OS << "}\n\n";
  }
}

// Generates the mutual exclusion checks. The checks for parsed attributes are
// written into OS and the checks for merging declaration attributes are
// written into MergeOS.
static void GenerateMutualExclusionsChecks(const Record &Attr,
                                           const RecordKeeper &Records,
                                           raw_ostream &OS,
                                           raw_ostream &MergeDeclOS,
                                           raw_ostream &MergeStmtOS) {
  // We don't do any of this magic for type attributes yet.
  if (Attr.isSubClassOf("TypeAttr"))
    return;

  // This means the attribute is either a statement attribute, a decl
  // attribute, or both; find out which.
  bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") ||
                           Attr.isSubClassOf("DeclOrStmtAttr") ||
                           Attr.isSubClassOf("InheritableParamOrStmtAttr");
  bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr ||
                           Attr.isSubClassOf("DeclOrStmtAttr") ||
                           Attr.isSubClassOf("InheritableParamOrStmtAttr");

  std::vector<std::string> DeclAttrs, StmtAttrs;

  // Find all of the definitions that inherit from MutualExclusions and include
  // the given attribute in the list of exclusions to generate the
  // diagMutualExclusion() check.
  for (const Record *Exclusion :
       Records.getAllDerivedDefinitions("MutualExclusions")) {
    std::vector<const Record *> MutuallyExclusiveAttrs =
        Exclusion->getValueAsListOfDefs("Exclusions");
    auto IsCurAttr = [Attr](const Record *R) {
      return R->getName() == Attr.getName();
    };
    if (any_of(MutuallyExclusiveAttrs, IsCurAttr)) {
      // This list of exclusions includes the attribute we're looking for, so
      // add the exclusive attributes to the proper list for checking.
      for (const Record *AttrToExclude : MutuallyExclusiveAttrs) {
        if (IsCurAttr(AttrToExclude))
          continue;

        if (CurAttrIsStmtAttr)
          StmtAttrs.push_back((AttrToExclude->getName() + "Attr").str());
        if (CurAttrIsDeclAttr)
          DeclAttrs.push_back((AttrToExclude->getName() + "Attr").str());
      }
    }
  }

  // If there are any decl or stmt attributes, silence -Woverloaded-virtual
  // warnings for them both.
  if (!DeclAttrs.empty() || !StmtAttrs.empty())
    OS << "  using ParsedAttrInfo::diagMutualExclusion;\n\n";

  // If we discovered any decl or stmt attributes to test for, generate the
  // predicates for them now.
  if (!DeclAttrs.empty()) {
    // Generate the ParsedAttrInfo subclass logic for declarations.
    OS << "  bool diagMutualExclusion(Sema &S, const ParsedAttr &AL, "
       << "const Decl *D) const override {\n";
    for (const std::string &A : DeclAttrs) {
      OS << "    if (const auto *A = D->getAttr<" << A << ">()) {\n";
      OS << "      S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
         << " << AL << A << (AL.isRegularKeywordAttribute() ||"
         << " A->isRegularKeywordAttribute());\n";
      OS << "      S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
      OS << "      \nreturn false;\n";
      OS << "    }\n";
    }
    OS << "    return true;\n";
    OS << "  }\n\n";

    // Also generate the declaration attribute merging logic if the current
    // attribute is one that can be inheritted on a declaration. It is assumed
    // this code will be executed in the context of a function with parameters:
    // Sema &S, Decl *D, Attr *A and that returns a bool (false on diagnostic,
    // true on success).
    if (Attr.isSubClassOf("InheritableAttr")) {
      MergeDeclOS << "  if (const auto *Second = dyn_cast<"
                  << (Attr.getName() + "Attr").str() << ">(A)) {\n";
      for (const std::string &A : DeclAttrs) {
        MergeDeclOS << "    if (const auto *First = D->getAttr<" << A
                    << ">()) {\n";
        MergeDeclOS << "      S.Diag(First->getLocation(), "
                    << "diag::err_attributes_are_not_compatible) << First << "
                    << "Second << (First->isRegularKeywordAttribute() || "
                    << "Second->isRegularKeywordAttribute());\n";
        MergeDeclOS << "      S.Diag(Second->getLocation(), "
                    << "diag::note_conflicting_attribute);\n";
        MergeDeclOS << "      return false;\n";
        MergeDeclOS << "    }\n";
      }
      MergeDeclOS << "    return true;\n";
      MergeDeclOS << "  }\n";
    }
  }

  // Statement attributes are a bit different from declarations. With
  // declarations, each attribute is added to the declaration as it is
  // processed, and so you can look on the Decl * itself to see if there is a
  // conflicting attribute. Statement attributes are processed as a group
  // because AttributedStmt needs to tail-allocate all of the attribute nodes
  // at once. This means we cannot check whether the statement already contains
  // an attribute to check for the conflict. Instead, we need to check whether
  // the given list of semantic attributes contain any conflicts. It is assumed
  // this code will be executed in the context of a function with parameters:
  // Sema &S, const SmallVectorImpl<const Attr *> &C. The code will be within a
  // loop which loops over the container C with a loop variable named A to
  // represent the current attribute to check for conflicts.
  //
  // FIXME: it would be nice not to walk over the list of potential attributes
  // to apply to the statement more than once, but statements typically don't
  // have long lists of attributes on them, so re-walking the list should not
  // be an expensive operation.
  if (!StmtAttrs.empty()) {
    MergeStmtOS << "    if (const auto *Second = dyn_cast<"
                << (Attr.getName() + "Attr").str() << ">(A)) {\n";
    MergeStmtOS << "      auto Iter = llvm::find_if(C, [](const Attr *Check) "
                << "{ return isa<";
    interleave(
        StmtAttrs, [&](StringRef Name) { MergeStmtOS << Name; },
        [&] { MergeStmtOS << ", "; });
    MergeStmtOS << ">(Check); });\n";
    MergeStmtOS << "      if (Iter != C.end()) {\n";
    MergeStmtOS << "        S.Diag((*Iter)->getLocation(), "
                << "diag::err_attributes_are_not_compatible) << *Iter << "
                << "Second << ((*Iter)->isRegularKeywordAttribute() || "
                << "Second->isRegularKeywordAttribute());\n";
    MergeStmtOS << "        S.Diag(Second->getLocation(), "
                << "diag::note_conflicting_attribute);\n";
    MergeStmtOS << "        return false;\n";
    MergeStmtOS << "      }\n";
    MergeStmtOS << "    }\n";
  }
}

static void
emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
                        raw_ostream &OS) {
  OS << "static bool checkAttributeMatchRuleAppliesTo(const Decl *D, "
     << AttributeSubjectMatchRule::EnumName << " rule) {\n";
  OS << "  switch (rule) {\n";
  for (const auto &Rule : PragmaAttributeSupport.Rules) {
    if (Rule.isAbstractRule()) {
      OS << "  case " << Rule.getEnumValue() << ":\n";
      OS << "    assert(false && \"Abstract matcher rule isn't allowed\");\n";
      OS << "    return false;\n";
      continue;
    }
    std::vector<const Record *> Subjects = Rule.getSubjects();
    assert(!Subjects.empty() && "Missing subjects");
    OS << "  case " << Rule.getEnumValue() << ":\n";
    OS << "    return ";
    for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
      // If the subject has custom code associated with it, use the function
      // that was generated for GenerateAppertainsTo to check if the declaration
      // is valid.
      if ((*I)->isSubClassOf("SubsetSubject"))
        OS << functionNameForCustomAppertainsTo(**I) << "(D)";
      else
        OS << "isa<" << GetSubjectWithSuffix(*I) << ">(D)";

      if (I + 1 != E)
        OS << " || ";
    }
    OS << ";\n";
  }
  OS << "  }\n";
  OS << "  llvm_unreachable(\"Invalid match rule\");\nreturn false;\n";
  OS << "}\n\n";
}

static void GenerateLangOptRequirements(const Record &R,
                                        raw_ostream &OS) {
  // If the attribute has an empty or unset list of language requirements,
  // use the default handler.
  std::vector<const Record *> LangOpts = R.getValueAsListOfDefs("LangOpts");
  if (LangOpts.empty())
    return;

  OS << "bool acceptsLangOpts(const LangOptions &LangOpts) const override {\n";
  OS << "  return " << GenerateTestExpression(LangOpts) << ";\n";
  OS << "}\n\n";
}

static void GenerateTargetRequirements(const Record &Attr,
                                       const ParsedAttrMap &Dupes,
                                       raw_ostream &OS) {
  // If the attribute is not a target specific attribute, use the default
  // target handler.
  if (!Attr.isSubClassOf("TargetSpecificAttr"))
    return;

  // Get the list of architectures to be tested for.
  const Record *R = Attr.getValueAsDef("Target");
  std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches");

  // If there are other attributes which share the same parsed attribute kind,
  // such as target-specific attributes with a shared spelling, collapse the
  // duplicate architectures. This is required because a shared target-specific
  // attribute has only one ParsedAttr::Kind enumeration value, but it
  // applies to multiple target architectures. In order for the attribute to be
  // considered valid, all of its architectures need to be included.
  if (!Attr.isValueUnset("ParseKind")) {
    const StringRef APK = Attr.getValueAsString("ParseKind");
    for (const auto &I : Dupes) {
      if (I.first == APK) {
        std::vector<StringRef> DA =
            I.second->getValueAsDef("Target")->getValueAsListOfStrings(
                "Arches");
        llvm::append_range(Arches, DA);
      }
    }
  }

  std::string FnName = "isTarget";
  std::string Test;
  bool UsesT = GenerateTargetSpecificAttrChecks(R, Arches, Test, &FnName);

  OS << "bool existsInTarget(const TargetInfo &Target) const override {\n";
  if (UsesT)
    OS << "  const llvm::Triple &T = Target.getTriple(); (void)T;\n";
  OS << "  return " << Test << ";\n";
  OS << "}\n\n";
}

static void
GenerateSpellingTargetRequirements(const Record &Attr,
                                   ArrayRef<const Record *> TargetSpellings,
                                   raw_ostream &OS) {
  // If there are no target specific spellings, use the default target handler.
  if (TargetSpellings.empty())
    return;

  std::string Test;
  bool UsesT = false;
  const std::vector<FlattenedSpelling> SpellingList =
      GetFlattenedSpellings(Attr);
  for (unsigned TargetIndex = 0; TargetIndex < TargetSpellings.size();
       ++TargetIndex) {
    const auto &TargetSpelling = TargetSpellings[TargetIndex];
    std::vector<FlattenedSpelling> Spellings =
        GetFlattenedSpellings(*TargetSpelling);

    Test += "((SpellingListIndex == ";
    for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
      Test += itostr(getSpellingListIndex(SpellingList, Spellings[Index]));
      if (Index != Spellings.size() - 1)
        Test += " ||\n    SpellingListIndex == ";
      else
        Test += ") && ";
    }

    const Record *Target = TargetSpelling->getValueAsDef("Target");
    std::vector<StringRef> Arches = Target->getValueAsListOfStrings("Arches");
    std::string FnName = "isTargetSpelling";
    UsesT |= GenerateTargetSpecificAttrChecks(Target, Arches, Test, &FnName);
    Test += ")";
    if (TargetIndex != TargetSpellings.size() - 1)
      Test += " || ";
  }

  OS << "bool spellingExistsInTarget(const TargetInfo &Target,\n";
  OS << "                            const unsigned SpellingListIndex) const "
        "override {\n";
  if (UsesT)
    OS << "  const llvm::Triple &T = Target.getTriple(); (void)T;\n";
  OS << "  return " << Test << ";\n", OS << "}\n\n";
}

static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
                                                    raw_ostream &OS) {
  // If the attribute does not have a semantic form, we can bail out early.
  if (!Attr.getValueAsBit("ASTNode"))
    return;

  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);

  // If there are zero or one spellings, or all of the spellings share the same
  // name, we can also bail out early.
  if (Spellings.size() <= 1 || SpellingNamesAreCommon(Spellings))
    return;

  // Generate the enumeration we will use for the mapping.
  SemanticSpellingMap SemanticToSyntacticMap;
  std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);

  OS << "unsigned spellingIndexToSemanticSpelling(";
  OS << "const ParsedAttr &Attr) const override {\n";
  OS << Enum;
  OS << "  unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
  WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
  OS << "}\n\n";
}

static void GenerateHandleDeclAttribute(const Record &Attr, raw_ostream &OS) {
  // Only generate if Attr can be handled simply.
  if (!Attr.getValueAsBit("SimpleHandler"))
    return;

  // Generate a function which just converts from ParsedAttr to the Attr type.
  OS << "AttrHandling handleDeclAttribute(Sema &S, Decl *D,";
  OS << "const ParsedAttr &Attr) const override {\n";
  OS << "  D->addAttr(::new (S.Context) " << Attr.getName();
  OS << "Attr(S.Context, Attr));\n";
  OS << "  return AttributeApplied;\n";
  OS << "}\n\n";
}

static bool isParamExpr(const Record *Arg) {
  return !Arg->getDirectSuperClasses().empty() &&
         StringSwitch<bool>(
             Arg->getDirectSuperClasses().back().first->getName())
             .Case("ExprArgument", true)
             .Case("VariadicExprArgument", true)
             .Default(false);
}

static void GenerateIsParamExpr(const Record &Attr, raw_ostream &OS) {
  OS << "bool isParamExpr(size_t N) const override {\n";
  OS << "  return ";
  auto Args = Attr.getValueAsListOfDefs("Args");
  for (size_t I = 0; I < Args.size(); ++I)
    if (isParamExpr(Args[I]))
      OS << "(N == " << I << ") || ";
  OS << "false;\n";
  OS << "}\n\n";
}

static void GenerateHandleAttrWithDelayedArgs(const RecordKeeper &Records,
                                              raw_ostream &OS) {
  OS << "static void handleAttrWithDelayedArgs(Sema &S, Decl *D, ";
  OS << "const ParsedAttr &Attr) {\n";
  OS << "  SmallVector<Expr *, 4> ArgExprs;\n";
  OS << "  ArgExprs.reserve(Attr.getNumArgs());\n";
  OS << "  for (unsigned I = 0; I < Attr.getNumArgs(); ++I) {\n";
  OS << "    assert(!Attr.isArgIdent(I));\n";
  OS << "    ArgExprs.push_back(Attr.getArgAsExpr(I));\n";
  OS << "  }\n";
  OS << "  clang::Attr *CreatedAttr = nullptr;\n";
  OS << "  switch (Attr.getKind()) {\n";
  OS << "  default:\n";
  OS << "    llvm_unreachable(\"Attribute cannot hold delayed arguments.\");\n";
  ParsedAttrMap Attrs = getParsedAttrList(Records);
  for (const auto &I : Attrs) {
    const Record &R = *I.second;
    if (!R.getValueAsBit("AcceptsExprPack"))
      continue;
    OS << "  case ParsedAttr::AT_" << I.first << ": {\n";
    OS << "    CreatedAttr = " << R.getName() << "Attr::CreateWithDelayedArgs";
    OS << "(S.Context, ArgExprs.data(), ArgExprs.size(), Attr);\n";
    OS << "    break;\n";
    OS << "  }\n";
  }
  OS << "  }\n";
  OS << "  D->addAttr(CreatedAttr);\n";
  OS << "}\n\n";
}

static bool IsKnownToGCC(const Record &Attr) {
  // Look at the spellings for this subject; if there are any spellings which
  // claim to be known to GCC, the attribute is known to GCC.
  return any_of(GetFlattenedSpellings(Attr),
                [](const FlattenedSpelling &S) { return S.knownToGCC(); });
}

/// Emits the parsed attribute helpers
void EmitClangAttrParsedAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Parsed attribute helpers", OS, Records);

  OS << "#if !defined(WANT_DECL_MERGE_LOGIC) && "
     << "!defined(WANT_STMT_MERGE_LOGIC)\n";
  PragmaClangAttributeSupport &PragmaAttributeSupport =
      getPragmaAttributeSupport(Records);

  // Get the list of parsed attributes, and accept the optional list of
  // duplicates due to the ParseKind.
  ParsedAttrMap Dupes;
  ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes);

  // Generate all of the custom appertainsTo functions that the attributes
  // will be using.
  for (const auto &I : Attrs) {
    const Record &Attr = *I.second;
    if (Attr.isValueUnset("Subjects"))
      continue;
    const Record *SubjectObj = Attr.getValueAsDef("Subjects");
    for (const Record *Subject : SubjectObj->getValueAsListOfDefs("Subjects"))
      if (Subject->isSubClassOf("SubsetSubject"))
        GenerateCustomAppertainsTo(*Subject, OS);
  }

  // This stream is used to collect all of the declaration attribute merging
  // logic for performing mutual exclusion checks. This gets emitted at the
  // end of the file in a helper function of its own.
  std::string DeclMergeChecks, StmtMergeChecks;
  raw_string_ostream MergeDeclOS(DeclMergeChecks), MergeStmtOS(StmtMergeChecks);

  // Generate a ParsedAttrInfo struct for each of the attributes.
  for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
    // TODO: If the attribute's kind appears in the list of duplicates, that is
    // because it is a target-specific attribute that appears multiple times.
    // It would be beneficial to test whether the duplicates are "similar
    // enough" to each other to not cause problems. For instance, check that
    // the spellings are identical, and custom parsing rules match, etc.

    // We need to generate struct instances based off ParsedAttrInfo from
    // ParsedAttr.cpp.
    const std::string &AttrName = I->first;
    const Record &Attr = *I->second;
    auto Spellings = GetFlattenedSpellings(Attr);
    if (!Spellings.empty()) {
      OS << "static constexpr ParsedAttrInfo::Spelling " << I->first
         << "Spellings[] = {\n";
      for (const auto &S : Spellings) {
        StringRef RawSpelling = S.name();
        std::string Spelling;
        if (!S.nameSpace().empty())
          Spelling += S.nameSpace().str() + "::";
        if (S.variety() == "GNU")
          Spelling += NormalizeGNUAttrSpelling(RawSpelling);
        else
          Spelling += RawSpelling;
        OS << "  {AttributeCommonInfo::AS_" << S.variety();
        OS << ", \"" << Spelling << "\"},\n";
      }
      OS << "};\n";
    }

    std::vector<std::string> ArgNames;
    for (const auto *Arg : Attr.getValueAsListOfDefs("Args")) {
      bool UnusedUnset;
      if (Arg->getValueAsBitOrUnset("Fake", UnusedUnset))
        continue;
      ArgNames.push_back(Arg->getValueAsString("Name").str());
      for (const Record *Class : Arg->getSuperClasses()) {
        if (Class->getName().starts_with("Variadic")) {
          ArgNames.back().append("...");
          break;
        }
      }
    }
    if (!ArgNames.empty()) {
      OS << "static constexpr const char *" << I->first << "ArgNames[] = {\n";
      for (const auto &N : ArgNames)
        OS << '"' << N << "\",";
      OS << "};\n";
    }

    OS << "struct ParsedAttrInfo" << I->first
       << " final : public ParsedAttrInfo {\n";
    OS << "  constexpr ParsedAttrInfo" << I->first << "() : ParsedAttrInfo(\n";
    OS << "    /*AttrKind=*/ParsedAttr::AT_" << AttrName << ",\n";
    emitArgInfo(Attr, OS);
    OS << "    /*HasCustomParsing=*/";
    OS << Attr.getValueAsBit("HasCustomParsing") << ",\n";
    OS << "    /*AcceptsExprPack=*/";
    OS << Attr.getValueAsBit("AcceptsExprPack") << ",\n";
    OS << "    /*IsTargetSpecific=*/";
    OS << Attr.isSubClassOf("TargetSpecificAttr") << ",\n";
    OS << "    /*IsType=*/";
    OS << (Attr.isSubClassOf("TypeAttr") || Attr.isSubClassOf("DeclOrTypeAttr"))
       << ",\n";
    OS << "    /*IsStmt=*/";
    OS << (Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"))
       << ",\n";
    OS << "    /*IsKnownToGCC=*/";
    OS << IsKnownToGCC(Attr) << ",\n";
    OS << "    /*IsSupportedByPragmaAttribute=*/";
    OS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ",\n";
    if (!Spellings.empty())
      OS << "    /*Spellings=*/" << I->first << "Spellings,\n";
    else
      OS << "    /*Spellings=*/{},\n";
    if (!ArgNames.empty())
      OS << "    /*ArgNames=*/" << I->first << "ArgNames";
    else
      OS << "    /*ArgNames=*/{}";
    OS << ") {}\n";
    GenerateAppertainsTo(Attr, OS);
    GenerateMutualExclusionsChecks(Attr, Records, OS, MergeDeclOS, MergeStmtOS);
    GenerateLangOptRequirements(Attr, OS);
    GenerateTargetRequirements(Attr, Dupes, OS);
    GenerateSpellingTargetRequirements(
        Attr, Attr.getValueAsListOfDefs("TargetSpecificSpellings"), OS);
    GenerateSpellingIndexToSemanticSpelling(Attr, OS);
    PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
    GenerateHandleDeclAttribute(Attr, OS);
    GenerateIsParamExpr(Attr, OS);
    OS << "static const ParsedAttrInfo" << I->first << " Instance;\n";
    OS << "};\n";
    OS << "const ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first
       << "::Instance;\n";
  }

  OS << "static const ParsedAttrInfo *AttrInfoMap[] = {\n";
  for (const auto &Attr : Attrs)
    OS << "&ParsedAttrInfo" << Attr.first << "::Instance,\n";
  OS << "};\n\n";

  // Generate function for handling attributes with delayed arguments
  GenerateHandleAttrWithDelayedArgs(Records, OS);

  // Generate the attribute match rules.
  emitAttributeMatchRules(PragmaAttributeSupport, OS);

  OS << "#elif defined(WANT_DECL_MERGE_LOGIC)\n\n";

  // Write out the declaration merging check logic.
  OS << "static bool DiagnoseMutualExclusions(Sema &S, const NamedDecl *D, "
     << "const Attr *A) {\n";
  OS << DeclMergeChecks;
  OS << "  return true;\n";
  OS << "}\n\n";

  OS << "#elif defined(WANT_STMT_MERGE_LOGIC)\n\n";

  // Write out the statement merging check logic.
  OS << "static bool DiagnoseMutualExclusions(Sema &S, "
     << "const SmallVectorImpl<const Attr *> &C) {\n";
  OS << "  for (const Attr *A : C) {\n";
  OS << StmtMergeChecks;
  OS << "  }\n";
  OS << "  return true;\n";
  OS << "}\n\n";

  OS << "#endif\n";
}

// Emits the kind list of parsed attributes
void EmitClangAttrParsedAttrKinds(const RecordKeeper &Records,
                                  raw_ostream &OS) {
  emitSourceFileHeader("Attribute name matcher", OS, Records);

  std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11,
      Keywords, Pragma, C23, HLSLAnnotation;
  std::set<StringRef> Seen;
  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    const Record &Attr = *A;

    bool SemaHandler = Attr.getValueAsBit("SemaHandler");
    bool Ignored = Attr.getValueAsBit("Ignored");
    if (SemaHandler || Ignored) {
      // Attribute spellings can be shared between target-specific attributes,
      // and can be shared between syntaxes for the same attribute. For
      // instance, an attribute can be spelled GNU<"interrupt"> for an ARM-
      // specific attribute, or MSP430-specific attribute. Additionally, an
      // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport">
      // for the same semantic attribute. Ultimately, we need to map each of
      // these to a single AttributeCommonInfo::Kind value, but the
      // StringMatcher class cannot handle duplicate match strings. So we
      // generate a list of string to match based on the syntax, and emit
      // multiple string matchers depending on the syntax used.
      std::string AttrName;
      if (Attr.isSubClassOf("TargetSpecificAttr") &&
          !Attr.isValueUnset("ParseKind")) {
        StringRef ParseKind = Attr.getValueAsString("ParseKind");
        if (!Seen.insert(ParseKind).second)
          continue;
        AttrName = ParseKind.str();
      } else {
        AttrName = NormalizeAttrName(Attr.getName()).str();
      }

      std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
      for (const auto &S : Spellings) {
        StringRef RawSpelling = S.name();
        std::vector<StringMatcher::StringPair> *Matches = nullptr;
        std::string Spelling;
        StringRef Variety = S.variety();
        if (Variety == "CXX11") {
          Matches = &CXX11;
          if (!S.nameSpace().empty())
            Spelling += S.nameSpace().str() + "::";
        } else if (Variety == "C23") {
          Matches = &C23;
          if (!S.nameSpace().empty())
            Spelling += S.nameSpace().str() + "::";
        } else if (Variety == "GNU") {
          Matches = &GNU;
        } else if (Variety == "Declspec") {
          Matches = &Declspec;
        } else if (Variety == "Microsoft") {
          Matches = &Microsoft;
        } else if (Variety == "Keyword") {
          Matches = &Keywords;
        } else if (Variety == "Pragma") {
          Matches = &Pragma;
        } else if (Variety == "HLSLAnnotation") {
          Matches = &HLSLAnnotation;
          if (RawSpelling.compare(RawSpelling.lower()) != 0)
            PrintError(S.getSpellingRecord().getLoc(),
                       "HLSLAnnotation Attribute must be lower case.");
        }

        assert(Matches && "Unsupported spelling variety found");

        if (Variety == "GNU")
          Spelling += NormalizeGNUAttrSpelling(RawSpelling);
        else
          Spelling += RawSpelling;

        if (SemaHandler)
          Matches->push_back(StringMatcher::StringPair(
              Spelling, "return AttributeCommonInfo::AT_" + AttrName + ";"));
        else
          Matches->push_back(StringMatcher::StringPair(
              Spelling, "return AttributeCommonInfo::IgnoredAttribute;"));
      }
    }
  }

  OS << "static AttributeCommonInfo::Kind getAttrKind(StringRef Name, ";
  OS << "AttributeCommonInfo::Syntax Syntax) {\n";
  OS << "  if (AttributeCommonInfo::AS_GNU == Syntax) {\n";
  StringMatcher("Name", GNU, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_Declspec == Syntax) {\n";
  StringMatcher("Name", Declspec, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_Microsoft == Syntax) {\n";
  StringMatcher("Name", Microsoft, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_CXX11 == Syntax) {\n";
  StringMatcher("Name", CXX11, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_C23 == Syntax) {\n";
  StringMatcher("Name", C23, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_Keyword == Syntax || ";
  OS << "AttributeCommonInfo::AS_ContextSensitiveKeyword == Syntax) {\n";
  StringMatcher("Name", Keywords, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_Pragma == Syntax) {\n";
  StringMatcher("Name", Pragma, OS).Emit();
  OS << "  } else if (AttributeCommonInfo::AS_HLSLAnnotation == Syntax) {\n";
  StringMatcher("Name", HLSLAnnotation, OS).Emit();
  OS << "  }\n";
  OS << "  return AttributeCommonInfo::UnknownAttribute;\n"
     << "}\n";
}

// Emits the code to dump an attribute.
void EmitClangAttrTextNodeDump(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute text node dumper", OS, Records);

  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;

    // If the attribute has a semantically-meaningful name (which is determined
    // by whether there is a Spelling enumeration for it), then write out the
    // spelling used for the attribute.

    std::string FunctionContent;
    raw_string_ostream SS(FunctionContent);

    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
    if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings))
      SS << "    OS << \" \" << A->getSpelling();\n";

    std::vector<const Record *> Args = R.getValueAsListOfDefs("Args");
    for (const auto *Arg : Args)
      createArgument(*Arg, R.getName())->writeDump(SS);

    if (Attr->getValueAsBit("AcceptsExprPack"))
      VariadicExprArgument("DelayedArgs", R.getName()).writeDump(OS);

    if (SS.tell()) {
      OS << "  void Visit" << R.getName() << "Attr(const " << R.getName()
         << "Attr *A) {\n";
      if (!Args.empty())
        OS << "    const auto *SA = cast<" << R.getName()
           << "Attr>(A); (void)SA;\n";
      OS << FunctionContent;
      OS << "  }\n";
    }
  }
}

void EmitClangAttrNodeTraverse(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute text node traverser", OS, Records);

  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;

    std::string FunctionContent;
    raw_string_ostream SS(FunctionContent);

    std::vector<const Record *> Args = R.getValueAsListOfDefs("Args");
    for (const auto *Arg : Args)
      createArgument(*Arg, R.getName())->writeDumpChildren(SS);
    if (Attr->getValueAsBit("AcceptsExprPack"))
      VariadicExprArgument("DelayedArgs", R.getName()).writeDumpChildren(SS);
    if (SS.tell()) {
      OS << "  void Visit" << R.getName() << "Attr(const " << R.getName()
         << "Attr *A) {\n";
      if (!Args.empty())
        OS << "    const auto *SA = cast<" << R.getName()
           << "Attr>(A); (void)SA;\n";
      OS << FunctionContent;
      OS << "  }\n";
    }
  }
}

void EmitClangAttrParserStringSwitches(const RecordKeeper &Records,
                                       raw_ostream &OS) {
  generateNameToAttrsMap(Records);
  emitSourceFileHeader("Parser-related llvm::StringSwitch cases", OS, Records);
  emitClangAttrArgContextList(Records, OS);
  emitClangAttrIdentifierArgList(Records, OS);
  emitClangAttrUnevaluatedStringLiteralList(Records, OS);
  emitClangAttrVariadicIdentifierArgList(Records, OS);
  emitClangAttrThisIsaIdentifierArgList(Records, OS);
  emitClangAttrAcceptsExprPack(Records, OS);
  emitClangAttrTypeArgList(Records, OS);
  emitClangAttrLateParsedList(Records, OS);
  emitClangAttrLateParsedExperimentalList(Records, OS);
  emitClangAttrStrictIdentifierArgList(Records, OS);
}

void EmitClangAttrSubjectMatchRulesParserStringSwitches(
    const RecordKeeper &Records, raw_ostream &OS) {
  getPragmaAttributeSupport(Records).generateParsingHelpers(OS);
}

void EmitClangAttrDocTable(const RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Clang attribute documentation", OS, Records);

  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    if (!A->getValueAsBit("ASTNode"))
      continue;
    std::vector<const Record *> Docs = A->getValueAsListOfDefs("Documentation");
    assert(!Docs.empty());
    // Only look at the first documentation if there are several.
    // (Currently there's only one such attr, revisit if this becomes common).
    StringRef Text =
        Docs.front()->getValueAsOptionalString("Content").value_or("");
    OS << "\nstatic const char AttrDoc_" << A->getName() << "[] = "
       << "R\"reST(" << Text.trim() << ")reST\";\n";
  }
}

enum class SpellingKind : size_t {
  GNU,
  CXX11,
  C23,
  Declspec,
  Microsoft,
  Keyword,
  Pragma,
  HLSLAnnotation,
  NumSpellingKinds
};
static const size_t NumSpellingKinds = (size_t)SpellingKind::NumSpellingKinds;

class SpellingList {
  std::array<std::vector<std::string>, NumSpellingKinds> Spellings;

public:
  ArrayRef<std::string> operator[](SpellingKind K) const {
    return Spellings[(size_t)K];
  }

  void add(const Record &Attr, FlattenedSpelling Spelling) {
    SpellingKind Kind =
        StringSwitch<SpellingKind>(Spelling.variety())
            .Case("GNU", SpellingKind::GNU)
            .Case("CXX11", SpellingKind::CXX11)
            .Case("C23", SpellingKind::C23)
            .Case("Declspec", SpellingKind::Declspec)
            .Case("Microsoft", SpellingKind::Microsoft)
            .Case("Keyword", SpellingKind::Keyword)
            .Case("Pragma", SpellingKind::Pragma)
            .Case("HLSLAnnotation", SpellingKind::HLSLAnnotation);
    std::string Name;
    StringRef NameSpace = Spelling.nameSpace();
    if (!NameSpace.empty()) {
      Name = NameSpace;
      switch (Kind) {
      case SpellingKind::CXX11:
      case SpellingKind::C23:
        Name += "::";
        break;
      case SpellingKind::Pragma:
        Name = " ";
        break;
      default:
        PrintFatalError(Attr.getLoc(), "Unexpected namespace in spelling");
      }
    }
    Name += Spelling.name();

    Spellings[(size_t)Kind].push_back(Name);
  }

  void merge(const SpellingList &Other) {
    for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) {
      Spellings[Kind].insert(Spellings[Kind].end(),
                             Other.Spellings[Kind].begin(),
                             Other.Spellings[Kind].end());
    }
  }

  bool hasSpelling() const {
    return llvm::any_of(Spellings, [](const auto &L) { return !L.empty(); });
  }
};

class DocumentationData {
public:
  const Record *Documentation;
  const Record *Attribute;
  std::string Heading;
  SpellingList SupportedSpellings;

  DocumentationData(const Record &Documentation, const Record &Attribute,
                    std::pair<std::string, SpellingList> HeadingAndSpellings)
      : Documentation(&Documentation), Attribute(&Attribute),
        Heading(std::move(HeadingAndSpellings.first)),
        SupportedSpellings(std::move(HeadingAndSpellings.second)) {}
};

static void WriteCategoryHeader(const Record *DocCategory,
                                raw_ostream &OS) {
  const StringRef Name = DocCategory->getValueAsString("Name");
  OS << Name << "\n" << std::string(Name.size(), '=') << "\n";

  // If there is content, print that as well.
  const StringRef ContentStr = DocCategory->getValueAsString("Content");
  // Trim leading and trailing newlines and spaces.
  OS << ContentStr.trim();

  OS << "\n\n";
}

static std::pair<std::string, SpellingList>
GetAttributeHeadingAndSpellings(const Record &Documentation,
                                const Record &Attribute,
                                StringRef Cat) {
  // FIXME: there is no way to have a per-spelling category for the attribute
  // documentation. This may not be a limiting factor since the spellings
  // should generally be consistently applied across the category.

  if (Cat == "HLSL Semantics") {
    if (!Attribute.getName().starts_with("HLSL"))
      PrintFatalError(Attribute.getLoc(),
                      "HLSL semantic attribute name must start with HLSL");

    assert(Attribute.getName().size() > 4);
    std::string Name = Attribute.getName().substr(4).str();
    return std::make_pair(std::move(Name), SpellingList());
  }

  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
  if (Spellings.empty())
    PrintFatalError(Attribute.getLoc(),
                    "Attribute has no supported spellings; cannot be "
                    "documented");

  // Determine the heading to be used for this attribute.
  std::string Heading = Documentation.getValueAsString("Heading").str();
  if (Heading.empty()) {
    // If there's only one spelling, we can simply use that.
    if (Spellings.size() == 1)
      Heading = Spellings.begin()->name();
    else {
      std::set<std::string> Uniques;
      for (const FlattenedSpelling &FS : Spellings) {
        std::string Spelling =
            NormalizeNameForSpellingComparison(FS.name()).str();
        Uniques.insert(Spelling);
      }
      // If the semantic map has only one spelling, that is sufficient for our
      // needs.
      if (Uniques.size() == 1)
        Heading = *Uniques.begin();
      // If it's in the undocumented category, just construct a header by
      // concatenating all the spellings. Might not be great, but better than
      // nothing.
      else if (Cat == "Undocumented")
        Heading = join(Uniques.begin(), Uniques.end(), ", ");
    }
  }

  // If the heading is still empty, it is an error.
  if (Heading.empty())
    PrintFatalError(Attribute.getLoc(),
                    "This attribute requires a heading to be specified");

  SpellingList SupportedSpellings;
  for (const auto &I : Spellings)
    SupportedSpellings.add(Attribute, I);

  return std::make_pair(std::move(Heading), std::move(SupportedSpellings));
}

static void WriteDocumentation(const RecordKeeper &Records,
                               const DocumentationData &Doc, raw_ostream &OS) {
  if (StringRef Label = Doc.Documentation->getValueAsString("Label");
      !Label.empty())
    OS << ".. _" << Label << ":\n\n";
  OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n";

  if (Doc.SupportedSpellings.hasSpelling()) {
    // List what spelling syntaxes the attribute supports.
    // Note: "#pragma clang attribute" is handled outside the spelling kinds
    // loop so it must be last.
    OS << ".. csv-table:: Supported Syntaxes\n";
    OS << "   :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\",";
    OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma "
          "clang ";
    OS << "attribute``\"\n\n   \"";
    for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) {
      SpellingKind K = (SpellingKind)Kind;
      // TODO: List Microsoft (IDL-style attribute) spellings once we fully
      // support them.
      if (K == SpellingKind::Microsoft)
        continue;

      bool PrintedAny = false;
      for (StringRef Spelling : Doc.SupportedSpellings[K]) {
        if (PrintedAny)
          OS << " |br| ";
        OS << "``" << Spelling << "``";
        PrintedAny = true;
      }

      OS << "\",\"";
    }

    if (getPragmaAttributeSupport(Records).isAttributedSupported(
            *Doc.Attribute))
      OS << "Yes";
    OS << "\"\n\n";
  }

  // If the attribute is deprecated, print a message about it, and possibly
  // provide a replacement attribute.
  if (!Doc.Documentation->isValueUnset("Deprecated")) {
    OS << "This attribute has been deprecated, and may be removed in a future "
       << "version of Clang.";
    const Record &Deprecated = *Doc.Documentation->getValueAsDef("Deprecated");
    const StringRef Replacement = Deprecated.getValueAsString("Replacement");
    if (!Replacement.empty())
      OS << "  This attribute has been superseded by ``" << Replacement
         << "``.";
    OS << "\n\n";
  }

  const StringRef ContentStr = Doc.Documentation->getValueAsString("Content");
  // Trim leading and trailing newlines and spaces.
  OS << ContentStr.trim();

  OS << "\n\n\n";
}

void EmitClangAttrDocs(const RecordKeeper &Records, raw_ostream &OS) {
  // Get the documentation introduction paragraph.
  const Record *Documentation = Records.getDef("GlobalDocumentation");
  if (!Documentation) {
    PrintFatalError("The Documentation top-level definition is missing, "
                    "no documentation will be generated.");
    return;
  }

  OS << Documentation->getValueAsString("Intro") << "\n";

  // Gather the Documentation lists from each of the attributes, based on the
  // category provided.
  struct CategoryLess {
    bool operator()(const Record *L, const Record *R) const {
      return L->getValueAsString("Name") < R->getValueAsString("Name");
    }
  };

  std::map<const Record *, std::map<uint32_t, DocumentationData>, CategoryLess>
      MergedDocs;

  std::vector<DocumentationData> UndocumentedDocs;
  const Record *UndocumentedCategory = nullptr;

  // Collect documentation data, grouping by category and heading.
  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
    const Record &Attr = *A;
    std::vector<const Record *> Docs =
        Attr.getValueAsListOfDefs("Documentation");

    for (const auto *D : Docs) {
      const Record &Doc = *D;
      const Record *Category = Doc.getValueAsDef("Category");
      // If the category is "InternalOnly", then there cannot be any other
      // documentation categories (otherwise, the attribute would be
      // emitted into the docs).
      StringRef Cat = Category->getValueAsString("Name");
      if (Cat == "InternalOnly" && Docs.size() > 1)
        PrintFatalError(Doc.getLoc(),
                        "Attribute is \"InternalOnly\", but has multiple "
                        "documentation categories");

      if (Cat == "InternalOnly")
        continue;

      // Track the Undocumented category Record for later grouping
      if (Cat == "Undocumented" && !UndocumentedCategory)
        UndocumentedCategory = Category;

      // Generate Heading and Spellings.
      auto HeadingAndSpellings =
          GetAttributeHeadingAndSpellings(Doc, Attr, Cat);

      // Handle Undocumented category separately - no content merging
      if (Cat == "Undocumented" && UndocumentedCategory) {
        UndocumentedDocs.push_back(
            DocumentationData(Doc, Attr, std::move(HeadingAndSpellings)));
        continue;
      }

      auto &CategoryDocs = MergedDocs[Category];

      std::string key = Doc.getValueAsString("Content").str();
      uint32_t keyHash = llvm::hash_value(key);

      // If the content already exists, merge the documentation.
      auto It = CategoryDocs.find(keyHash);
      if (It != CategoryDocs.end()) {
        // Merge heading
        if (It->second.Heading != HeadingAndSpellings.first)
          It->second.Heading += ", " + HeadingAndSpellings.first;
        // Merge spellings
        It->second.SupportedSpellings.merge(HeadingAndSpellings.second);
        // Merge content
        It->second.Documentation = &Doc; // Update reference
      } else {
        // Create new entry for unique content
        CategoryDocs.emplace(keyHash,
                             DocumentationData(Doc, Attr, HeadingAndSpellings));
      }
    }
  }

  std::map<const Record *, std::vector<DocumentationData>, CategoryLess>
      SplitDocs;

  for (auto &CategoryPair : MergedDocs) {

    std::vector<DocumentationData> MD;
    for (auto &DocPair : CategoryPair.second)
      MD.push_back(std::move(DocPair.second));

    SplitDocs.emplace(CategoryPair.first, MD);
  }

  // Append Undocumented category entries
  if (!UndocumentedDocs.empty() && UndocumentedCategory) {
    SplitDocs.emplace(UndocumentedCategory, UndocumentedDocs);
  }

  // Having split the attributes out based on what documentation goes where,
  // we can begin to generate sections of documentation.
  for (auto &I : SplitDocs) {
    WriteCategoryHeader(I.first, OS);

    sort(I.second,
         [](const DocumentationData &D1, const DocumentationData &D2) {
           return D1.Heading < D2.Heading;
         });

    // Walk over each of the attributes in the category and write out their
    // documentation.
    for (const auto &Doc : I.second)
      WriteDocumentation(Records, Doc, OS);
  }
}

void EmitTestPragmaAttributeSupportedAttributes(const RecordKeeper &Records,
                                                raw_ostream &OS) {
  PragmaClangAttributeSupport Support = getPragmaAttributeSupport(Records);
  ParsedAttrMap Attrs = getParsedAttrList(Records);
  OS << "#pragma clang attribute supports the following attributes:\n";
  for (const auto &I : Attrs) {
    if (!Support.isAttributedSupported(*I.second))
      continue;
    OS << I.first;
    if (I.second->isValueUnset("Subjects")) {
      OS << " ()\n";
      continue;
    }
    const Record *SubjectObj = I.second->getValueAsDef("Subjects");
    OS << " (";
    ListSeparator LS;
    for (const auto &Subject :
         enumerate(SubjectObj->getValueAsListOfDefs("Subjects"))) {
      if (!isSupportedPragmaClangAttributeSubject(*Subject.value()))
        continue;
      OS << LS;
      PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet =
          Support.SubjectsToRules.find(Subject.value())->getSecond();
      if (RuleSet.isRule()) {
        OS << RuleSet.getRule().getEnumValueName();
        continue;
      }
      OS << "(";
      for (const auto &Rule : enumerate(RuleSet.getAggregateRuleSet())) {
        if (Rule.index())
          OS << ", ";
        OS << Rule.value().getEnumValueName();
      }
      OS << ")";
    }
    OS << ")\n";
  }
  OS << "End of supported attributes.\n";
}

} // end namespace clang
