//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
//
// 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/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/iterator_range.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 <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

namespace {

class FlattenedSpelling {
  std::string V, N, NS;
  bool K = false;

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

  const std::string &variety() const { return V; }
  const std::string &name() const { return N; }
  const std::string &nameSpace() const { return NS; }
  bool knownToGCC() const { return K; }
};

} // end anonymous namespace

static std::vector<FlattenedSpelling>
GetFlattenedSpellings(const Record &Attr) {
  std::vector<Record *> Spellings = Attr.getValueAsListOfDefs("Spellings");
  std::vector<FlattenedSpelling> Ret;

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

  return Ret;
}

static std::string ReadPCHRecord(StringRef type) {
  return StringSwitch<std::string>(type)
      .EndsWith("Decl *", "Record.GetLocalDeclAs<" +
                              std::string(type.data(), 0, type.size() - 1) +
                              ">(Record.readInt())")
      .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(" + std::string(name) + ");\n")
             .Case("TypeSourceInfo *",
                   "AddTypeSourceInfo(" + std::string(name) + ");\n")
             .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
             .Case("IdentifierInfo *",
                   "AddIdentifierRef(" + std::string(name) + ");\n")
             .Case("StringRef", "AddString(" + std::string(name) + ");\n")
             .Case("ParamIdx",
                   "push_back(" + std::string(name) + ".serialize());\n")
             .Case("OMPTraitInfo *",
                   "writeOMPTraitInfo(" + std::string(name) + ");\n")
             .Default("push_back(" + std::string(name) + ");\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.startswith("__") && AttrSpelling.endswith("__")) {
    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) {
  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
  std::set<std::string> Seen;
  ParsedAttrMap R;
  for (const auto *Attr : Attrs) {
    if (Attr->getValueAsBit("SemaHandler")) {
      std::string AN;
      if (Attr->isSubClassOf("TargetSpecificAttr") &&
          !Attr->isValueUnset("ParseKind")) {
        AN = std::string(Attr->getValueAsString("ParseKind"));

        // If this attribute has already been handled, it does not need to be
        // handled again.
        if (Seen.find(AN) != Seen.end()) {
          if (Dupes)
            Dupes->push_back(std::make_pair(AN, Attr));
          continue;
        }
        Seen.insert(AN);
      } 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(const Record &Arg, StringRef Attr)
        : lowerName(std::string(Arg.getValueAsString("Name"))),
          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_";
    }
    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" + std::string(getUpperName()) + "()");
    }

    std::string getIsOmitted() const override {
      if (type == "IdentifierInfo *")
        return "!get" + getUpperName().str() + "()";
      if (type == "TypeSourceInfo *")
        return "!get" + getUpperName().str() + "Loc()";
      if (type == "ParamIdx")
        return "!get" + getUpperName().str() + "().isValid()";
      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 == "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).endswith("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 << "  }";
    }

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

      // FIXME: Do not do the calculation here
      // FIXME: Handle types correctly
      // A null pointer means maximum alignment
      OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
         << "(ASTContext &Ctx) const {\n";
      OS << "  assert(!is" << getUpperName() << "Dependent());\n";
      OS << "  if (is" << getLowerName() << "Expr)\n";
      OS << "    return " << getLowerName() << "Expr ? " << getLowerName()
         << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue()"
         << " * Ctx.getCharWidth() : "
         << "Ctx.getTargetDefaultAlignForAttributeAligned();\n";
      OS << "  else\n";
      OS << "    return 0; // FIXME\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 << "};";
    }

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

    void writeValue(raw_ostream &OS) const override {
      OS << "\";\n";
      OS << "    " << getLowerName()
         << "Expr->printPretty(OS, nullptr, 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(std::string(getLowerName())) {}

    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 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 = std::string(getStorageType(getType()));
      std::string StorageName = std::string(getLowerName());
      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 << "  bool isFirst = true;\n"
         << "  for (const auto &Val : " << RangeName << "()) {\n"
         << "    if (isFirst) isFirst = false;\n"
         << "    else OS << \", \";\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 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 type;
    std::vector<StringRef> values, enums, uniques;

  public:
    EnumArgument(const Record &Arg, StringRef Attr)
        : Argument(Arg, Attr), type(std::string(Arg.getValueAsString("Type"))),
          values(Arg.getValueAsListOfStrings("Values")),
          enums(Arg.getValueAsListOfStrings("Enums")),
          uniques(uniqueEnumsInOrder(enums)) {
      // FIXME: Emit a proper error
      assert(!uniques.empty());
    }

    bool isEnumArg() const override { return true; }

    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() << "(" << type << "(0))";
    }
    void writeCtorParameters(raw_ostream &OS) const override {
      OS << type << " " << getUpperName();
    }
    void writeDeclarations(raw_ostream &OS) const override {
      auto i = uniques.cbegin(), e = uniques.cend();
      // The last one needs to not have a comma.
      --e;

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

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

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

    void writePCHWrite(raw_ostream &OS) const override {
      OS << "Record.push_back(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" << type << "ToStr(get"
         << getUpperName() << "()) << \"\\\"";
    }

    void writeDump(raw_ostream &OS) const override {
      OS << "    switch(SA->get" << getUpperName() << "()) {\n";
      for (const auto &I : uniques) {
        OS << "    case " << getAttrName() << "Attr::" << I << ":\n";
        OS << "      OS << \" " << I << "\";\n";
        OS << "      break;\n";
      }
      OS << "    }\n";
    }

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

      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << type
         << "(StringRef Val, " << type << " &Out) {\n";
      OS << "  Optional<" << type << "> R = llvm::StringSwitch<Optional<";
      OS << type << ">>(Val)\n";
      for (size_t I = 0; I < enums.size(); ++I) {
        OS << "    .Case(\"" << values[I] << "\", ";
        OS << getAttrName() << "Attr::" << enums[I] << ")\n";
      }
      OS << "    .Default(Optional<" << type << ">());\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" << type
         << "ToStr(" << type << " 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 " << getAttrName() << "Attr::" << enums[I]
             << ": return \"" << values[I] << "\";\n";
      }
      OS << "  }\n"
         << "  llvm_unreachable(\"No enumerator with that value\");\n"
         << "}\n";
    }
  };

  class VariadicEnumArgument: public VariadicArgument {
    std::string type, QualifiedTypeName;
    std::vector<StringRef> values, enums, uniques;

  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" << type
         << "ToStr(Val)" << "<< \"\\\"\";\n";
    }

  public:
    VariadicEnumArgument(const Record &Arg, StringRef Attr)
        : VariadicArgument(Arg, Attr,
                           std::string(Arg.getValueAsString("Type"))),
          type(std::string(Arg.getValueAsString("Type"))),
          values(Arg.getValueAsListOfStrings("Values")),
          enums(Arg.getValueAsListOfStrings("Enums")),
          uniques(uniqueEnumsInOrder(enums)) {
      QualifiedTypeName = getAttrName().str() + "Attr::" + type;

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

    bool isVariadicEnumArg() const override { return true; }

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

      OS << "public:\n";
      OS << "  enum " << type << " {\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 " << getAttrName() << "Attr::" << UI << ":\n";
        OS << "      OS << \" " << UI << "\";\n";
        OS << "      break;\n";
      }
      OS << "      }\n";
      OS << "    }\n";
    }

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

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

      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << type
         << "(StringRef Val, ";
      OS << type << " &Out) {\n";
      OS << "  Optional<" << type << "> R = llvm::StringSwitch<Optional<";
      OS << type << ">>(Val)\n";
      for (size_t I = 0; I < enums.size(); ++I) {
        OS << "    .Case(\"" << values[I] << "\", ";
        OS << getAttrName() << "Attr::" << enums[I] << ")\n";
      }
      OS << "    .Default(Optional<" << type << ">());\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" << type
         << "ToStr(" << type << " 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 " << getAttrName() << "Attr::" << enums[I]
             << ": return \"" << values[I] << "\";\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 << "        tempInst" << getUpperName() << " = "
         << "Result.getAs<Expr>();\n";
      OS << "      }\n";
    }

    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 *")
    {}

    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() << ", "
         << "A->" << getLowerName() << "_size()";
    }

    void writeTemplateInstantiation(raw_ostream &OS) const override {
      OS << "      auto *tempInst" << getUpperName()
         << " = new (C, 16) " << getType()
         << "[A->" << getLowerName() << "_size()];\n";
      OS << "      {\n";
      OS << "        EnterExpressionEvaluationContext "
         << "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n";
      OS << "        " << getType() << " *TI = tempInst" << getUpperName()
         << ";\n";
      OS << "        " << getType() << " *I = A->" << getLowerName()
         << "_begin();\n";
      OS << "        " << getType() << " *E = A->" << getLowerName()
         << "_end();\n";
      OS << "        for (; I != E; ++I, ++TI) {\n";
      OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
      OS << "          *TI = Result.getAs<Expr>();\n";
      OS << "        }\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 writeTemplateInstantiationArgs(raw_ostream &OS) const override {
      OS << "A->get" << getUpperName() << "Loc()";
    }

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

} // 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;
  llvm::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 == "OMPTraitInfoArgument")
    Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "OMPTraitInfo *");

  if (!Ptr) {
    // Search in reverse order so that the most-derived type is handled first.
    ArrayRef<std::pair<Record*, SMRange>> Bases = Search->getSuperClasses();
    for (const auto &Base : llvm::reverse(Bases)) {
      if ((Ptr = createArgument(Arg, Attr, Base.first)))
        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, std::string &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 (unsigned I = 0; I < Spellings.size(); ++I)
    OS << "  case " << I << ":\n"
          "    return \"" << Spellings[I].name() << "\";\n";
  // 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 << "  switch (getAttributeSpellingListIndex()) {\n"
        "  default:\n"
        "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
        "    break;\n";

  for (unsigned I = 0; I < Spellings.size(); ++ I) {
    llvm::SmallString<16> Prefix;
    llvm::SmallString<8> Suffix;
    // The actual spelling of the name and namespace (if applicable)
    // of an attribute without considering prefix and suffix.
    llvm::SmallString<64> Spelling;
    std::string Name = Spellings[I].name();
    std::string Variety = Spellings[I].variety();

    if (Variety == "GNU") {
      Prefix = " __attribute__((";
      Suffix = "))";
    } else if (Variety == "CXX11" || Variety == "C2x") {
      Prefix = " [[";
      Suffix = "]]";
      std::string Namespace = Spellings[I].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";
      std::string Namespace = Spellings[I].nameSpace();
      if (!Namespace.empty()) {
        Spelling += Namespace;
        Spelling += " ";
      }
    } else {
      llvm_unreachable("Unknown attribute syntax variety!");
    }

    Spelling += Name;

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

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

    if (Spelling == "availability") {
      OS << "(";
      writeAvailabilityValue(OS);
      OS << ")";
    } else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") {
      OS << "(";
      writeDeprecatedAttrValue(OS, Variety);
      OS << ")";
    } 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.
      unsigned NonFakeArgs = 0;
      unsigned TrailingOptArgs = 0;
      bool FoundNonOptArg = false;
      for (const auto &arg : llvm::reverse(Args)) {
        if (arg->isFake())
          continue;
        ++NonFakeArgs;
        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;
        }
        if (!TrailingOptArgs++)
          OS << "\";\n"
             << "    unsigned TrailingOmittedArgs = 0;\n";
        OS << "    if (" << arg->getIsOmitted() << ")\n"
           << "      ++TrailingOmittedArgs;\n";
      }
      if (TrailingOptArgs)
        OS << "    OS << \"";
      if (TrailingOptArgs < NonFakeArgs)
        OS << "(";
      else if (TrailingOptArgs)
        OS << "\";\n"
           << "    if (TrailingOmittedArgs < " << NonFakeArgs << ")\n"
           << "       OS << \"(\";\n"
           << "    OS << \"";
      unsigned ArgIndex = 0;
      for (const auto &arg : Args) {
        if (arg->isFake())
          continue;
        if (ArgIndex) {
          if (ArgIndex >= NonFakeArgs - TrailingOptArgs)
            OS << "\";\n"
               << "    if (" << ArgIndex << " < " << NonFakeArgs
               << " - TrailingOmittedArgs)\n"
               << "      OS << \", \";\n"
               << "    OS << \"";
          else
            OS << ", ";
        }
        std::string IsOmitted = arg->getIsOmitted();
        if (arg->isOptional() && IsOmitted != "false")
          OS << "\";\n"
             << "    if (!(" << IsOmitted << ")) {\n"
             << "      OS << \"";
        arg->writeValue(OS);
        if (arg->isOptional() && IsOmitted != "false")
          OS << "\";\n"
             << "    }\n"
             << "    OS << \"";
        ++ArgIndex;
      }
      if (TrailingOptArgs < NonFakeArgs)
        OS << ")";
      else if (TrailingOptArgs)
        OS << "\";\n"
           << "    if (TrailingOmittedArgs < " << NonFakeArgs << ")\n"
           << "       OS << \")\";\n"
           << "    OS << \"";
    }

    OS << Suffix + "\";\n";

    OS <<
      "    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(const std::vector<FlattenedSpelling> &SpellingList,
                     const FlattenedSpelling &Spelling) {
  assert(!SpellingList.empty() && "Spelling list is empty!");

  for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
    const FlattenedSpelling &S = SpellingList[Index];
    if (S.variety() != Spelling.variety())
      continue;
    if (S.nameSpace() != Spelling.nameSpace())
      continue;
    if (S.name() != Spelling.name())
      continue;

    return Index;
  }

  llvm_unreachable("Unknown spelling!");
}

static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
  std::vector<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");
  std::string FirstName =
      std::string(NormalizeNameForSpellingComparison(Spellings.front().name()));
  for (const auto &Spelling :
       llvm::make_range(std::next(Spellings.begin()), Spellings.end())) {
    std::string Name =
        std::string(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;
    const std::string &Variety = S.variety();
    const std::string &Spelling = S.name();
    const std::string &Namespace = S.nameSpace();
    std::string EnumName;

    EnumName += (Variety + "_");
    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.find(EnumName) != Uniques.end())
      continue;

    Uniques.insert(EnumName);
    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 + " = " + llvm::utostr(Idx);
  }
  Ret += ",\n  SpellingNotCalculated = 15\n";
  Ret += "\n  };\n\n";
  return Ret;
}

void WriteSemanticSpellingSwitch(const std::string &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";
}

// Emits the LateParsed property for attributes.
static void emitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n";
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");

  for (const auto *Attr : Attrs) {
    bool LateParsed = Attr->getValueAsBit("LateParsed");

    if (LateParsed) {
      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() << "\", " << LateParsed << ")\n";
      }
    }
  }
  OS << "#endif // CLANG_ATTR_LATE_PARSED_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<Record *> getSubjects() const {
    return (Constraint ? Constraint : MetaSubject)
        ->getValueAsListOfDefs("Subjects");
  }

  std::vector<Record *> getLangOpts() const {
    if (Constraint) {
      // Lookup the options in the sub-rule first, in case the sub-rule
      // overrides the rules options.
      std::vector<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 = std::string(MetaSubject->getValueAsString("Name"));
    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.str());
  }

  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);
    }
  };
  llvm::DenseMap<const Record *, RuleOrAggregateRuleSet> SubjectsToRules;

  PragmaClangAttributeSupport(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 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(
    RecordKeeper &Records) {
  std::vector<Record *> MetaSubjects =
      Records.getAllDerivedDefinitions("AttrSubjectMatcherRule");
  auto MapFromSubjectsToRules = [this](const Record *SubjectContainer,
                                       const Record *MetaSubject,
                                       const Record *Constraint) {
    Rules.emplace_back(MetaSubject, Constraint);
    std::vector<Record *> ApplicableSubjects =
        SubjectContainer->getValueAsListOfDefs("Subjects");
    for (const auto *Subject : ApplicableSubjects) {
      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 : MetaSubjects) {
    MapFromSubjectsToRules(MetaSubject, MetaSubject, /*Constraints=*/nullptr);
    std::vector<Record *> Constraints =
        MetaSubject->getValueAsListOfDefs("Constraints");
    for (const auto *Constraint : Constraints)
      MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
  }

  std::vector<Record *> Aggregates =
      Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule");
  std::vector<Record *> DeclNodes =
    Records.getAllDerivedDefinitions(DeclNodeClassName);
  for (const auto *Aggregate : Aggregates) {
    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(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)
  if (Attribute.getValueAsBit("LateParsed"))
    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");
  std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
  if (Subjects.empty())
    return false;
  for (const auto *Subject : Subjects) {
    if (SubjectsToRules.find(Subject) == SubjectsToRules.end())
      return false;
  }
  return true;
}

static std::string GenerateTestExpression(ArrayRef<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");
  std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
  for (const auto *Subject : Subjects) {
    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<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 << "Optional<attr::SubjectMatchRule> "
        "defaultIsAttributeSubjectMatchSubRuleFor(StringRef, bool) {\n";
  OS << "  return None;\n";
  OS << "}\n\n";

  std::map<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 << "Optional<attr::SubjectMatchRule> isAttributeSubjectMatchSubRuleFor_"
       << SubMatchRule.first->getValueAsString("Name")
       << "(StringRef Name, bool IsUnless) {\n";
    OS << "  if (IsUnless)\n";
    OS << "    return "
          "llvm::StringSwitch<Optional<attr::SubjectMatchRule>>(Name).\n";
    for (const auto &Rule : SubMatchRule.second) {
      if (Rule.isNegatedSubRule())
        OS << "    Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
           << ").\n";
    }
    OS << "    Default(None);\n";
    OS << "  return "
          "llvm::StringSwitch<Optional<attr::SubjectMatchRule>>(Name).\n";
    for (const auto &Rule : SubMatchRule.second) {
      if (!Rule.isNegatedSubRule())
        OS << "  Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
           << ").\n";
    }
    OS << "  Default(None);\n";
    OS << "}\n\n";
  }

  // Generate the function that checks for the top-level rules.
  OS << "std::pair<Optional<attr::SubjectMatchRule>, "
        "Optional<attr::SubjectMatchRule> (*)(StringRef, "
        "bool)> isAttributeSubjectMatchRule(StringRef Name) {\n";
  OS << "  return "
        "llvm::StringSwitch<std::pair<Optional<attr::SubjectMatchRule>, "
        "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(None, "
        "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 forEachUniqueSpelling(const Record &Attr, Fn &&F) {
  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
  SmallDenseSet<StringRef, 8> Seen;
  for (const FlattenedSpelling &S : Spellings) {
    if (Seen.insert(S.name()).second)
      F(S);
  }
}

/// Emits the first-argument-is-type property for attributes.
static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");

  for (const auto *Attr : Attrs) {
    // Determine whether the first argument is a type.
    std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
    if (Args.empty())
      continue;

    if (Args[0]->getSuperClasses().back().first->getName() != "TypeArgument")
      continue;

    // All these spellings take a single type argument.
    forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
      OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
    });
  }
  OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
}

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

    if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
      continue;

    // All these spellings take are parsed unevaluated.
    forEachUniqueSpelling(Attr, [&](const FlattenedSpelling &S) {
      OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
    });
  }
  OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
}

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

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

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

    // All these spellings take an identifier argument.
    forEachUniqueSpelling(*A, [&](const FlattenedSpelling &S) {
      OS << ".Case(\"" << S.name() << "\", "
         << "true"
         << ")\n";
    });
  }
  OS << "#endif // CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST\n\n";
}

// Emits the first-argument-is-identifier property for attributes.
static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
  OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n";
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");

  for (const auto *Attr : Attrs) {
    // Determine whether the first argument is an identifier.
    std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
    if (Args.empty() || !isIdentifierArgument(Args[0]))
      continue;

    // All these spellings take an identifier argument.
    forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
      OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
    });
  }
  OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
}

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

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

    // All these spellings take an identifier argument.
    forEachUniqueSpelling(*A, [&](const FlattenedSpelling &S) {
      OS << ".Case(\"" << S.name() << "\", "
         << "true"
         << ")\n";
    });
  }
  OS << "#endif // CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST\n\n";
}

static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
                           bool Header) {
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
  ParsedAttrMap AttrMap = getParsedAttrList(Records);

  for (const auto *Attr : Attrs) {
    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;

    ArrayRef<std::pair<Record *, SMRange>> Supers = R.getSuperClasses();
    assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
    std::string SuperName;
    bool Inheritable = false;
    for (const auto &Super : llvm::reverse(Supers)) {
      const Record *R = Super.first;
      if (R->getName() != "TargetSpecificAttr" &&
          R->getName() != "DeclOrTypeAttr" && SuperName.empty())
        SuperName = std::string(R->getName());
      if (R->getName() == "InheritableAttr")
        Inheritable = true;
    }

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

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

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

    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 = llvm::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 emitFake) {
      if (Header)
        OS << "  static ";
      OS << R.getName() << "Attr *";
      if (!Header)
        OS << R.getName() << "Attr::";
      OS << "Create";
      if (Implicit)
        OS << "Implicit";
      OS << "(";
      OS << "ASTContext &Ctx";
      for (auto const &ai : Args) {
        if (ai->isFake() && !emitFake) continue;
        OS << ", ";
        ai->writeCtorParameters(OS);
      }
      OS << ", const AttributeCommonInfo &CommonInfo";
      if (Header)
        OS << " = {SourceRange{}}";
      OS << ")";
      if (Header) {
        OS << ";\n";
        return;
      }

      OS << " {\n";
      OS << "  auto *A = new (Ctx) " << R.getName();
      OS << "Attr(Ctx, CommonInfo";
      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";
      }
      OS << "  return A;\n}\n\n";
    };

    auto emitCreateNoCI = [&](bool Implicit, bool emitFake) {
      if (Header)
        OS << "  static ";
      OS << R.getName() << "Attr *";
      if (!Header)
        OS << R.getName() << "Attr::";
      OS << "Create";
      if (Implicit)
        OS << "Implicit";
      OS << "(";
      OS << "ASTContext &Ctx";
      for (auto const &ai : Args) {
        if (ai->isFake() && !emitFake) continue;
        OS << ", ";
        ai->writeCtorParameters(OS);
      }
      OS << ", SourceRange Range, AttributeCommonInfo::Syntax Syntax";
      if (!ElideSpelling) {
        OS << ", " << R.getName() << "Attr::Spelling S";
        if (Header)
          OS << " = static_cast<Spelling>(SpellingNotCalculated)";
      }
      OS << ")";
      if (Header) {
        OS << ";\n";
        return;
      }

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

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

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

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

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

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

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

    // Emit constructors.
    auto emitCtor = [&](bool emitOpt, bool emitFake) {
      auto shouldEmitArg = [=](const std::unique_ptr<Argument> &arg) {
        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() << ", "
         << (R.getValueAsBit("LateParsed") ? "true" : "false");
      if (Inheritable) {
        OS << ", "
           << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
                                                              : "false");
      }
      OS << ")\n";

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

      OS << "  {\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);

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

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

    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) {
      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 {
      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";
      OS << "  return A;\n}\n\n";

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

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

  emitAttributes(Records, OS, true);

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

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

  emitAttributes(Records, OS, false);

  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");

  // 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 : Attrs) {
      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,
                         const std::vector<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 llvm::find_if(Spellings, [](const FlattenedSpelling &S) {
           return S.variety() == "Pragma";
         }) != Spellings.end();
}

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" },
  { "INHERITABLE_ATTR", "InheritableAttr" },
  { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" },
  { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
  { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
};

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;
    Record *TheRecord;
    AttrClass *SuperClass = nullptr;
    std::vector<AttrClass*> SubClasses;
    std::vector<Record*> Attrs;

    AttrClass(const AttrClassDescriptor &Descriptor, 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(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(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;
    }

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

    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(RecordKeeper &Records) {
      // Find records for all the classes.
      for (auto &Descriptor : AttrClassDescriptors) {
        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(Record *Attr) {
      // Add the attribute to the root class.
      Classes[0]->classifyAttrOnRoot(Attr);
    }

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

    AttrClass *findSuperClass(Record *R) const {
      // TableGen flattens the superclass list, so we just need to walk it
      // in reverse.
      auto SuperClasses = R->getSuperClasses();
      for (signed i = 0, e = SuperClasses.size(); i != e; ++i) {
        auto SuperClass = findClassByRecord(SuperClasses[e - i - 1].first);
        if (SuperClass) return SuperClass;
      }
      return nullptr;
    }
  };

} // end anonymous namespace

namespace clang {

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

  AttrClassHierarchy Hierarchy(Records);

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

  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
  std::vector<Record *> PragmaAttrs;
  for (auto *Attr : Attrs) {
    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(RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader(
      "List of all attribute subject matching rules that Clang recognizes", OS);
  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(RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Attribute deserialization code", OS);

  Record *InhClass = Records.getClass("InheritableAttr");
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
                       ArgRecords;
  std::vector<std::unique_ptr<Argument>> Args;

  OS << "  switch (Kind) {\n";
  for (const auto *Attr : Attrs) {
    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";
    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";
    OS << "    break;\n";
    OS << "  }\n";
  }
  OS << "  }\n";
}

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

  Record *InhClass = Records.getClass("InheritableAttr");
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;

  OS << "  switch (A->getKind()) {\n";
  for (const auto *Attr : Attrs) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;
    OS << "  case attr::" << R.getName() << ": {\n";
    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";

    for (const auto *Arg : Args)
      createArgument(*Arg, R.getName())->writePCHWrite(OS);
    OS << "    break;\n";
    OS << "  }\n";
  }
  OS << "  }\n";
}

// 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 llvm::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(
    const std::vector<Record *> &Attrs, raw_ostream &OS,
    const std::string &Variety = "", const std::string &Scope = "") {
  for (const auto *Attr : 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
    int Version = 1;

    if (Variety == "CXX11") {
        std::vector<Record *> Spellings = Attr->getValueAsListOfDefs("Spellings");
        for (const auto &Spelling : Spellings) {
          if (Spelling->getValueAsString("Variety") == "CXX11") {
            Version = static_cast<int>(Spelling->getValueAsInt("Version"));
            if (Scope.empty() && Version == 1)
              PrintError(Spelling->getLoc(), "C++ standard attributes must "
              "have valid version information.");
            break;
          }
      }
    }

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

      // If this is the C++11 variety, also add in the LangOpts test.
      if (Variety == "CXX11")
        Test += " && LangOpts.CPlusPlus11";
      else if (Variety == "C2x")
        Test += " && LangOpts.DoubleSquareBracketAttributes";
    } else if (Variety == "CXX11")
      // C++11 mode should be checked against LangOpts, which is presumed to be
      // present in the caller.
      Test = "LangOpts.CPlusPlus11";
    else if (Variety == "C2x")
      Test = "LangOpts.DoubleSquareBracketAttributes";

    std::string TestStr =
        !Test.empty() ? Test + " ? " + llvm::itostr(Version) + " : 0" : "1";
    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
    for (const auto &S : Spellings)
      if (Variety.empty() || (Variety == S.variety() &&
                              (Scope.empty() || Scope == S.nameSpace())))
        OS << "    .Case(\"" << S.name() << "\", " << TestStr << ")\n";
  }
  OS << "    .Default(0);\n";
}

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

  // 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.
  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
  std::vector<Record *> Declspec, Microsoft, GNU, Pragma;
  std::map<std::string, std::vector<Record *>> CXX, C2x;

  // Walk over the list of all attributes, and split them out based on the
  // spelling variety.
  for (auto *R : Attrs) {
    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
    for (const auto &SI : Spellings) {
      const std::string &Variety = SI.variety();
      if (Variety == "GNU")
        GNU.push_back(R);
      else if (Variety == "Declspec")
        Declspec.push_back(R);
      else if (Variety == "Microsoft")
        Microsoft.push_back(R);
      else if (Variety == "CXX11")
        CXX[SI.nameSpace()].push_back(R);
      else if (Variety == "C2x")
        C2x[SI.nameSpace()].push_back(R);
      else if (Variety == "Pragma")
        Pragma.push_back(R);
    }
  }

  OS << "const llvm::Triple &T = Target.getTriple();\n";
  OS << "switch (Syntax) {\n";
  OS << "case AttrSyntax::GNU:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU");
  OS << "case AttrSyntax::Declspec:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
  OS << "case AttrSyntax::Microsoft:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(Microsoft, OS, "Microsoft");
  OS << "case AttrSyntax::Pragma:\n";
  OS << "  return llvm::StringSwitch<int>(Name)\n";
  GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
  auto fn = [&OS](const char *Spelling, const char *Variety,
                  const std::map<std::string, std::vector<Record *>> &List) {
    OS << "case AttrSyntax::" << Variety << ": {\n";
    // C++11-style attributes are further split out based on the Scope.
    for (auto I = List.cbegin(), E = List.cend(); I != E; ++I) {
      if (I != List.cbegin())
        OS << " else ";
      if (I->first.empty())
        OS << "if (ScopeName == \"\") {\n";
      else
        OS << "if (ScopeName == \"" << I->first << "\") {\n";
      OS << "  return llvm::StringSwitch<int>(Name)\n";
      GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first);
      OS << "}";
    }
    OS << "\n} break;\n";
  };
  fn("CXX11", "CXX", CXX);
  fn("C2x", "C", C2x);
  OS << "}\n";
}

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

  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";
    for (unsigned I = 0; I < Spellings.size(); ++ I) {
      OS << "    if (Name == \"" << Spellings[I].name() << "\" && "
         << "getSyntax() == AttributeCommonInfo::AS_" << Spellings[I].variety()
         << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
         << "        return " << I << ";\n";
    }

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

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

// Emits code used by RecursiveASTVisitor to visit attributes
void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS);

  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");

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

    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
    for (const auto *Arg : ArgRecords)
      createArgument(*Arg, 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";
}

void EmitClangAttrTemplateInstantiateHelper(const std::vector<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<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(RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("Template instantiation code for attributes", OS);

  std::vector<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(RecordKeeper &Records, raw_ostream &OS) {
  emitSourceFileHeader("List of all attributes that Clang recognizes", OS);

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

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.
  std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
  unsigned ArgCount = 0, OptCount = 0;
  bool HasVariadic = false;
  for (const auto *Arg : 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;
    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";
}

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

  // 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;
  std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
  for (const auto *Subject : 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;
      llvm::SplitString(V, Frags, ",");
      for (auto Str : Frags) {
        DiagList.push_back(std::string(Str.trim()));
      }
    }
  }

  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 = llvm::join(DiagList.begin(), DiagList.end() - 1, ", ");
  return '"' + Diag + ", and " + *(DiagList.end() - 1) + '"';
}

static std::string GetSubjectWithSuffix(const Record *R) {
  const std::string &B = std::string(R->getName());
  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.
  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<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");

  // Otherwise, generate an appertainsTo check specific to this attribute which
  // checks all of the given subjects against the Decl passed in.
  //
  // If D is null, that means the attribute was not applied to a declaration
  // at all (for instance because it was applied to a type), or that the caller
  // has determined that the check should fail (perhaps prior to the creation
  // of the declaration).
  OS << "bool diagAppertainsToDecl(Sema &S, ";
  OS << "const ParsedAttr &Attr, const Decl *D) const override {\n";
  OS << "  if (";
  for (auto I = Subjects.begin(), E = Subjects.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 << ";
  OS << CalculateDiagnostic(*SubjectObj) << ";\n";
  OS << "    return false;\n";
  OS << "  }\n";
  OS << "  return true;\n";
  OS << "}\n\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<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<Record *> LangOpts = R.getValueAsListOfDefs("LangOpts");
  if (LangOpts.empty())
    return;

  OS << "bool diagLangOpts(Sema &S, const ParsedAttr &Attr) ";
  OS << "const override {\n";
  OS << "  auto &LangOpts = S.LangOpts;\n";
  OS << "  if (" << GenerateTestExpression(LangOpts) << ")\n";
  OS << "    return true;\n\n";
  OS << "  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) ";
  OS << "<< Attr;\n";
  OS << "  return false;\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");
        Arches.insert(Arches.end(), DA.begin(), DA.end());
      }
    }
  }

  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 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);
  std::string Name = Attr.getName().str() + "AttrSpellingMap";

  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 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 llvm::any_of(
      GetFlattenedSpellings(Attr),
      [](const FlattenedSpelling &S) { return S.knownToGCC(); });
}

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

  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 (auto I : Attrs) {
    const Record &Attr = *I.second;
    if (Attr.isValueUnset("Subjects"))
      continue;
    const Record *SubjectObj = Attr.getValueAsDef("Subjects");
    for (auto Subject : SubjectObj->getValueAsListOfDefs("Subjects"))
      if (Subject->isSubClassOf("SubsetSubject"))
        GenerateCustomAppertainsTo(*Subject, OS);
  }

  // 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) {
        const std::string &RawSpelling = S.name();
        std::string Spelling;
        if (!S.nameSpace().empty())
          Spelling += S.nameSpace() + "::";
        if (S.variety() == "GNU")
          Spelling += NormalizeGNUAttrSpelling(RawSpelling);
        else
          Spelling += RawSpelling;
        OS << "  {AttributeCommonInfo::AS_" << S.variety();
        OS << ", \"" << Spelling << "\"},\n";
      }
      OS << "};\n";
    }
    OS << "struct ParsedAttrInfo" << I->first
       << " final : public ParsedAttrInfo {\n";
    OS << "  ParsedAttrInfo" << I->first << "() {\n";
    OS << "    AttrKind = ParsedAttr::AT_" << AttrName << ";\n";
    emitArgInfo(Attr, OS);
    OS << "    HasCustomParsing = ";
    OS << Attr.getValueAsBit("HasCustomParsing") << ";\n";
    OS << "    IsTargetSpecific = ";
    OS << Attr.isSubClassOf("TargetSpecificAttr") << ";\n";
    OS << "    IsType = ";
    OS << (Attr.isSubClassOf("TypeAttr") ||
           Attr.isSubClassOf("DeclOrTypeAttr")) << ";\n";
    OS << "    IsStmt = ";
    OS << Attr.isSubClassOf("StmtAttr") << ";\n";
    OS << "    IsKnownToGCC = ";
    OS << IsKnownToGCC(Attr) << ";\n";
    OS << "    IsSupportedByPragmaAttribute = ";
    OS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ";\n";
    if (!Spellings.empty())
      OS << "    Spellings = " << I->first << "Spellings;\n";
    OS << "  }\n";
    GenerateAppertainsTo(Attr, OS);
    GenerateLangOptRequirements(Attr, OS);
    GenerateTargetRequirements(Attr, Dupes, OS);
    GenerateSpellingIndexToSemanticSpelling(Attr, OS);
    PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
    GenerateHandleDeclAttribute(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 (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
    OS << "&ParsedAttrInfo" << I->first << "::Instance,\n";
  }
  OS << "};\n\n";

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

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

  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
  std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11,
      Keywords, Pragma, C2x;
  std::set<std::string> Seen;
  for (const auto *A : Attrs) {
    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")) {
        AttrName = std::string(Attr.getValueAsString("ParseKind"));
        if (Seen.find(AttrName) != Seen.end())
          continue;
        Seen.insert(AttrName);
      } else
        AttrName = NormalizeAttrName(StringRef(Attr.getName())).str();

      std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
      for (const auto &S : Spellings) {
        const std::string &RawSpelling = S.name();
        std::vector<StringMatcher::StringPair> *Matches = nullptr;
        std::string Spelling;
        const std::string &Variety = S.variety();
        if (Variety == "CXX11") {
          Matches = &CXX11;
          if (!S.nameSpace().empty())
            Spelling += S.nameSpace() + "::";
        } else if (Variety == "C2x") {
          Matches = &C2x;
          if (!S.nameSpace().empty())
            Spelling += S.nameSpace() + "::";
        } 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;

        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_C2x == Syntax) {\n";
  StringMatcher("Name", C2x, 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 << "  }\n";
  OS << "  return AttributeCommonInfo::UnknownAttribute;\n"
     << "}\n";
}

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

  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
  for (const auto *Attr : Attrs) {
    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;
    llvm::raw_string_ostream SS(FunctionContent);

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

    Args = R.getValueAsListOfDefs("Args");
    for (const auto *Arg : Args)
      createArgument(*Arg, R.getName())->writeDump(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 << SS.str();
      OS << "  }\n";
    }
  }
}

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

  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
  for (const auto *Attr : Attrs) {
    const Record &R = *Attr;
    if (!R.getValueAsBit("ASTNode"))
      continue;

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

    Args = R.getValueAsListOfDefs("Args");
    for (const auto *Arg : Args)
      createArgument(*Arg, 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 << SS.str();
      OS << "  }\n";
    }
  }
}

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

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

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

class SpellingList {
  std::vector<std::string> Spellings[NumSpellingKinds];

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("C2x", SpellingKind::C2x)
                            .Case("Declspec", SpellingKind::Declspec)
                            .Case("Microsoft", SpellingKind::Microsoft)
                            .Case("Keyword", SpellingKind::Keyword)
                            .Case("Pragma", SpellingKind::Pragma);
    std::string Name;
    if (!Spelling.nameSpace().empty()) {
      switch (Kind) {
      case SpellingKind::CXX11:
      case SpellingKind::C2x:
        Name = Spelling.nameSpace() + "::";
        break;
      case SpellingKind::Pragma:
        Name = Spelling.nameSpace() + " ";
        break;
      default:
        PrintFatalError(Attr.getLoc(), "Unexpected namespace in spelling");
      }
    }
    Name += Spelling.name();

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

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) {
  // 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.

  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 = std::string(Documentation.getValueAsString("Heading"));
  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 (auto I = Spellings.begin(), E = Spellings.end();
           I != E && Uniques.size() <= 1; ++I) {
        std::string Spelling =
            std::string(NormalizeNameForSpellingComparison(I->name()));
        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 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(RecordKeeper &Records,
                               const DocumentationData &Doc, raw_ostream &OS) {
  OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n";

  // List what spelling syntaxes the attribute supports.
  OS << ".. csv-table:: Supported Syntaxes\n";
  OS << "   :header: \"GNU\", \"C++11\", \"C2x\", \"``__declspec``\",";
  OS << " \"Keyword\", \"``#pragma``\", \"``#pragma clang attribute``\"\n\n";
  OS << "   \"";
  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(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.
  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
  std::map<const Record *, std::vector<DocumentationData>> SplitDocs;
  for (const auto *A : Attrs) {
    const Record &Attr = *A;
    std::vector<Record *> Docs = Attr.getValueAsListOfDefs("Documentation");
    for (const auto *D : Docs) {
      const Record &Doc = *D;
      const Record *Category = Doc.getValueAsDef("Category");
      // If the category is "undocumented", then there cannot be any other
      // documentation categories (otherwise, the attribute would become
      // documented).
      const StringRef Cat = Category->getValueAsString("Name");
      bool Undocumented = Cat == "Undocumented";
      if (Undocumented && Docs.size() > 1)
        PrintFatalError(Doc.getLoc(),
                        "Attribute is \"Undocumented\", but has multiple "
                        "documentation categories");

      if (!Undocumented)
        SplitDocs[Category].push_back(DocumentationData(
            Doc, Attr, GetAttributeHeadingAndSpellings(Doc, Attr)));
    }
  }

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

    llvm::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(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");
    std::vector<Record *> Subjects =
        SubjectObj->getValueAsListOfDefs("Subjects");
    OS << " (";
    for (const auto &Subject : llvm::enumerate(Subjects)) {
      if (Subject.index())
        OS << ", ";
      PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet =
          Support.SubjectsToRules.find(Subject.value())->getSecond();
      if (RuleSet.isRule()) {
        OS << RuleSet.getRule().getEnumValueName();
        continue;
      }
      OS << "(";
      for (const auto &Rule : llvm::enumerate(RuleSet.getAggregateRuleSet())) {
        if (Rule.index())
          OS << ", ";
        OS << Rule.value().getEnumValueName();
      }
      OS << ")";
    }
    OS << ")\n";
  }
  OS << "End of supported attributes.\n";
}

} // end namespace clang
