/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Attribute classes' member function definitions                             *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

static inline void DelimitAttributeArgument(raw_ostream& OS, bool& IsFirst) {
  if (IsFirst) {
    IsFirst = false;
    OS << "(";
  } else
    OS << ", ";
}

// AArch64SVEPcsAttr implementation

AArch64SVEPcsAttr *AArch64SVEPcsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AArch64SVEPcsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AArch64SVEPcsAttr *AArch64SVEPcsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AArch64SVEPcsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AArch64SVEPcsAttr *AArch64SVEPcsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AArch64SVEPcsAttr *AArch64SVEPcsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AArch64SVEPcsAttr::AArch64SVEPcsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AArch64SVEPcs, false, false)
  {
}

AArch64SVEPcsAttr *AArch64SVEPcsAttr::clone(ASTContext &C) const {
  auto *A = new (C) AArch64SVEPcsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AArch64SVEPcsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((aarch64_sve_pcs";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::aarch64_sve_pcs";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::aarch64_sve_pcs";
    OS << "]]";
    break;
  }
}
}

const char *AArch64SVEPcsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "aarch64_sve_pcs";
  case 1:
    return "aarch64_sve_pcs";
  case 2:
    return "aarch64_sve_pcs";
  }
}


// AArch64VectorPcsAttr implementation

AArch64VectorPcsAttr *AArch64VectorPcsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AArch64VectorPcsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AArch64VectorPcsAttr *AArch64VectorPcsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AArch64VectorPcsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AArch64VectorPcsAttr *AArch64VectorPcsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AArch64VectorPcsAttr *AArch64VectorPcsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AArch64VectorPcsAttr::AArch64VectorPcsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AArch64VectorPcs, false, false)
  {
}

AArch64VectorPcsAttr *AArch64VectorPcsAttr::clone(ASTContext &C) const {
  auto *A = new (C) AArch64VectorPcsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AArch64VectorPcsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((aarch64_vector_pcs";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::aarch64_vector_pcs";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::aarch64_vector_pcs";
    OS << "]]";
    break;
  }
}
}

const char *AArch64VectorPcsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "aarch64_vector_pcs";
  case 1:
    return "aarch64_vector_pcs";
  case 2:
    return "aarch64_vector_pcs";
  }
}


// AMDGPUFlatWorkGroupSizeAttr implementation

AMDGPUFlatWorkGroupSizeAttr *AMDGPUFlatWorkGroupSizeAttr::CreateImplicit(ASTContext &Ctx, Expr * Min, Expr * Max, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUFlatWorkGroupSizeAttr(Ctx, CommonInfo, Min, Max);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUFlatWorkGroupSizeAttr *AMDGPUFlatWorkGroupSizeAttr::Create(ASTContext &Ctx, Expr * Min, Expr * Max, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUFlatWorkGroupSizeAttr(Ctx, CommonInfo, Min, Max);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUFlatWorkGroupSizeAttr *AMDGPUFlatWorkGroupSizeAttr::CreateImplicit(ASTContext &Ctx, Expr * Min, Expr * Max, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Min, Max, I);
}

AMDGPUFlatWorkGroupSizeAttr *AMDGPUFlatWorkGroupSizeAttr::Create(ASTContext &Ctx, Expr * Min, Expr * Max, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Min, Max, I);
}

AMDGPUFlatWorkGroupSizeAttr::AMDGPUFlatWorkGroupSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Min
              , Expr * Max
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AMDGPUFlatWorkGroupSize, false, false)
              , min(Min)
              , max(Max)
  {
}





AMDGPUFlatWorkGroupSizeAttr *AMDGPUFlatWorkGroupSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) AMDGPUFlatWorkGroupSizeAttr(C, *this, min, max);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AMDGPUFlatWorkGroupSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((amdgpu_flat_work_group_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMin() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMax() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::amdgpu_flat_work_group_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMin() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMax() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AMDGPUFlatWorkGroupSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "amdgpu_flat_work_group_size";
  case 1:
    return "amdgpu_flat_work_group_size";
  }
}


// AMDGPUKernelCallAttr implementation

AMDGPUKernelCallAttr *AMDGPUKernelCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUKernelCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUKernelCallAttr *AMDGPUKernelCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUKernelCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUKernelCallAttr *AMDGPUKernelCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AMDGPUKernelCallAttr *AMDGPUKernelCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AMDGPUKernelCallAttr::AMDGPUKernelCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AMDGPUKernelCall, false, false)
  {
}

AMDGPUKernelCallAttr *AMDGPUKernelCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) AMDGPUKernelCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AMDGPUKernelCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((amdgpu_kernel";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::amdgpu_kernel";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::amdgpu_kernel";
    OS << "]]";
    break;
  }
}
}

const char *AMDGPUKernelCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "amdgpu_kernel";
  case 1:
    return "amdgpu_kernel";
  case 2:
    return "amdgpu_kernel";
  }
}


// AMDGPUNumSGPRAttr implementation

AMDGPUNumSGPRAttr *AMDGPUNumSGPRAttr::CreateImplicit(ASTContext &Ctx, unsigned NumSGPR, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUNumSGPRAttr(Ctx, CommonInfo, NumSGPR);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUNumSGPRAttr *AMDGPUNumSGPRAttr::Create(ASTContext &Ctx, unsigned NumSGPR, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUNumSGPRAttr(Ctx, CommonInfo, NumSGPR);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUNumSGPRAttr *AMDGPUNumSGPRAttr::CreateImplicit(ASTContext &Ctx, unsigned NumSGPR, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, NumSGPR, I);
}

AMDGPUNumSGPRAttr *AMDGPUNumSGPRAttr::Create(ASTContext &Ctx, unsigned NumSGPR, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, NumSGPR, I);
}

AMDGPUNumSGPRAttr::AMDGPUNumSGPRAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned NumSGPR
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AMDGPUNumSGPR, false, false)
              , numSGPR(NumSGPR)
  {
}



AMDGPUNumSGPRAttr *AMDGPUNumSGPRAttr::clone(ASTContext &C) const {
  auto *A = new (C) AMDGPUNumSGPRAttr(C, *this, numSGPR);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AMDGPUNumSGPRAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((amdgpu_num_sgpr";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumSGPR() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::amdgpu_num_sgpr";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumSGPR() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AMDGPUNumSGPRAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "amdgpu_num_sgpr";
  case 1:
    return "amdgpu_num_sgpr";
  }
}


// AMDGPUNumVGPRAttr implementation

AMDGPUNumVGPRAttr *AMDGPUNumVGPRAttr::CreateImplicit(ASTContext &Ctx, unsigned NumVGPR, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUNumVGPRAttr(Ctx, CommonInfo, NumVGPR);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUNumVGPRAttr *AMDGPUNumVGPRAttr::Create(ASTContext &Ctx, unsigned NumVGPR, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUNumVGPRAttr(Ctx, CommonInfo, NumVGPR);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUNumVGPRAttr *AMDGPUNumVGPRAttr::CreateImplicit(ASTContext &Ctx, unsigned NumVGPR, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, NumVGPR, I);
}

AMDGPUNumVGPRAttr *AMDGPUNumVGPRAttr::Create(ASTContext &Ctx, unsigned NumVGPR, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, NumVGPR, I);
}

AMDGPUNumVGPRAttr::AMDGPUNumVGPRAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned NumVGPR
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AMDGPUNumVGPR, false, false)
              , numVGPR(NumVGPR)
  {
}



AMDGPUNumVGPRAttr *AMDGPUNumVGPRAttr::clone(ASTContext &C) const {
  auto *A = new (C) AMDGPUNumVGPRAttr(C, *this, numVGPR);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AMDGPUNumVGPRAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((amdgpu_num_vgpr";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumVGPR() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::amdgpu_num_vgpr";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumVGPR() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AMDGPUNumVGPRAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "amdgpu_num_vgpr";
  case 1:
    return "amdgpu_num_vgpr";
  }
}


// AMDGPUWavesPerEUAttr implementation

AMDGPUWavesPerEUAttr *AMDGPUWavesPerEUAttr::CreateImplicit(ASTContext &Ctx, Expr * Min, Expr * Max, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUWavesPerEUAttr(Ctx, CommonInfo, Min, Max);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUWavesPerEUAttr *AMDGPUWavesPerEUAttr::Create(ASTContext &Ctx, Expr * Min, Expr * Max, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AMDGPUWavesPerEUAttr(Ctx, CommonInfo, Min, Max);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AMDGPUWavesPerEUAttr *AMDGPUWavesPerEUAttr::CreateImplicit(ASTContext &Ctx, Expr * Min, Expr * Max, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Min, Max, I);
}

AMDGPUWavesPerEUAttr *AMDGPUWavesPerEUAttr::Create(ASTContext &Ctx, Expr * Min, Expr * Max, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Min, Max, I);
}

AMDGPUWavesPerEUAttr::AMDGPUWavesPerEUAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Min
              , Expr * Max
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AMDGPUWavesPerEU, false, false)
              , min(Min)
              , max(Max)
  {
}

AMDGPUWavesPerEUAttr::AMDGPUWavesPerEUAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Min
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AMDGPUWavesPerEU, false, false)
              , min(Min)
              , max()
  {
}





AMDGPUWavesPerEUAttr *AMDGPUWavesPerEUAttr::clone(ASTContext &C) const {
  auto *A = new (C) AMDGPUWavesPerEUAttr(C, *this, min, max);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AMDGPUWavesPerEUAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((amdgpu_waves_per_eu";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMin() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMax() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::amdgpu_waves_per_eu";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMin() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMax() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AMDGPUWavesPerEUAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "amdgpu_waves_per_eu";
  case 1:
    return "amdgpu_waves_per_eu";
  }
}


// ARMInterruptAttr implementation

ARMInterruptAttr *ARMInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ARMInterruptAttr(Ctx, CommonInfo, Interrupt);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ARMInterruptAttr *ARMInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ARMInterruptAttr(Ctx, CommonInfo, Interrupt);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ARMInterruptAttr *ARMInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Interrupt, I);
}

ARMInterruptAttr *ARMInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Interrupt, I);
}

ARMInterruptAttr::ARMInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , InterruptType Interrupt
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ARMInterrupt, false, false)
              , interrupt(Interrupt)
  {
}

ARMInterruptAttr::ARMInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ARMInterrupt, false, false)
              , interrupt(InterruptType(0))
  {
}



bool ARMInterruptAttr::ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
  Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
    .Case("IRQ", ARMInterruptAttr::IRQ)
    .Case("FIQ", ARMInterruptAttr::FIQ)
    .Case("SWI", ARMInterruptAttr::SWI)
    .Case("ABORT", ARMInterruptAttr::ABORT)
    .Case("UNDEF", ARMInterruptAttr::UNDEF)
    .Case("", ARMInterruptAttr::Generic)
    .Default(Optional<InterruptType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ARMInterruptAttr::ConvertInterruptTypeToStr(InterruptType Val) {
  switch(Val) {
  case ARMInterruptAttr::IRQ: return "IRQ";
  case ARMInterruptAttr::FIQ: return "FIQ";
  case ARMInterruptAttr::SWI: return "SWI";
  case ARMInterruptAttr::ABORT: return "ABORT";
  case ARMInterruptAttr::UNDEF: return "UNDEF";
  case ARMInterruptAttr::Generic: return "";
  }
  llvm_unreachable("No enumerator with that value");
}
ARMInterruptAttr *ARMInterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) ARMInterruptAttr(C, *this, interrupt);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ARMInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ARMInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ARMInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ARMInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ARMInterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// AVRInterruptAttr implementation

AVRInterruptAttr *AVRInterruptAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AVRInterruptAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AVRInterruptAttr *AVRInterruptAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AVRInterruptAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AVRInterruptAttr *AVRInterruptAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AVRInterruptAttr *AVRInterruptAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AVRInterruptAttr::AVRInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AVRInterrupt, false, false)
  {
}

AVRInterruptAttr *AVRInterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) AVRInterruptAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AVRInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    OS << "]]";
    break;
  }
}
}

const char *AVRInterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// AVRSignalAttr implementation

AVRSignalAttr *AVRSignalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AVRSignalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AVRSignalAttr *AVRSignalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AVRSignalAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AVRSignalAttr *AVRSignalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AVRSignalAttr *AVRSignalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AVRSignalAttr::AVRSignalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AVRSignal, false, false)
  {
}

AVRSignalAttr *AVRSignalAttr::clone(ASTContext &C) const {
  auto *A = new (C) AVRSignalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AVRSignalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((signal";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::signal";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::signal";
    OS << "]]";
    break;
  }
}
}

const char *AVRSignalAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "signal";
  case 1:
    return "signal";
  case 2:
    return "signal";
  }
}


// AbiTagAttr implementation

AbiTagAttr *AbiTagAttr::CreateImplicit(ASTContext &Ctx, StringRef *Tags, unsigned TagsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AbiTagAttr(Ctx, CommonInfo, Tags, TagsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AbiTagAttr *AbiTagAttr::Create(ASTContext &Ctx, StringRef *Tags, unsigned TagsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AbiTagAttr(Ctx, CommonInfo, Tags, TagsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AbiTagAttr *AbiTagAttr::CreateImplicit(ASTContext &Ctx, StringRef *Tags, unsigned TagsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Tags, TagsSize, I);
}

AbiTagAttr *AbiTagAttr::Create(ASTContext &Ctx, StringRef *Tags, unsigned TagsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Tags, TagsSize, I);
}

AbiTagAttr::AbiTagAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *Tags, unsigned TagsSize
             )
  : Attr(Ctx, CommonInfo, attr::AbiTag, false)
              , tags_Size(TagsSize), tags_(new (Ctx, 16) StringRef[tags_Size])
  {
  for (size_t I = 0, E = tags_Size; I != E;
       ++I) {
    StringRef Ref = Tags[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      tags_[I] = StringRef(Mem, Ref.size());
    }
  }
}

AbiTagAttr::AbiTagAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::AbiTag, false)
              , tags_Size(0), tags_(nullptr)
  {
}



AbiTagAttr *AbiTagAttr::clone(ASTContext &C) const {
  auto *A = new (C) AbiTagAttr(C, *this, tags_, tags_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AbiTagAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((abi_tag";
    OS << "";
  for (const auto &Val : tags()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::abi_tag";
    OS << "";
  for (const auto &Val : tags()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AbiTagAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "abi_tag";
  case 1:
    return "abi_tag";
  }
}


// AcquireCapabilityAttr implementation

AcquireCapabilityAttr *AcquireCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquireCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquireCapabilityAttr *AcquireCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquireCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  return A;
}

AcquireCapabilityAttr *AcquireCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AcquireCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

AcquireCapabilityAttr *AcquireCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AcquireCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Args, ArgsSize, I);
}

AcquireCapabilityAttr::AcquireCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquireCapability, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

AcquireCapabilityAttr::AcquireCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquireCapability, true, true)
              , args_Size(0), args_(nullptr)
  {
}

AcquireCapabilityAttr::Spelling AcquireCapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_acquire_capability;
    case 1: return CXX11_clang_acquire_capability;
    case 2: return GNU_acquire_shared_capability;
    case 3: return CXX11_clang_acquire_shared_capability;
    case 4: return GNU_exclusive_lock_function;
    case 5: return GNU_shared_lock_function;
  }
}


AcquireCapabilityAttr *AcquireCapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) AcquireCapabilityAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AcquireCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((acquire_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::acquire_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((acquire_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::acquire_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " __attribute__((exclusive_lock_function";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 5 : {
    OS << " __attribute__((shared_lock_function";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *AcquireCapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "acquire_capability";
  case 1:
    return "acquire_capability";
  case 2:
    return "acquire_shared_capability";
  case 3:
    return "acquire_shared_capability";
  case 4:
    return "exclusive_lock_function";
  case 5:
    return "shared_lock_function";
  }
}


// AcquireHandleAttr implementation

AcquireHandleAttr *AcquireHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquireHandleAttr(Ctx, CommonInfo, HandleType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquireHandleAttr *AcquireHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquireHandleAttr(Ctx, CommonInfo, HandleType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquireHandleAttr *AcquireHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, HandleType, I);
}

AcquireHandleAttr *AcquireHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, HandleType, I);
}

AcquireHandleAttr::AcquireHandleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef HandleType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquireHandle, false, false)
              , handleTypeLength(HandleType.size()),handleType(new (Ctx, 1) char[handleTypeLength])
  {
    if (!HandleType.empty())
      std::memcpy(handleType, HandleType.data(), handleTypeLength);
}



AcquireHandleAttr *AcquireHandleAttr::clone(ASTContext &C) const {
  auto *A = new (C) AcquireHandleAttr(C, *this, getHandleType());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AcquireHandleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((acquire_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::acquire_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::acquire_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AcquireHandleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "acquire_handle";
  case 1:
    return "acquire_handle";
  case 2:
    return "acquire_handle";
  }
}


// AcquiredAfterAttr implementation

AcquiredAfterAttr *AcquiredAfterAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquiredAfterAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquiredAfterAttr *AcquiredAfterAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquiredAfterAttr(Ctx, CommonInfo, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquiredAfterAttr *AcquiredAfterAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

AcquiredAfterAttr *AcquiredAfterAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Args, ArgsSize, I);
}

AcquiredAfterAttr::AcquiredAfterAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquiredAfter, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

AcquiredAfterAttr::AcquiredAfterAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquiredAfter, true, true)
              , args_Size(0), args_(nullptr)
  {
}



AcquiredAfterAttr *AcquiredAfterAttr::clone(ASTContext &C) const {
  auto *A = new (C) AcquiredAfterAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AcquiredAfterAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((acquired_after";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *AcquiredAfterAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "acquired_after";
  }
}


// AcquiredBeforeAttr implementation

AcquiredBeforeAttr *AcquiredBeforeAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquiredBeforeAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquiredBeforeAttr *AcquiredBeforeAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AcquiredBeforeAttr(Ctx, CommonInfo, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AcquiredBeforeAttr *AcquiredBeforeAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

AcquiredBeforeAttr *AcquiredBeforeAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Args, ArgsSize, I);
}

AcquiredBeforeAttr::AcquiredBeforeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquiredBefore, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

AcquiredBeforeAttr::AcquiredBeforeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AcquiredBefore, true, true)
              , args_Size(0), args_(nullptr)
  {
}



AcquiredBeforeAttr *AcquiredBeforeAttr::clone(ASTContext &C) const {
  auto *A = new (C) AcquiredBeforeAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AcquiredBeforeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((acquired_before";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *AcquiredBeforeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "acquired_before";
  }
}


// AddressSpaceAttr implementation

AddressSpaceAttr *AddressSpaceAttr::CreateImplicit(ASTContext &Ctx, int AddressSpace, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AddressSpaceAttr(Ctx, CommonInfo, AddressSpace);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AddressSpaceAttr *AddressSpaceAttr::Create(ASTContext &Ctx, int AddressSpace, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AddressSpaceAttr(Ctx, CommonInfo, AddressSpace);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AddressSpaceAttr *AddressSpaceAttr::CreateImplicit(ASTContext &Ctx, int AddressSpace, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, AddressSpace, I);
}

AddressSpaceAttr *AddressSpaceAttr::Create(ASTContext &Ctx, int AddressSpace, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, AddressSpace, I);
}

AddressSpaceAttr::AddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int AddressSpace
             )
  : TypeAttr(Ctx, CommonInfo, attr::AddressSpace, false)
              , addressSpace(AddressSpace)
  {
}



AddressSpaceAttr *AddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) AddressSpaceAttr(C, *this, addressSpace);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((address_space";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAddressSpace() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::address_space";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAddressSpace() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::address_space";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAddressSpace() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "address_space";
  case 1:
    return "address_space";
  case 2:
    return "address_space";
  }
}


// AliasAttr implementation

AliasAttr *AliasAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AliasAttr(Ctx, CommonInfo, Aliasee);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AliasAttr *AliasAttr::Create(ASTContext &Ctx, llvm::StringRef Aliasee, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AliasAttr(Ctx, CommonInfo, Aliasee);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AliasAttr *AliasAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Aliasee, I);
}

AliasAttr *AliasAttr::Create(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Aliasee, I);
}

AliasAttr::AliasAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Aliasee
             )
  : Attr(Ctx, CommonInfo, attr::Alias, false)
              , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
  {
    if (!Aliasee.empty())
      std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
}



AliasAttr *AliasAttr::clone(ASTContext &C) const {
  auto *A = new (C) AliasAttr(C, *this, getAliasee());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AliasAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "alias";
  case 1:
    return "alias";
  case 2:
    return "alias";
  }
}


// AlignMac68kAttr implementation

AlignMac68kAttr *AlignMac68kAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignMac68kAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignMac68kAttr *AlignMac68kAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignMac68kAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignMac68kAttr *AlignMac68kAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AlignMac68kAttr *AlignMac68kAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AlignMac68kAttr::AlignMac68kAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AlignMac68k, false, false)
  {
}

AlignMac68kAttr *AlignMac68kAttr::clone(ASTContext &C) const {
  auto *A = new (C) AlignMac68kAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AlignMac68kAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *AlignMac68kAttr::getSpelling() const {
  return "(No spelling)";
}


// AlignNaturalAttr implementation

AlignNaturalAttr *AlignNaturalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignNaturalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignNaturalAttr *AlignNaturalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignNaturalAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignNaturalAttr *AlignNaturalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AlignNaturalAttr *AlignNaturalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AlignNaturalAttr::AlignNaturalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AlignNatural, false, false)
  {
}

AlignNaturalAttr *AlignNaturalAttr::clone(ASTContext &C) const {
  auto *A = new (C) AlignNaturalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AlignNaturalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *AlignNaturalAttr::getSpelling() const {
  return "(No spelling)";
}


// AlignValueAttr implementation

AlignValueAttr *AlignValueAttr::CreateImplicit(ASTContext &Ctx, Expr * Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignValueAttr(Ctx, CommonInfo, Alignment);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignValueAttr *AlignValueAttr::Create(ASTContext &Ctx, Expr * Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignValueAttr(Ctx, CommonInfo, Alignment);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignValueAttr *AlignValueAttr::CreateImplicit(ASTContext &Ctx, Expr * Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Alignment, I);
}

AlignValueAttr *AlignValueAttr::Create(ASTContext &Ctx, Expr * Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Alignment, I);
}

AlignValueAttr::AlignValueAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Alignment
             )
  : Attr(Ctx, CommonInfo, attr::AlignValue, false)
              , alignment(Alignment)
  {
}



AlignValueAttr *AlignValueAttr::clone(ASTContext &C) const {
  auto *A = new (C) AlignValueAttr(C, *this, alignment);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AlignValueAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((align_value";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAlignment() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *AlignValueAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "align_value";
  }
}


// AlignedAttr implementation

AlignedAttr *AlignedAttr::CreateImplicit(ASTContext &Ctx, bool IsAlignmentExpr, void *Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignedAttr(Ctx, CommonInfo, IsAlignmentExpr, Alignment);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlignedAttr *AlignedAttr::Create(ASTContext &Ctx, bool IsAlignmentExpr, void *Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlignedAttr(Ctx, CommonInfo, IsAlignmentExpr, Alignment);
  return A;
}

AlignedAttr *AlignedAttr::CreateImplicit(ASTContext &Ctx, bool IsAlignmentExpr, void *Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AlignedAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, IsAlignmentExpr, Alignment, I);
}

AlignedAttr *AlignedAttr::Create(ASTContext &Ctx, bool IsAlignmentExpr, void *Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AlignedAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, IsAlignmentExpr, Alignment, I);
}

AlignedAttr::AlignedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , bool IsAlignmentExpr, void *Alignment
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Aligned, false, false)
              , isalignmentExpr(IsAlignmentExpr)
  {
    if (isalignmentExpr)
       alignmentExpr = reinterpret_cast<Expr *>(Alignment);
    else
       alignmentType = reinterpret_cast<TypeSourceInfo *>(Alignment);
}

AlignedAttr::AlignedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Aligned, false, false)
              , isalignmentExpr(false)
  {
}

AlignedAttr::Spelling AlignedAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_aligned;
    case 1: return CXX11_gnu_aligned;
    case 2: return C2x_gnu_aligned;
    case 3: return Declspec_align;
    case 4: return Keyword_alignas;
    case 5: return Keyword_Alignas;
  }
}
bool AlignedAttr::isAlignmentDependent() const {
  if (isalignmentExpr)
    return alignmentExpr && (alignmentExpr->isValueDependent() || alignmentExpr->isTypeDependent());
  else
    return alignmentType->getType()->isDependentType();
}
bool AlignedAttr::isAlignmentErrorDependent() const {
  if (isalignmentExpr)
    return alignmentExpr && alignmentExpr->containsErrors();
  return alignmentType->getType()->containsErrors();
}
unsigned AlignedAttr::getAlignment(ASTContext &Ctx) const {
  assert(!isAlignmentDependent());
  if (isalignmentExpr)
    return alignmentExpr ? alignmentExpr->EvaluateKnownConstInt(Ctx).getZExtValue() * Ctx.getCharWidth() : Ctx.getTargetDefaultAlignForAttributeAligned();
  else
    return 0; // FIXME
}


AlignedAttr *AlignedAttr::clone(ASTContext &C) const {
  auto *A = new (C) AlignedAttr(C, *this, isalignmentExpr, isalignmentExpr ? static_cast<void*>(alignmentExpr) : alignmentType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AlignedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((aligned";
    if (!isalignmentExpr || !alignmentExpr)
      ++TrailingOmittedArgs;
    if (!(!isalignmentExpr || !alignmentExpr)) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "";
    alignmentExpr->printPretty(OS, nullptr, Policy);
    OS << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::aligned";
    if (!isalignmentExpr || !alignmentExpr)
      ++TrailingOmittedArgs;
    if (!(!isalignmentExpr || !alignmentExpr)) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "";
    alignmentExpr->printPretty(OS, nullptr, Policy);
    OS << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::aligned";
    if (!isalignmentExpr || !alignmentExpr)
      ++TrailingOmittedArgs;
    if (!(!isalignmentExpr || !alignmentExpr)) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "";
    alignmentExpr->printPretty(OS, nullptr, Policy);
    OS << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(align";
    if (!isalignmentExpr || !alignmentExpr)
      ++TrailingOmittedArgs;
    if (!(!isalignmentExpr || !alignmentExpr)) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "";
    alignmentExpr->printPretty(OS, nullptr, Policy);
    OS << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
  case 4 : {
    OS << " alignas";
    if (!isalignmentExpr || !alignmentExpr)
      ++TrailingOmittedArgs;
    if (!(!isalignmentExpr || !alignmentExpr)) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "";
    alignmentExpr->printPretty(OS, nullptr, Policy);
    OS << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "";
    break;
  }
  case 5 : {
    OS << " _Alignas";
    if (!isalignmentExpr || !alignmentExpr)
      ++TrailingOmittedArgs;
    if (!(!isalignmentExpr || !alignmentExpr)) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "";
    alignmentExpr->printPretty(OS, nullptr, Policy);
    OS << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "";
    break;
  }
}
}

const char *AlignedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "aligned";
  case 1:
    return "aligned";
  case 2:
    return "aligned";
  case 3:
    return "align";
  case 4:
    return "alignas";
  case 5:
    return "_Alignas";
  }
}


// AllocAlignAttr implementation

AllocAlignAttr *AllocAlignAttr::CreateImplicit(ASTContext &Ctx, ParamIdx ParamIndex, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AllocAlignAttr(Ctx, CommonInfo, ParamIndex);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AllocAlignAttr *AllocAlignAttr::Create(ASTContext &Ctx, ParamIdx ParamIndex, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AllocAlignAttr(Ctx, CommonInfo, ParamIndex);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AllocAlignAttr *AllocAlignAttr::CreateImplicit(ASTContext &Ctx, ParamIdx ParamIndex, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ParamIndex, I);
}

AllocAlignAttr *AllocAlignAttr::Create(ASTContext &Ctx, ParamIdx ParamIndex, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ParamIndex, I);
}

AllocAlignAttr::AllocAlignAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx ParamIndex
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AllocAlign, false, false)
              , paramIndex(ParamIndex)
  {
}



AllocAlignAttr *AllocAlignAttr::clone(ASTContext &C) const {
  auto *A = new (C) AllocAlignAttr(C, *this, paramIndex);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AllocAlignAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((alloc_align";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getParamIndex().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::alloc_align";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getParamIndex().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::alloc_align";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getParamIndex().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AllocAlignAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "alloc_align";
  case 1:
    return "alloc_align";
  case 2:
    return "alloc_align";
  }
}


// AllocSizeAttr implementation

AllocSizeAttr *AllocSizeAttr::CreateImplicit(ASTContext &Ctx, ParamIdx ElemSizeParam, ParamIdx NumElemsParam, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AllocSizeAttr(Ctx, CommonInfo, ElemSizeParam, NumElemsParam);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AllocSizeAttr *AllocSizeAttr::Create(ASTContext &Ctx, ParamIdx ElemSizeParam, ParamIdx NumElemsParam, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AllocSizeAttr(Ctx, CommonInfo, ElemSizeParam, NumElemsParam);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AllocSizeAttr *AllocSizeAttr::CreateImplicit(ASTContext &Ctx, ParamIdx ElemSizeParam, ParamIdx NumElemsParam, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ElemSizeParam, NumElemsParam, I);
}

AllocSizeAttr *AllocSizeAttr::Create(ASTContext &Ctx, ParamIdx ElemSizeParam, ParamIdx NumElemsParam, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ElemSizeParam, NumElemsParam, I);
}

AllocSizeAttr::AllocSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx ElemSizeParam
              , ParamIdx NumElemsParam
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AllocSize, false, false)
              , elemSizeParam(ElemSizeParam)
              , numElemsParam(NumElemsParam)
  {
}

AllocSizeAttr::AllocSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx ElemSizeParam
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AllocSize, false, false)
              , elemSizeParam(ElemSizeParam)
              , numElemsParam()
  {
}





AllocSizeAttr *AllocSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) AllocSizeAttr(C, *this, elemSizeParam, numElemsParam);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AllocSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((alloc_size";
    if (!getNumElemsParam().isValid())
      ++TrailingOmittedArgs;
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getElemSizeParam().getSourceIndex() << "";
    if (!(!getNumElemsParam().isValid())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumElemsParam().getSourceIndex() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::alloc_size";
    if (!getNumElemsParam().isValid())
      ++TrailingOmittedArgs;
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getElemSizeParam().getSourceIndex() << "";
    if (!(!getNumElemsParam().isValid())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumElemsParam().getSourceIndex() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::alloc_size";
    if (!getNumElemsParam().isValid())
      ++TrailingOmittedArgs;
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getElemSizeParam().getSourceIndex() << "";
    if (!(!getNumElemsParam().isValid())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumElemsParam().getSourceIndex() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AllocSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "alloc_size";
  case 1:
    return "alloc_size";
  case 2:
    return "alloc_size";
  }
}


// AlwaysDestroyAttr implementation

AlwaysDestroyAttr *AlwaysDestroyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlwaysDestroyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlwaysDestroyAttr *AlwaysDestroyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlwaysDestroyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlwaysDestroyAttr *AlwaysDestroyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AlwaysDestroyAttr *AlwaysDestroyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AlwaysDestroyAttr::AlwaysDestroyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AlwaysDestroy, false, false)
  {
}

AlwaysDestroyAttr *AlwaysDestroyAttr::clone(ASTContext &C) const {
  auto *A = new (C) AlwaysDestroyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AlwaysDestroyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((always_destroy";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::always_destroy";
    OS << "]]";
    break;
  }
}
}

const char *AlwaysDestroyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "always_destroy";
  case 1:
    return "always_destroy";
  }
}


// AlwaysInlineAttr implementation

AlwaysInlineAttr *AlwaysInlineAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlwaysInlineAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AlwaysInlineAttr *AlwaysInlineAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AlwaysInlineAttr(Ctx, CommonInfo);
  return A;
}

AlwaysInlineAttr *AlwaysInlineAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AlwaysInlineAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

AlwaysInlineAttr *AlwaysInlineAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AlwaysInlineAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

AlwaysInlineAttr::AlwaysInlineAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : DeclOrStmtAttr(Ctx, CommonInfo, attr::AlwaysInline, false, false)
  {
}

AlwaysInlineAttr::Spelling AlwaysInlineAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_always_inline;
    case 1: return CXX11_gnu_always_inline;
    case 2: return C2x_gnu_always_inline;
    case 3: return CXX11_clang_always_inline;
    case 4: return C2x_clang_always_inline;
    case 5: return Keyword_forceinline;
  }
}
AlwaysInlineAttr *AlwaysInlineAttr::clone(ASTContext &C) const {
  auto *A = new (C) AlwaysInlineAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AlwaysInlineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((always_inline";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::always_inline";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::always_inline";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[clang::always_inline";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::always_inline";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " __forceinline";
    OS << "";
    break;
  }
}
}

const char *AlwaysInlineAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "always_inline";
  case 1:
    return "always_inline";
  case 2:
    return "always_inline";
  case 3:
    return "always_inline";
  case 4:
    return "always_inline";
  case 5:
    return "__forceinline";
  }
}


// AnalyzerNoReturnAttr implementation

AnalyzerNoReturnAttr *AnalyzerNoReturnAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnalyzerNoReturnAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnalyzerNoReturnAttr *AnalyzerNoReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnalyzerNoReturnAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnalyzerNoReturnAttr *AnalyzerNoReturnAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AnalyzerNoReturnAttr *AnalyzerNoReturnAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AnalyzerNoReturnAttr::AnalyzerNoReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AnalyzerNoReturn, false, false)
  {
}

AnalyzerNoReturnAttr *AnalyzerNoReturnAttr::clone(ASTContext &C) const {
  auto *A = new (C) AnalyzerNoReturnAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AnalyzerNoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((analyzer_noreturn";
    OS << "))";
    break;
  }
}
}

const char *AnalyzerNoReturnAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "analyzer_noreturn";
  }
}


// AnnotateAttr implementation

AnnotateAttr *AnnotateAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateAttr(Ctx, CommonInfo, Annotation, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnnotateAttr *AnnotateAttr::Create(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateAttr(Ctx, CommonInfo, Annotation, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnnotateAttr *AnnotateAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Annotation, Args, ArgsSize, I);
}

AnnotateAttr *AnnotateAttr::Create(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Annotation, Args, ArgsSize, I);
}

AnnotateAttr *AnnotateAttr::CreateImplicitWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  A->setDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize);
  return A;
}

AnnotateAttr *AnnotateAttr::CreateWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  A->setDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize);
  return A;
}

AnnotateAttr *AnnotateAttr::CreateImplicitWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicitWithDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize, I);
}

AnnotateAttr *AnnotateAttr::CreateWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateWithDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize, I);
}

AnnotateAttr::AnnotateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Annotation
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::Annotate, false, false)
              , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength])
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
              , delayedArgs_Size(0), delayedArgs_(nullptr)
  {
    if (!Annotation.empty())
      std::memcpy(annotation, Annotation.data(), annotationLength);
  std::copy(Args, Args + args_Size, args_);
}

AnnotateAttr::AnnotateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Annotation
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::Annotate, false, false)
              , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength])
              , args_Size(0), args_(nullptr)
              , delayedArgs_Size(0), delayedArgs_(nullptr)
  {
    if (!Annotation.empty())
      std::memcpy(annotation, Annotation.data(), annotationLength);
}

AnnotateAttr::AnnotateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::Annotate, false, false)
              , annotationLength(0),annotation(nullptr)
              , args_Size(0), args_(nullptr)
              , delayedArgs_Size(0), delayedArgs_(nullptr)
  {
}





AnnotateAttr *AnnotateAttr::clone(ASTContext &C) const {
  auto *A = new (C) AnnotateAttr(C, *this, getAnnotation(), args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  A->setDelayedArgs(C, delayedArgs_, delayedArgs_Size);
  return A;
}

void AnnotateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((annotate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAnnotation() << "\"";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::annotate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAnnotation() << "\"";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::annotate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAnnotation() << "\"";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AnnotateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "annotate";
  case 1:
    return "annotate";
  case 2:
    return "annotate";
  }
}


// AnnotateTypeAttr implementation

AnnotateTypeAttr *AnnotateTypeAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateTypeAttr(Ctx, CommonInfo, Annotation, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnnotateTypeAttr *AnnotateTypeAttr::Create(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateTypeAttr(Ctx, CommonInfo, Annotation, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnnotateTypeAttr *AnnotateTypeAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Annotation, Args, ArgsSize, I);
}

AnnotateTypeAttr *AnnotateTypeAttr::Create(ASTContext &Ctx, llvm::StringRef Annotation, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Annotation, Args, ArgsSize, I);
}

AnnotateTypeAttr *AnnotateTypeAttr::CreateImplicitWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateTypeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  A->setDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize);
  return A;
}

AnnotateTypeAttr *AnnotateTypeAttr::CreateWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnnotateTypeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  A->setDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize);
  return A;
}

AnnotateTypeAttr *AnnotateTypeAttr::CreateImplicitWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicitWithDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize, I);
}

AnnotateTypeAttr *AnnotateTypeAttr::CreateWithDelayedArgs(ASTContext &Ctx, Expr * *DelayedArgs, unsigned DelayedArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateWithDelayedArgs(Ctx, DelayedArgs, DelayedArgsSize, I);
}

AnnotateTypeAttr::AnnotateTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Annotation
              , Expr * *Args, unsigned ArgsSize
             )
  : TypeAttr(Ctx, CommonInfo, attr::AnnotateType, false)
              , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength])
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
              , delayedArgs_Size(0), delayedArgs_(nullptr)
  {
    if (!Annotation.empty())
      std::memcpy(annotation, Annotation.data(), annotationLength);
  std::copy(Args, Args + args_Size, args_);
}

AnnotateTypeAttr::AnnotateTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Annotation
             )
  : TypeAttr(Ctx, CommonInfo, attr::AnnotateType, false)
              , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength])
              , args_Size(0), args_(nullptr)
              , delayedArgs_Size(0), delayedArgs_(nullptr)
  {
    if (!Annotation.empty())
      std::memcpy(annotation, Annotation.data(), annotationLength);
}

AnnotateTypeAttr::AnnotateTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::AnnotateType, false)
              , annotationLength(0),annotation(nullptr)
              , args_Size(0), args_(nullptr)
              , delayedArgs_Size(0), delayedArgs_(nullptr)
  {
}





AnnotateTypeAttr *AnnotateTypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) AnnotateTypeAttr(C, *this, getAnnotation(), args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  A->setDelayedArgs(C, delayedArgs_, delayedArgs_Size);
  return A;
}

void AnnotateTypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[clang::annotate_type";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAnnotation() << "\"";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[clang::annotate_type";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAnnotation() << "\"";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AnnotateTypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "annotate_type";
  case 1:
    return "annotate_type";
  }
}


// AnyX86InterruptAttr implementation

AnyX86InterruptAttr *AnyX86InterruptAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnyX86InterruptAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnyX86InterruptAttr *AnyX86InterruptAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnyX86InterruptAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnyX86InterruptAttr *AnyX86InterruptAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AnyX86InterruptAttr *AnyX86InterruptAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AnyX86InterruptAttr::AnyX86InterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AnyX86Interrupt, false, false)
  {
}

AnyX86InterruptAttr *AnyX86InterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) AnyX86InterruptAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AnyX86InterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    OS << "]]";
    break;
  }
}
}

const char *AnyX86InterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// AnyX86NoCallerSavedRegistersAttr implementation

AnyX86NoCallerSavedRegistersAttr *AnyX86NoCallerSavedRegistersAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnyX86NoCallerSavedRegistersAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnyX86NoCallerSavedRegistersAttr *AnyX86NoCallerSavedRegistersAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnyX86NoCallerSavedRegistersAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnyX86NoCallerSavedRegistersAttr *AnyX86NoCallerSavedRegistersAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AnyX86NoCallerSavedRegistersAttr *AnyX86NoCallerSavedRegistersAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AnyX86NoCallerSavedRegistersAttr::AnyX86NoCallerSavedRegistersAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AnyX86NoCallerSavedRegisters, false, false)
  {
}

AnyX86NoCallerSavedRegistersAttr *AnyX86NoCallerSavedRegistersAttr::clone(ASTContext &C) const {
  auto *A = new (C) AnyX86NoCallerSavedRegistersAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AnyX86NoCallerSavedRegistersAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_caller_saved_registers";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::no_caller_saved_registers";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::no_caller_saved_registers";
    OS << "]]";
    break;
  }
}
}

const char *AnyX86NoCallerSavedRegistersAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_caller_saved_registers";
  case 1:
    return "no_caller_saved_registers";
  case 2:
    return "no_caller_saved_registers";
  }
}


// AnyX86NoCfCheckAttr implementation

AnyX86NoCfCheckAttr *AnyX86NoCfCheckAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnyX86NoCfCheckAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnyX86NoCfCheckAttr *AnyX86NoCfCheckAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AnyX86NoCfCheckAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AnyX86NoCfCheckAttr *AnyX86NoCfCheckAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

AnyX86NoCfCheckAttr *AnyX86NoCfCheckAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

AnyX86NoCfCheckAttr::AnyX86NoCfCheckAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AnyX86NoCfCheck, false, false)
  {
}

AnyX86NoCfCheckAttr *AnyX86NoCfCheckAttr::clone(ASTContext &C) const {
  auto *A = new (C) AnyX86NoCfCheckAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AnyX86NoCfCheckAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nocf_check";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nocf_check";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nocf_check";
    OS << "]]";
    break;
  }
}
}

const char *AnyX86NoCfCheckAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nocf_check";
  case 1:
    return "nocf_check";
  case 2:
    return "nocf_check";
  }
}


// ArcWeakrefUnavailableAttr implementation

ArcWeakrefUnavailableAttr *ArcWeakrefUnavailableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArcWeakrefUnavailableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArcWeakrefUnavailableAttr *ArcWeakrefUnavailableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArcWeakrefUnavailableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArcWeakrefUnavailableAttr *ArcWeakrefUnavailableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ArcWeakrefUnavailableAttr *ArcWeakrefUnavailableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ArcWeakrefUnavailableAttr::ArcWeakrefUnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ArcWeakrefUnavailable, false, false)
  {
}

ArcWeakrefUnavailableAttr *ArcWeakrefUnavailableAttr::clone(ASTContext &C) const {
  auto *A = new (C) ArcWeakrefUnavailableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ArcWeakrefUnavailableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_arc_weak_reference_unavailable";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_arc_weak_reference_unavailable";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_arc_weak_reference_unavailable";
    OS << "]]";
    break;
  }
}
}

const char *ArcWeakrefUnavailableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_arc_weak_reference_unavailable";
  case 1:
    return "objc_arc_weak_reference_unavailable";
  case 2:
    return "objc_arc_weak_reference_unavailable";
  }
}


// ArgumentWithTypeTagAttr implementation

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, bool IsPointer, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArgumentWithTypeTagAttr(Ctx, CommonInfo, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, bool IsPointer, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArgumentWithTypeTagAttr(Ctx, CommonInfo, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer);
  return A;
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, bool IsPointer, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ArgumentWithTypeTagAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer, I);
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, bool IsPointer, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ArgumentWithTypeTagAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer, I);
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArgumentWithTypeTagAttr(Ctx, CommonInfo, ArgumentKind, ArgumentIdx, TypeTagIdx);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArgumentWithTypeTagAttr(Ctx, CommonInfo, ArgumentKind, ArgumentIdx, TypeTagIdx);
  return A;
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ArgumentWithTypeTagAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, I);
}

ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ArgumentWithTypeTagAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, I);
}

ArgumentWithTypeTagAttr::ArgumentWithTypeTagAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * ArgumentKind
              , ParamIdx ArgumentIdx
              , ParamIdx TypeTagIdx
              , bool IsPointer
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ArgumentWithTypeTag, false, false)
              , argumentKind(ArgumentKind)
              , argumentIdx(ArgumentIdx)
              , typeTagIdx(TypeTagIdx)
              , isPointer(IsPointer)
  {
}

ArgumentWithTypeTagAttr::ArgumentWithTypeTagAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * ArgumentKind
              , ParamIdx ArgumentIdx
              , ParamIdx TypeTagIdx
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ArgumentWithTypeTag, false, false)
              , argumentKind(ArgumentKind)
              , argumentIdx(ArgumentIdx)
              , typeTagIdx(TypeTagIdx)
              , isPointer()
  {
}

ArgumentWithTypeTagAttr::Spelling ArgumentWithTypeTagAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_argument_with_type_tag;
    case 1: return CXX11_clang_argument_with_type_tag;
    case 2: return C2x_clang_argument_with_type_tag;
    case 3: return GNU_pointer_with_type_tag;
    case 4: return CXX11_clang_pointer_with_type_tag;
    case 5: return C2x_clang_pointer_with_type_tag;
  }
}








ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::clone(ASTContext &C) const {
  auto *A = new (C) ArgumentWithTypeTagAttr(C, *this, argumentKind, argumentIdx, typeTagIdx, isPointer);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ArgumentWithTypeTagAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((argument_with_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentIdx().getSourceIndex() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeTagIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::argument_with_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentIdx().getSourceIndex() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeTagIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::argument_with_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentIdx().getSourceIndex() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeTagIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((pointer_with_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentIdx().getSourceIndex() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeTagIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::pointer_with_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentIdx().getSourceIndex() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeTagIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::pointer_with_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentIdx().getSourceIndex() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeTagIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ArgumentWithTypeTagAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "argument_with_type_tag";
  case 1:
    return "argument_with_type_tag";
  case 2:
    return "argument_with_type_tag";
  case 3:
    return "pointer_with_type_tag";
  case 4:
    return "pointer_with_type_tag";
  case 5:
    return "pointer_with_type_tag";
  }
}


// ArmBuiltinAliasAttr implementation

ArmBuiltinAliasAttr *ArmBuiltinAliasAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BuiltinName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArmBuiltinAliasAttr(Ctx, CommonInfo, BuiltinName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArmBuiltinAliasAttr *ArmBuiltinAliasAttr::Create(ASTContext &Ctx, IdentifierInfo * BuiltinName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArmBuiltinAliasAttr(Ctx, CommonInfo, BuiltinName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArmBuiltinAliasAttr *ArmBuiltinAliasAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BuiltinName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BuiltinName, I);
}

ArmBuiltinAliasAttr *ArmBuiltinAliasAttr::Create(ASTContext &Ctx, IdentifierInfo * BuiltinName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BuiltinName, I);
}

ArmBuiltinAliasAttr::ArmBuiltinAliasAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * BuiltinName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ArmBuiltinAlias, false, false)
              , builtinName(BuiltinName)
  {
}



ArmBuiltinAliasAttr *ArmBuiltinAliasAttr::clone(ASTContext &C) const {
  auto *A = new (C) ArmBuiltinAliasAttr(C, *this, builtinName);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ArmBuiltinAliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((__clang_arm_builtin_alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBuiltinName() ? getBuiltinName()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::__clang_arm_builtin_alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBuiltinName() ? getBuiltinName()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::__clang_arm_builtin_alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBuiltinName() ? getBuiltinName()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ArmBuiltinAliasAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__clang_arm_builtin_alias";
  case 1:
    return "__clang_arm_builtin_alias";
  case 2:
    return "__clang_arm_builtin_alias";
  }
}


// ArmMveStrictPolymorphismAttr implementation

ArmMveStrictPolymorphismAttr *ArmMveStrictPolymorphismAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArmMveStrictPolymorphismAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArmMveStrictPolymorphismAttr *ArmMveStrictPolymorphismAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArmMveStrictPolymorphismAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArmMveStrictPolymorphismAttr *ArmMveStrictPolymorphismAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ArmMveStrictPolymorphismAttr *ArmMveStrictPolymorphismAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ArmMveStrictPolymorphismAttr::ArmMveStrictPolymorphismAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::ArmMveStrictPolymorphism, false)
  {
}

ArmMveStrictPolymorphismAttr *ArmMveStrictPolymorphismAttr::clone(ASTContext &C) const {
  auto *A = new (C) ArmMveStrictPolymorphismAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ArmMveStrictPolymorphismAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((__clang_arm_mve_strict_polymorphism";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::__clang_arm_mve_strict_polymorphism";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::__clang_arm_mve_strict_polymorphism";
    OS << "]]";
    break;
  }
}
}

const char *ArmMveStrictPolymorphismAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__clang_arm_mve_strict_polymorphism";
  case 1:
    return "__clang_arm_mve_strict_polymorphism";
  case 2:
    return "__clang_arm_mve_strict_polymorphism";
  }
}


// ArtificialAttr implementation

ArtificialAttr *ArtificialAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArtificialAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArtificialAttr *ArtificialAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ArtificialAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ArtificialAttr *ArtificialAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ArtificialAttr *ArtificialAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ArtificialAttr::ArtificialAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Artificial, false, false)
  {
}

ArtificialAttr *ArtificialAttr::clone(ASTContext &C) const {
  auto *A = new (C) ArtificialAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ArtificialAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((artificial";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::artificial";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::artificial";
    OS << "]]";
    break;
  }
}
}

const char *ArtificialAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "artificial";
  case 1:
    return "artificial";
  case 2:
    return "artificial";
  }
}


// AsmLabelAttr implementation

AsmLabelAttr *AsmLabelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, bool IsLiteralLabel, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AsmLabelAttr(Ctx, CommonInfo, Label, IsLiteralLabel);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AsmLabelAttr *AsmLabelAttr::Create(ASTContext &Ctx, llvm::StringRef Label, bool IsLiteralLabel, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AsmLabelAttr(Ctx, CommonInfo, Label, IsLiteralLabel);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AsmLabelAttr *AsmLabelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, bool IsLiteralLabel, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Label, IsLiteralLabel, I);
}

AsmLabelAttr *AsmLabelAttr::Create(ASTContext &Ctx, llvm::StringRef Label, bool IsLiteralLabel, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Label, IsLiteralLabel, I);
}

AsmLabelAttr *AsmLabelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AsmLabelAttr(Ctx, CommonInfo, Label);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AsmLabelAttr *AsmLabelAttr::Create(ASTContext &Ctx, llvm::StringRef Label, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AsmLabelAttr(Ctx, CommonInfo, Label);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AsmLabelAttr *AsmLabelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Label, I);
}

AsmLabelAttr *AsmLabelAttr::Create(ASTContext &Ctx, llvm::StringRef Label, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Label, I);
}

AsmLabelAttr::AsmLabelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Label
              , bool IsLiteralLabel
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AsmLabel, false, false)
              , labelLength(Label.size()),label(new (Ctx, 1) char[labelLength])
              , isLiteralLabel(IsLiteralLabel)
  {
    if (!Label.empty())
      std::memcpy(label, Label.data(), labelLength);
}

AsmLabelAttr::AsmLabelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Label
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AsmLabel, false, false)
              , labelLength(Label.size()),label(new (Ctx, 1) char[labelLength])
              , isLiteralLabel()
  {
    if (!Label.empty())
      std::memcpy(label, Label.data(), labelLength);
}





AsmLabelAttr *AsmLabelAttr::clone(ASTContext &C) const {
  auto *A = new (C) AsmLabelAttr(C, *this, getLabel(), isLiteralLabel);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AsmLabelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " asm";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getLabel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "";
    break;
  }
  case 1 : {
    OS << " __asm__";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getLabel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "";
    break;
  }
}
}

const char *AsmLabelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "asm";
  case 1:
    return "__asm__";
  }
}


// AssertCapabilityAttr implementation

AssertCapabilityAttr *AssertCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssertCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssertCapabilityAttr *AssertCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssertCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  return A;
}

AssertCapabilityAttr *AssertCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AssertCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

AssertCapabilityAttr *AssertCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, AssertCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Args, ArgsSize, I);
}

AssertCapabilityAttr::AssertCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssertCapability, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

AssertCapabilityAttr::AssertCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssertCapability, true, true)
              , args_Size(0), args_(nullptr)
  {
}

AssertCapabilityAttr::Spelling AssertCapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_assert_capability;
    case 1: return CXX11_clang_assert_capability;
    case 2: return GNU_assert_shared_capability;
    case 3: return CXX11_clang_assert_shared_capability;
  }
}


AssertCapabilityAttr *AssertCapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) AssertCapabilityAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AssertCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((assert_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::assert_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((assert_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::assert_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AssertCapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "assert_capability";
  case 1:
    return "assert_capability";
  case 2:
    return "assert_shared_capability";
  case 3:
    return "assert_shared_capability";
  }
}


// AssertExclusiveLockAttr implementation

AssertExclusiveLockAttr *AssertExclusiveLockAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssertExclusiveLockAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssertExclusiveLockAttr *AssertExclusiveLockAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssertExclusiveLockAttr(Ctx, CommonInfo, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssertExclusiveLockAttr *AssertExclusiveLockAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

AssertExclusiveLockAttr *AssertExclusiveLockAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Args, ArgsSize, I);
}

AssertExclusiveLockAttr::AssertExclusiveLockAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssertExclusiveLock, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

AssertExclusiveLockAttr::AssertExclusiveLockAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssertExclusiveLock, true, true)
              , args_Size(0), args_(nullptr)
  {
}



AssertExclusiveLockAttr *AssertExclusiveLockAttr::clone(ASTContext &C) const {
  auto *A = new (C) AssertExclusiveLockAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AssertExclusiveLockAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((assert_exclusive_lock";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *AssertExclusiveLockAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "assert_exclusive_lock";
  }
}


// AssertSharedLockAttr implementation

AssertSharedLockAttr *AssertSharedLockAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssertSharedLockAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssertSharedLockAttr *AssertSharedLockAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssertSharedLockAttr(Ctx, CommonInfo, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssertSharedLockAttr *AssertSharedLockAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

AssertSharedLockAttr *AssertSharedLockAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Args, ArgsSize, I);
}

AssertSharedLockAttr::AssertSharedLockAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssertSharedLock, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

AssertSharedLockAttr::AssertSharedLockAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssertSharedLock, true, true)
              , args_Size(0), args_(nullptr)
  {
}



AssertSharedLockAttr *AssertSharedLockAttr::clone(ASTContext &C) const {
  auto *A = new (C) AssertSharedLockAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AssertSharedLockAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((assert_shared_lock";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *AssertSharedLockAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "assert_shared_lock";
  }
}


// AssumeAlignedAttr implementation

AssumeAlignedAttr *AssumeAlignedAttr::CreateImplicit(ASTContext &Ctx, Expr * Alignment, Expr * Offset, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssumeAlignedAttr(Ctx, CommonInfo, Alignment, Offset);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssumeAlignedAttr *AssumeAlignedAttr::Create(ASTContext &Ctx, Expr * Alignment, Expr * Offset, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssumeAlignedAttr(Ctx, CommonInfo, Alignment, Offset);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssumeAlignedAttr *AssumeAlignedAttr::CreateImplicit(ASTContext &Ctx, Expr * Alignment, Expr * Offset, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Alignment, Offset, I);
}

AssumeAlignedAttr *AssumeAlignedAttr::Create(ASTContext &Ctx, Expr * Alignment, Expr * Offset, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Alignment, Offset, I);
}

AssumeAlignedAttr::AssumeAlignedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Alignment
              , Expr * Offset
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssumeAligned, false, false)
              , alignment(Alignment)
              , offset(Offset)
  {
}

AssumeAlignedAttr::AssumeAlignedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Alignment
             )
  : InheritableAttr(Ctx, CommonInfo, attr::AssumeAligned, false, false)
              , alignment(Alignment)
              , offset()
  {
}





AssumeAlignedAttr *AssumeAlignedAttr::clone(ASTContext &C) const {
  auto *A = new (C) AssumeAlignedAttr(C, *this, alignment, offset);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AssumeAlignedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((assume_aligned";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAlignment() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::assume_aligned";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAlignment() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::assume_aligned";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getAlignment() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AssumeAlignedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "assume_aligned";
  case 1:
    return "assume_aligned";
  case 2:
    return "assume_aligned";
  }
}


// AssumptionAttr implementation

AssumptionAttr *AssumptionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Assumption, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssumptionAttr(Ctx, CommonInfo, Assumption);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssumptionAttr *AssumptionAttr::Create(ASTContext &Ctx, llvm::StringRef Assumption, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AssumptionAttr(Ctx, CommonInfo, Assumption);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AssumptionAttr *AssumptionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Assumption, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Assumption, I);
}

AssumptionAttr *AssumptionAttr::Create(ASTContext &Ctx, llvm::StringRef Assumption, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Assumption, I);
}

AssumptionAttr::AssumptionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Assumption
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Assumption, false, true)
              , assumptionLength(Assumption.size()),assumption(new (Ctx, 1) char[assumptionLength])
  {
    if (!Assumption.empty())
      std::memcpy(assumption, Assumption.data(), assumptionLength);
}



AssumptionAttr *AssumptionAttr::clone(ASTContext &C) const {
  auto *A = new (C) AssumptionAttr(C, *this, getAssumption());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AssumptionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((assume";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAssumption() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::assume";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAssumption() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::assume";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAssumption() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AssumptionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "assume";
  case 1:
    return "assume";
  case 2:
    return "assume";
  }
}


// AvailabilityAttr implementation

AvailabilityAttr *AvailabilityAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, bool Strict, llvm::StringRef Replacement, int Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AvailabilityAttr(Ctx, CommonInfo, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, Strict, Replacement, Priority);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AvailabilityAttr *AvailabilityAttr::Create(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, bool Strict, llvm::StringRef Replacement, int Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) AvailabilityAttr(Ctx, CommonInfo, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, Strict, Replacement, Priority);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

AvailabilityAttr *AvailabilityAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, bool Strict, llvm::StringRef Replacement, int Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, Strict, Replacement, Priority, I);
}

AvailabilityAttr *AvailabilityAttr::Create(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, bool Strict, llvm::StringRef Replacement, int Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, Strict, Replacement, Priority, I);
}

AvailabilityAttr::AvailabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Platform
              , VersionTuple Introduced
              , VersionTuple Deprecated
              , VersionTuple Obsoleted
              , bool Unavailable
              , llvm::StringRef Message
              , bool Strict
              , llvm::StringRef Replacement
              , int Priority
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Availability, false, true)
              , platform(Platform)
              , introduced(Introduced)
              , deprecated(Deprecated)
              , obsoleted(Obsoleted)
              , unavailable(Unavailable)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , strict(Strict)
              , replacementLength(Replacement.size()),replacement(new (Ctx, 1) char[replacementLength])
              , priority(Priority)
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
    if (!Replacement.empty())
      std::memcpy(replacement, Replacement.data(), replacementLength);
}



















AvailabilityAttr *AvailabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) AvailabilityAttr(C, *this, platform, getIntroduced(), getDeprecated(), getObsoleted(), unavailable, getMessage(), strict, getReplacement(), priority);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void AvailabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((availability";
    OS << "(" << getPlatform()->getName();
  if (getStrict()) OS << ", strict";
  if (!getIntroduced().empty()) OS << ", introduced=" << getIntroduced();
  if (!getDeprecated().empty()) OS << ", deprecated=" << getDeprecated();
  if (!getObsoleted().empty()) OS << ", obsoleted=" << getObsoleted();
  if (getUnavailable()) OS << ", unavailable";
  OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::availability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getPlatform() ? getPlatform()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "introduced=" << getIntroduced() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "deprecated=" << getDeprecated() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "obsoleted=" << getObsoleted() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getUnavailable() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getStrict() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getReplacement() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::availability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getPlatform() ? getPlatform()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "introduced=" << getIntroduced() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "deprecated=" << getDeprecated() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "obsoleted=" << getObsoleted() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getUnavailable() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getStrict() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getReplacement() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *AvailabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "availability";
  case 1:
    return "availability";
  case 2:
    return "availability";
  }
}


// BPFPreserveAccessIndexAttr implementation

BPFPreserveAccessIndexAttr *BPFPreserveAccessIndexAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BPFPreserveAccessIndexAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BPFPreserveAccessIndexAttr *BPFPreserveAccessIndexAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BPFPreserveAccessIndexAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BPFPreserveAccessIndexAttr *BPFPreserveAccessIndexAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

BPFPreserveAccessIndexAttr *BPFPreserveAccessIndexAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

BPFPreserveAccessIndexAttr::BPFPreserveAccessIndexAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::BPFPreserveAccessIndex, false, false)
  {
}

BPFPreserveAccessIndexAttr *BPFPreserveAccessIndexAttr::clone(ASTContext &C) const {
  auto *A = new (C) BPFPreserveAccessIndexAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void BPFPreserveAccessIndexAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preserve_access_index";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preserve_access_index";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::preserve_access_index";
    OS << "]]";
    break;
  }
}
}

const char *BPFPreserveAccessIndexAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preserve_access_index";
  case 1:
    return "preserve_access_index";
  case 2:
    return "preserve_access_index";
  }
}


// BTFDeclTagAttr implementation

BTFDeclTagAttr *BTFDeclTagAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef BTFDeclTag, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BTFDeclTagAttr(Ctx, CommonInfo, BTFDeclTag);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BTFDeclTagAttr *BTFDeclTagAttr::Create(ASTContext &Ctx, llvm::StringRef BTFDeclTag, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BTFDeclTagAttr(Ctx, CommonInfo, BTFDeclTag);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BTFDeclTagAttr *BTFDeclTagAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef BTFDeclTag, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BTFDeclTag, I);
}

BTFDeclTagAttr *BTFDeclTagAttr::Create(ASTContext &Ctx, llvm::StringRef BTFDeclTag, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BTFDeclTag, I);
}

BTFDeclTagAttr::BTFDeclTagAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef BTFDeclTag
             )
  : InheritableAttr(Ctx, CommonInfo, attr::BTFDeclTag, false, false)
              , bTFDeclTagLength(BTFDeclTag.size()),bTFDeclTag(new (Ctx, 1) char[bTFDeclTagLength])
  {
    if (!BTFDeclTag.empty())
      std::memcpy(bTFDeclTag, BTFDeclTag.data(), bTFDeclTagLength);
}



BTFDeclTagAttr *BTFDeclTagAttr::clone(ASTContext &C) const {
  auto *A = new (C) BTFDeclTagAttr(C, *this, getBTFDeclTag());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void BTFDeclTagAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((btf_decl_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getBTFDeclTag() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::btf_decl_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getBTFDeclTag() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::btf_decl_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getBTFDeclTag() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *BTFDeclTagAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "btf_decl_tag";
  case 1:
    return "btf_decl_tag";
  case 2:
    return "btf_decl_tag";
  }
}


// BTFTypeTagAttr implementation

BTFTypeTagAttr *BTFTypeTagAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef BTFTypeTag, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BTFTypeTagAttr(Ctx, CommonInfo, BTFTypeTag);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BTFTypeTagAttr *BTFTypeTagAttr::Create(ASTContext &Ctx, llvm::StringRef BTFTypeTag, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BTFTypeTagAttr(Ctx, CommonInfo, BTFTypeTag);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BTFTypeTagAttr *BTFTypeTagAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef BTFTypeTag, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BTFTypeTag, I);
}

BTFTypeTagAttr *BTFTypeTagAttr::Create(ASTContext &Ctx, llvm::StringRef BTFTypeTag, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BTFTypeTag, I);
}

BTFTypeTagAttr::BTFTypeTagAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef BTFTypeTag
             )
  : TypeAttr(Ctx, CommonInfo, attr::BTFTypeTag, false)
              , bTFTypeTagLength(BTFTypeTag.size()),bTFTypeTag(new (Ctx, 1) char[bTFTypeTagLength])
  {
    if (!BTFTypeTag.empty())
      std::memcpy(bTFTypeTag, BTFTypeTag.data(), bTFTypeTagLength);
}



BTFTypeTagAttr *BTFTypeTagAttr::clone(ASTContext &C) const {
  auto *A = new (C) BTFTypeTagAttr(C, *this, getBTFTypeTag());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void BTFTypeTagAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((btf_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getBTFTypeTag() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::btf_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getBTFTypeTag() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::btf_type_tag";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getBTFTypeTag() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *BTFTypeTagAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "btf_type_tag";
  case 1:
    return "btf_type_tag";
  case 2:
    return "btf_type_tag";
  }
}


// BlocksAttr implementation

BlocksAttr *BlocksAttr::CreateImplicit(ASTContext &Ctx, BlockType Type, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BlocksAttr(Ctx, CommonInfo, Type);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BlocksAttr *BlocksAttr::Create(ASTContext &Ctx, BlockType Type, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BlocksAttr(Ctx, CommonInfo, Type);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BlocksAttr *BlocksAttr::CreateImplicit(ASTContext &Ctx, BlockType Type, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Type, I);
}

BlocksAttr *BlocksAttr::Create(ASTContext &Ctx, BlockType Type, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Type, I);
}

BlocksAttr::BlocksAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , BlockType Type
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Blocks, false, false)
              , type(Type)
  {
}



bool BlocksAttr::ConvertStrToBlockType(StringRef Val, BlockType &Out) {
  Optional<BlockType> R = llvm::StringSwitch<Optional<BlockType>>(Val)
    .Case("byref", BlocksAttr::ByRef)
    .Default(Optional<BlockType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *BlocksAttr::ConvertBlockTypeToStr(BlockType Val) {
  switch(Val) {
  case BlocksAttr::ByRef: return "byref";
  }
  llvm_unreachable("No enumerator with that value");
}
BlocksAttr *BlocksAttr::clone(ASTContext &C) const {
  auto *A = new (C) BlocksAttr(C, *this, type);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void BlocksAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((blocks";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << BlocksAttr::ConvertBlockTypeToStr(getType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::blocks";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << BlocksAttr::ConvertBlockTypeToStr(getType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::blocks";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << BlocksAttr::ConvertBlockTypeToStr(getType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *BlocksAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "blocks";
  case 1:
    return "blocks";
  case 2:
    return "blocks";
  }
}


// BuiltinAttr implementation

BuiltinAttr *BuiltinAttr::CreateImplicit(ASTContext &Ctx, unsigned ID, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BuiltinAttr(Ctx, CommonInfo, ID);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BuiltinAttr *BuiltinAttr::Create(ASTContext &Ctx, unsigned ID, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BuiltinAttr(Ctx, CommonInfo, ID);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BuiltinAttr *BuiltinAttr::CreateImplicit(ASTContext &Ctx, unsigned ID, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ID, I);
}

BuiltinAttr *BuiltinAttr::Create(ASTContext &Ctx, unsigned ID, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ID, I);
}

BuiltinAttr::BuiltinAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned ID
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Builtin, false, false)
              , iD(ID)
  {
}



BuiltinAttr *BuiltinAttr::clone(ASTContext &C) const {
  auto *A = new (C) BuiltinAttr(C, *this, iD);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void BuiltinAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *BuiltinAttr::getSpelling() const {
  return "(No spelling)";
}


// BuiltinAliasAttr implementation

BuiltinAliasAttr *BuiltinAliasAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BuiltinName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BuiltinAliasAttr(Ctx, CommonInfo, BuiltinName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

BuiltinAliasAttr *BuiltinAliasAttr::Create(ASTContext &Ctx, IdentifierInfo * BuiltinName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) BuiltinAliasAttr(Ctx, CommonInfo, BuiltinName);
  return A;
}

BuiltinAliasAttr *BuiltinAliasAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BuiltinName, SourceRange Range, AttributeCommonInfo::Syntax Syntax, BuiltinAliasAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, BuiltinName, I);
}

BuiltinAliasAttr *BuiltinAliasAttr::Create(ASTContext &Ctx, IdentifierInfo * BuiltinName, SourceRange Range, AttributeCommonInfo::Syntax Syntax, BuiltinAliasAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, BuiltinName, I);
}

BuiltinAliasAttr::BuiltinAliasAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * BuiltinName
             )
  : Attr(Ctx, CommonInfo, attr::BuiltinAlias, false)
              , builtinName(BuiltinName)
  {
}

BuiltinAliasAttr::Spelling BuiltinAliasAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return CXX11_clang_builtin_alias;
    case 1: return C2x_clang_builtin_alias;
    case 2: return GNU_clang_builtin_alias;
  }
}


BuiltinAliasAttr *BuiltinAliasAttr::clone(ASTContext &C) const {
  auto *A = new (C) BuiltinAliasAttr(C, *this, builtinName);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void BuiltinAliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[clang::builtin_alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBuiltinName() ? getBuiltinName()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[clang::builtin_alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBuiltinName() ? getBuiltinName()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((clang_builtin_alias";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBuiltinName() ? getBuiltinName()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *BuiltinAliasAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "builtin_alias";
  case 1:
    return "builtin_alias";
  case 2:
    return "clang_builtin_alias";
  }
}


// C11NoReturnAttr implementation

C11NoReturnAttr *C11NoReturnAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) C11NoReturnAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

C11NoReturnAttr *C11NoReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) C11NoReturnAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

C11NoReturnAttr *C11NoReturnAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

C11NoReturnAttr *C11NoReturnAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

C11NoReturnAttr::C11NoReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::C11NoReturn, false, false)
  {
}

C11NoReturnAttr *C11NoReturnAttr::clone(ASTContext &C) const {
  auto *A = new (C) C11NoReturnAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void C11NoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Noreturn";
    OS << "";
    break;
  }
}
}

const char *C11NoReturnAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Noreturn";
  }
}


// CDeclAttr implementation

CDeclAttr *CDeclAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CDeclAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CDeclAttr *CDeclAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CDeclAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CDeclAttr *CDeclAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CDeclAttr *CDeclAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CDeclAttr::CDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CDecl, false, false)
  {
}

CDeclAttr *CDeclAttr::clone(ASTContext &C) const {
  auto *A = new (C) CDeclAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cdecl";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::cdecl";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::cdecl";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __cdecl";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _cdecl";
    OS << "";
    break;
  }
}
}

const char *CDeclAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cdecl";
  case 1:
    return "cdecl";
  case 2:
    return "cdecl";
  case 3:
    return "__cdecl";
  case 4:
    return "_cdecl";
  }
}


// CFAuditedTransferAttr implementation

CFAuditedTransferAttr *CFAuditedTransferAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFAuditedTransferAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFAuditedTransferAttr *CFAuditedTransferAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFAuditedTransferAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFAuditedTransferAttr *CFAuditedTransferAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CFAuditedTransferAttr *CFAuditedTransferAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CFAuditedTransferAttr::CFAuditedTransferAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CFAuditedTransfer, false, false)
  {
}

CFAuditedTransferAttr *CFAuditedTransferAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFAuditedTransferAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFAuditedTransferAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cf_audited_transfer";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cf_audited_transfer";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cf_audited_transfer";
    OS << "]]";
    break;
  }
}
}

const char *CFAuditedTransferAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cf_audited_transfer";
  case 1:
    return "cf_audited_transfer";
  case 2:
    return "cf_audited_transfer";
  }
}


// CFConsumedAttr implementation

CFConsumedAttr *CFConsumedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFConsumedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFConsumedAttr *CFConsumedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFConsumedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFConsumedAttr *CFConsumedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CFConsumedAttr *CFConsumedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CFConsumedAttr::CFConsumedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::CFConsumed, false, false)
  {
}

CFConsumedAttr *CFConsumedAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFConsumedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFConsumedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cf_consumed";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cf_consumed";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cf_consumed";
    OS << "]]";
    break;
  }
}
}

const char *CFConsumedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cf_consumed";
  case 1:
    return "cf_consumed";
  case 2:
    return "cf_consumed";
  }
}


// CFGuardAttr implementation

CFGuardAttr *CFGuardAttr::CreateImplicit(ASTContext &Ctx, GuardArg Guard, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFGuardAttr(Ctx, CommonInfo, Guard);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFGuardAttr *CFGuardAttr::Create(ASTContext &Ctx, GuardArg Guard, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFGuardAttr(Ctx, CommonInfo, Guard);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFGuardAttr *CFGuardAttr::CreateImplicit(ASTContext &Ctx, GuardArg Guard, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Guard, I);
}

CFGuardAttr *CFGuardAttr::Create(ASTContext &Ctx, GuardArg Guard, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Guard, I);
}

CFGuardAttr::CFGuardAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , GuardArg Guard
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CFGuard, false, false)
              , guard(Guard)
  {
}



bool CFGuardAttr::ConvertStrToGuardArg(StringRef Val, GuardArg &Out) {
  Optional<GuardArg> R = llvm::StringSwitch<Optional<GuardArg>>(Val)
    .Case("nocf", CFGuardAttr::nocf)
    .Default(Optional<GuardArg>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *CFGuardAttr::ConvertGuardArgToStr(GuardArg Val) {
  switch(Val) {
  case CFGuardAttr::nocf: return "nocf";
  }
  llvm_unreachable("No enumerator with that value");
}
CFGuardAttr *CFGuardAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFGuardAttr(C, *this, guard);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFGuardAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(guard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << CFGuardAttr::ConvertGuardArgToStr(getGuard()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
  case 1 : {
    OS << " __attribute__((guard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << CFGuardAttr::ConvertGuardArgToStr(getGuard()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[clang::guard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << CFGuardAttr::ConvertGuardArgToStr(getGuard()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[clang::guard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << CFGuardAttr::ConvertGuardArgToStr(getGuard()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *CFGuardAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "guard";
  case 1:
    return "guard";
  case 2:
    return "guard";
  case 3:
    return "guard";
  }
}


// CFICanonicalJumpTableAttr implementation

CFICanonicalJumpTableAttr *CFICanonicalJumpTableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFICanonicalJumpTableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFICanonicalJumpTableAttr *CFICanonicalJumpTableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFICanonicalJumpTableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFICanonicalJumpTableAttr *CFICanonicalJumpTableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CFICanonicalJumpTableAttr *CFICanonicalJumpTableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CFICanonicalJumpTableAttr::CFICanonicalJumpTableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CFICanonicalJumpTable, false, false)
  {
}

CFICanonicalJumpTableAttr *CFICanonicalJumpTableAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFICanonicalJumpTableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFICanonicalJumpTableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cfi_canonical_jump_table";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cfi_canonical_jump_table";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cfi_canonical_jump_table";
    OS << "]]";
    break;
  }
}
}

const char *CFICanonicalJumpTableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cfi_canonical_jump_table";
  case 1:
    return "cfi_canonical_jump_table";
  case 2:
    return "cfi_canonical_jump_table";
  }
}


// CFReturnsNotRetainedAttr implementation

CFReturnsNotRetainedAttr *CFReturnsNotRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFReturnsNotRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFReturnsNotRetainedAttr *CFReturnsNotRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFReturnsNotRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFReturnsNotRetainedAttr *CFReturnsNotRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CFReturnsNotRetainedAttr *CFReturnsNotRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CFReturnsNotRetainedAttr::CFReturnsNotRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CFReturnsNotRetained, false, false)
  {
}

CFReturnsNotRetainedAttr *CFReturnsNotRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFReturnsNotRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFReturnsNotRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cf_returns_not_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cf_returns_not_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cf_returns_not_retained";
    OS << "]]";
    break;
  }
}
}

const char *CFReturnsNotRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cf_returns_not_retained";
  case 1:
    return "cf_returns_not_retained";
  case 2:
    return "cf_returns_not_retained";
  }
}


// CFReturnsRetainedAttr implementation

CFReturnsRetainedAttr *CFReturnsRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFReturnsRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFReturnsRetainedAttr *CFReturnsRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFReturnsRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFReturnsRetainedAttr *CFReturnsRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CFReturnsRetainedAttr *CFReturnsRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CFReturnsRetainedAttr::CFReturnsRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CFReturnsRetained, false, false)
  {
}

CFReturnsRetainedAttr *CFReturnsRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFReturnsRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFReturnsRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cf_returns_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cf_returns_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cf_returns_retained";
    OS << "]]";
    break;
  }
}
}

const char *CFReturnsRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cf_returns_retained";
  case 1:
    return "cf_returns_retained";
  case 2:
    return "cf_returns_retained";
  }
}


// CFUnknownTransferAttr implementation

CFUnknownTransferAttr *CFUnknownTransferAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFUnknownTransferAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFUnknownTransferAttr *CFUnknownTransferAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CFUnknownTransferAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CFUnknownTransferAttr *CFUnknownTransferAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CFUnknownTransferAttr *CFUnknownTransferAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CFUnknownTransferAttr::CFUnknownTransferAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CFUnknownTransfer, false, false)
  {
}

CFUnknownTransferAttr *CFUnknownTransferAttr::clone(ASTContext &C) const {
  auto *A = new (C) CFUnknownTransferAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CFUnknownTransferAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cf_unknown_transfer";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cf_unknown_transfer";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cf_unknown_transfer";
    OS << "]]";
    break;
  }
}
}

const char *CFUnknownTransferAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cf_unknown_transfer";
  case 1:
    return "cf_unknown_transfer";
  case 2:
    return "cf_unknown_transfer";
  }
}


// CPUDispatchAttr implementation

CPUDispatchAttr *CPUDispatchAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CPUDispatchAttr(Ctx, CommonInfo, Cpus, CpusSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CPUDispatchAttr *CPUDispatchAttr::Create(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CPUDispatchAttr(Ctx, CommonInfo, Cpus, CpusSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CPUDispatchAttr *CPUDispatchAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Cpus, CpusSize, I);
}

CPUDispatchAttr *CPUDispatchAttr::Create(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Cpus, CpusSize, I);
}

CPUDispatchAttr::CPUDispatchAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * *Cpus, unsigned CpusSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CPUDispatch, false, false)
              , cpus_Size(CpusSize), cpus_(new (Ctx, 16) IdentifierInfo *[cpus_Size])
  {
  std::copy(Cpus, Cpus + cpus_Size, cpus_);
}

CPUDispatchAttr::CPUDispatchAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CPUDispatch, false, false)
              , cpus_Size(0), cpus_(nullptr)
  {
}



CPUDispatchAttr *CPUDispatchAttr::clone(ASTContext &C) const {
  auto *A = new (C) CPUDispatchAttr(C, *this, cpus_, cpus_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CPUDispatchAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cpu_dispatch";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cpu_dispatch";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cpu_dispatch";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(cpu_dispatch";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
}
}

const char *CPUDispatchAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cpu_dispatch";
  case 1:
    return "cpu_dispatch";
  case 2:
    return "cpu_dispatch";
  case 3:
    return "cpu_dispatch";
  }
}


// CPUSpecificAttr implementation

CPUSpecificAttr *CPUSpecificAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CPUSpecificAttr(Ctx, CommonInfo, Cpus, CpusSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CPUSpecificAttr *CPUSpecificAttr::Create(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CPUSpecificAttr(Ctx, CommonInfo, Cpus, CpusSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CPUSpecificAttr *CPUSpecificAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Cpus, CpusSize, I);
}

CPUSpecificAttr *CPUSpecificAttr::Create(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Cpus, CpusSize, I);
}

CPUSpecificAttr::CPUSpecificAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * *Cpus, unsigned CpusSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CPUSpecific, false, false)
              , cpus_Size(CpusSize), cpus_(new (Ctx, 16) IdentifierInfo *[cpus_Size])
  {
  std::copy(Cpus, Cpus + cpus_Size, cpus_);
}

CPUSpecificAttr::CPUSpecificAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CPUSpecific, false, false)
              , cpus_Size(0), cpus_(nullptr)
  {
}



CPUSpecificAttr *CPUSpecificAttr::clone(ASTContext &C) const {
  auto *A = new (C) CPUSpecificAttr(C, *this, cpus_, cpus_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CPUSpecificAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cpu_specific";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::cpu_specific";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::cpu_specific";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(cpu_specific";
    OS << "";
  for (const auto &Val : cpus()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
}
}

const char *CPUSpecificAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cpu_specific";
  case 1:
    return "cpu_specific";
  case 2:
    return "cpu_specific";
  case 3:
    return "cpu_specific";
  }
}


// CUDAConstantAttr implementation

CUDAConstantAttr *CUDAConstantAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAConstantAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAConstantAttr *CUDAConstantAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAConstantAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAConstantAttr *CUDAConstantAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDAConstantAttr *CUDAConstantAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDAConstantAttr::CUDAConstantAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDAConstant, false, false)
  {
}

CUDAConstantAttr *CUDAConstantAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDAConstantAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDAConstantAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((constant";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__constant__";
    OS << ")";
    break;
  }
}
}

const char *CUDAConstantAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "constant";
  case 1:
    return "__constant__";
  }
}


// CUDADeviceAttr implementation

CUDADeviceAttr *CUDADeviceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDADeviceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDADeviceAttr *CUDADeviceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDADeviceAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDADeviceAttr *CUDADeviceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDADeviceAttr *CUDADeviceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDADeviceAttr::CUDADeviceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDADevice, false, false)
  {
}

CUDADeviceAttr *CUDADeviceAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDADeviceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDADeviceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((device";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__device__";
    OS << ")";
    break;
  }
}
}

const char *CUDADeviceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "device";
  case 1:
    return "__device__";
  }
}


// CUDADeviceBuiltinSurfaceTypeAttr implementation

CUDADeviceBuiltinSurfaceTypeAttr *CUDADeviceBuiltinSurfaceTypeAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDADeviceBuiltinSurfaceTypeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDADeviceBuiltinSurfaceTypeAttr *CUDADeviceBuiltinSurfaceTypeAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDADeviceBuiltinSurfaceTypeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDADeviceBuiltinSurfaceTypeAttr *CUDADeviceBuiltinSurfaceTypeAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDADeviceBuiltinSurfaceTypeAttr *CUDADeviceBuiltinSurfaceTypeAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDADeviceBuiltinSurfaceTypeAttr::CUDADeviceBuiltinSurfaceTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDADeviceBuiltinSurfaceType, false, false)
  {
}

CUDADeviceBuiltinSurfaceTypeAttr *CUDADeviceBuiltinSurfaceTypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDADeviceBuiltinSurfaceTypeAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDADeviceBuiltinSurfaceTypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((device_builtin_surface_type";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__device_builtin_surface_type__";
    OS << ")";
    break;
  }
}
}

const char *CUDADeviceBuiltinSurfaceTypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "device_builtin_surface_type";
  case 1:
    return "__device_builtin_surface_type__";
  }
}


// CUDADeviceBuiltinTextureTypeAttr implementation

CUDADeviceBuiltinTextureTypeAttr *CUDADeviceBuiltinTextureTypeAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDADeviceBuiltinTextureTypeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDADeviceBuiltinTextureTypeAttr *CUDADeviceBuiltinTextureTypeAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDADeviceBuiltinTextureTypeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDADeviceBuiltinTextureTypeAttr *CUDADeviceBuiltinTextureTypeAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDADeviceBuiltinTextureTypeAttr *CUDADeviceBuiltinTextureTypeAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDADeviceBuiltinTextureTypeAttr::CUDADeviceBuiltinTextureTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDADeviceBuiltinTextureType, false, false)
  {
}

CUDADeviceBuiltinTextureTypeAttr *CUDADeviceBuiltinTextureTypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDADeviceBuiltinTextureTypeAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDADeviceBuiltinTextureTypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((device_builtin_texture_type";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__device_builtin_texture_type__";
    OS << ")";
    break;
  }
}
}

const char *CUDADeviceBuiltinTextureTypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "device_builtin_texture_type";
  case 1:
    return "__device_builtin_texture_type__";
  }
}


// CUDAGlobalAttr implementation

CUDAGlobalAttr *CUDAGlobalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAGlobalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAGlobalAttr *CUDAGlobalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAGlobalAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAGlobalAttr *CUDAGlobalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDAGlobalAttr *CUDAGlobalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDAGlobalAttr::CUDAGlobalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDAGlobal, false, false)
  {
}

CUDAGlobalAttr *CUDAGlobalAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDAGlobalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDAGlobalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((global";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__global__";
    OS << ")";
    break;
  }
}
}

const char *CUDAGlobalAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "global";
  case 1:
    return "__global__";
  }
}


// CUDAHostAttr implementation

CUDAHostAttr *CUDAHostAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAHostAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAHostAttr *CUDAHostAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAHostAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAHostAttr *CUDAHostAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDAHostAttr *CUDAHostAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDAHostAttr::CUDAHostAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDAHost, false, false)
  {
}

CUDAHostAttr *CUDAHostAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDAHostAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDAHostAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((host";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__host__";
    OS << ")";
    break;
  }
}
}

const char *CUDAHostAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "host";
  case 1:
    return "__host__";
  }
}


// CUDAInvalidTargetAttr implementation

CUDAInvalidTargetAttr *CUDAInvalidTargetAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAInvalidTargetAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAInvalidTargetAttr *CUDAInvalidTargetAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDAInvalidTargetAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDAInvalidTargetAttr *CUDAInvalidTargetAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDAInvalidTargetAttr *CUDAInvalidTargetAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDAInvalidTargetAttr::CUDAInvalidTargetAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDAInvalidTarget, false, false)
  {
}

CUDAInvalidTargetAttr *CUDAInvalidTargetAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDAInvalidTargetAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDAInvalidTargetAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *CUDAInvalidTargetAttr::getSpelling() const {
  return "(No spelling)";
}


// CUDALaunchBoundsAttr implementation

CUDALaunchBoundsAttr *CUDALaunchBoundsAttr::CreateImplicit(ASTContext &Ctx, Expr * MaxThreads, Expr * MinBlocks, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDALaunchBoundsAttr(Ctx, CommonInfo, MaxThreads, MinBlocks);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDALaunchBoundsAttr *CUDALaunchBoundsAttr::Create(ASTContext &Ctx, Expr * MaxThreads, Expr * MinBlocks, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDALaunchBoundsAttr(Ctx, CommonInfo, MaxThreads, MinBlocks);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDALaunchBoundsAttr *CUDALaunchBoundsAttr::CreateImplicit(ASTContext &Ctx, Expr * MaxThreads, Expr * MinBlocks, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, MaxThreads, MinBlocks, I);
}

CUDALaunchBoundsAttr *CUDALaunchBoundsAttr::Create(ASTContext &Ctx, Expr * MaxThreads, Expr * MinBlocks, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, MaxThreads, MinBlocks, I);
}

CUDALaunchBoundsAttr::CUDALaunchBoundsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * MaxThreads
              , Expr * MinBlocks
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDALaunchBounds, false, false)
              , maxThreads(MaxThreads)
              , minBlocks(MinBlocks)
  {
}

CUDALaunchBoundsAttr::CUDALaunchBoundsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * MaxThreads
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDALaunchBounds, false, false)
              , maxThreads(MaxThreads)
              , minBlocks()
  {
}





CUDALaunchBoundsAttr *CUDALaunchBoundsAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDALaunchBoundsAttr(C, *this, maxThreads, minBlocks);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDALaunchBoundsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((launch_bounds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMaxThreads() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMinBlocks() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__launch_bounds__";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMaxThreads() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMinBlocks() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
}
}

const char *CUDALaunchBoundsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "launch_bounds";
  case 1:
    return "__launch_bounds__";
  }
}


// CUDASharedAttr implementation

CUDASharedAttr *CUDASharedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDASharedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDASharedAttr *CUDASharedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CUDASharedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CUDASharedAttr *CUDASharedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CUDASharedAttr *CUDASharedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CUDASharedAttr::CUDASharedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CUDAShared, false, false)
  {
}

CUDASharedAttr *CUDASharedAttr::clone(ASTContext &C) const {
  auto *A = new (C) CUDASharedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CUDASharedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((shared";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__shared__";
    OS << ")";
    break;
  }
}
}

const char *CUDASharedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "shared";
  case 1:
    return "__shared__";
  }
}


// CXX11NoReturnAttr implementation

CXX11NoReturnAttr *CXX11NoReturnAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CXX11NoReturnAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CXX11NoReturnAttr *CXX11NoReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CXX11NoReturnAttr(Ctx, CommonInfo);
  return A;
}

CXX11NoReturnAttr *CXX11NoReturnAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, CXX11NoReturnAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

CXX11NoReturnAttr *CXX11NoReturnAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, CXX11NoReturnAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

CXX11NoReturnAttr::CXX11NoReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CXX11NoReturn, false, false)
  {
}

CXX11NoReturnAttr::Spelling CXX11NoReturnAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return CXX11_noreturn;
    case 1: return C2x_noreturn;
    case 2: return C2x_Noreturn;
  }
}
CXX11NoReturnAttr *CXX11NoReturnAttr::clone(ASTContext &C) const {
  auto *A = new (C) CXX11NoReturnAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CXX11NoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[noreturn";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[noreturn";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[_Noreturn";
    OS << "]]";
    break;
  }
}
}

const char *CXX11NoReturnAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "noreturn";
  case 1:
    return "noreturn";
  case 2:
    return "_Noreturn";
  }
}


// CallableWhenAttr implementation

CallableWhenAttr *CallableWhenAttr::CreateImplicit(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CallableWhenAttr(Ctx, CommonInfo, CallableStates, CallableStatesSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CallableWhenAttr *CallableWhenAttr::Create(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CallableWhenAttr(Ctx, CommonInfo, CallableStates, CallableStatesSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CallableWhenAttr *CallableWhenAttr::CreateImplicit(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, CallableStates, CallableStatesSize, I);
}

CallableWhenAttr *CallableWhenAttr::Create(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, CallableStates, CallableStatesSize, I);
}

CallableWhenAttr::CallableWhenAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState *CallableStates, unsigned CallableStatesSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CallableWhen, false, false)
              , callableStates_Size(CallableStatesSize), callableStates_(new (Ctx, 16) ConsumedState[callableStates_Size])
  {
  std::copy(CallableStates, CallableStates + callableStates_Size, callableStates_);
}

CallableWhenAttr::CallableWhenAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CallableWhen, false, false)
              , callableStates_Size(0), callableStates_(nullptr)
  {
}



bool CallableWhenAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("unknown", CallableWhenAttr::Unknown)
    .Case("consumed", CallableWhenAttr::Consumed)
    .Case("unconsumed", CallableWhenAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *CallableWhenAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case CallableWhenAttr::Unknown: return "unknown";
  case CallableWhenAttr::Consumed: return "consumed";
  case CallableWhenAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
CallableWhenAttr *CallableWhenAttr::clone(ASTContext &C) const {
  auto *A = new (C) CallableWhenAttr(C, *this, callableStates_, callableStates_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CallableWhenAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((callable_when";
    OS << "";
  for (const auto &Val : callableStates()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << CallableWhenAttr::ConvertConsumedStateToStr(Val)<< "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::callable_when";
    OS << "";
  for (const auto &Val : callableStates()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << CallableWhenAttr::ConvertConsumedStateToStr(Val)<< "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *CallableWhenAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "callable_when";
  case 1:
    return "callable_when";
  }
}


// CallbackAttr implementation

CallbackAttr *CallbackAttr::CreateImplicit(ASTContext &Ctx, int *Encoding, unsigned EncodingSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CallbackAttr(Ctx, CommonInfo, Encoding, EncodingSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CallbackAttr *CallbackAttr::Create(ASTContext &Ctx, int *Encoding, unsigned EncodingSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CallbackAttr(Ctx, CommonInfo, Encoding, EncodingSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CallbackAttr *CallbackAttr::CreateImplicit(ASTContext &Ctx, int *Encoding, unsigned EncodingSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Encoding, EncodingSize, I);
}

CallbackAttr *CallbackAttr::Create(ASTContext &Ctx, int *Encoding, unsigned EncodingSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Encoding, EncodingSize, I);
}

CallbackAttr::CallbackAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int *Encoding, unsigned EncodingSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Callback, false, false)
              , encoding_Size(EncodingSize), encoding_(new (Ctx, 16) int[encoding_Size])
  {
  std::copy(Encoding, Encoding + encoding_Size, encoding_);
}

CallbackAttr::CallbackAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Callback, false, false)
              , encoding_Size(0), encoding_(nullptr)
  {
}



CallbackAttr *CallbackAttr::clone(ASTContext &C) const {
  auto *A = new (C) CallbackAttr(C, *this, encoding_, encoding_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CallbackAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((callback";
    OS << "";
  for (const auto &Val : encoding()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::callback";
    OS << "";
  for (const auto &Val : encoding()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::callback";
    OS << "";
  for (const auto &Val : encoding()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *CallbackAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "callback";
  case 1:
    return "callback";
  case 2:
    return "callback";
  }
}


// CalledOnceAttr implementation

CalledOnceAttr *CalledOnceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CalledOnceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CalledOnceAttr *CalledOnceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CalledOnceAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CalledOnceAttr *CalledOnceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CalledOnceAttr *CalledOnceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CalledOnceAttr::CalledOnceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::CalledOnce, false)
  {
}

CalledOnceAttr *CalledOnceAttr::clone(ASTContext &C) const {
  auto *A = new (C) CalledOnceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CalledOnceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((called_once";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::called_once";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::called_once";
    OS << "]]";
    break;
  }
}
}

const char *CalledOnceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "called_once";
  case 1:
    return "called_once";
  case 2:
    return "called_once";
  }
}


// CapabilityAttr implementation

CapabilityAttr *CapabilityAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CapabilityAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CapabilityAttr *CapabilityAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CapabilityAttr(Ctx, CommonInfo, Name);
  return A;
}

CapabilityAttr *CapabilityAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax, CapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Name, I);
}

CapabilityAttr *CapabilityAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax, CapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Name, I);
}

CapabilityAttr::CapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Capability, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}

CapabilityAttr::Spelling CapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_capability;
    case 1: return CXX11_clang_capability;
    case 2: return GNU_shared_capability;
    case 3: return CXX11_clang_shared_capability;
  }
}


CapabilityAttr *CapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) CapabilityAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((shared_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::shared_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *CapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "capability";
  case 1:
    return "capability";
  case 2:
    return "shared_capability";
  case 3:
    return "shared_capability";
  }
}


// CapturedRecordAttr implementation

CapturedRecordAttr *CapturedRecordAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CapturedRecordAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CapturedRecordAttr *CapturedRecordAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CapturedRecordAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CapturedRecordAttr *CapturedRecordAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CapturedRecordAttr *CapturedRecordAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CapturedRecordAttr::CapturedRecordAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CapturedRecord, false, false)
  {
}

CapturedRecordAttr *CapturedRecordAttr::clone(ASTContext &C) const {
  auto *A = new (C) CapturedRecordAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CapturedRecordAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *CapturedRecordAttr::getSpelling() const {
  return "(No spelling)";
}


// CarriesDependencyAttr implementation

CarriesDependencyAttr *CarriesDependencyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CarriesDependencyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CarriesDependencyAttr *CarriesDependencyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CarriesDependencyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CarriesDependencyAttr *CarriesDependencyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CarriesDependencyAttr *CarriesDependencyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CarriesDependencyAttr::CarriesDependencyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::CarriesDependency, false, false)
  {
}

CarriesDependencyAttr *CarriesDependencyAttr::clone(ASTContext &C) const {
  auto *A = new (C) CarriesDependencyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CarriesDependencyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((carries_dependency";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[carries_dependency";
    OS << "]]";
    break;
  }
}
}

const char *CarriesDependencyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "carries_dependency";
  case 1:
    return "carries_dependency";
  }
}


// CleanupAttr implementation

CleanupAttr *CleanupAttr::CreateImplicit(ASTContext &Ctx, FunctionDecl * FunctionDecl, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CleanupAttr(Ctx, CommonInfo, FunctionDecl);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CleanupAttr *CleanupAttr::Create(ASTContext &Ctx, FunctionDecl * FunctionDecl, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CleanupAttr(Ctx, CommonInfo, FunctionDecl);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CleanupAttr *CleanupAttr::CreateImplicit(ASTContext &Ctx, FunctionDecl * FunctionDecl, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, FunctionDecl, I);
}

CleanupAttr *CleanupAttr::Create(ASTContext &Ctx, FunctionDecl * FunctionDecl, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, FunctionDecl, I);
}

CleanupAttr::CleanupAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , FunctionDecl * FunctionDecl
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Cleanup, false, false)
              , functionDecl(FunctionDecl)
  {
}



CleanupAttr *CleanupAttr::clone(ASTContext &C) const {
  auto *A = new (C) CleanupAttr(C, *this, functionDecl);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CleanupAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cleanup";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFunctionDecl()->getNameInfo().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::cleanup";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFunctionDecl()->getNameInfo().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::cleanup";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFunctionDecl()->getNameInfo().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *CleanupAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cleanup";
  case 1:
    return "cleanup";
  case 2:
    return "cleanup";
  }
}


// CmseNSCallAttr implementation

CmseNSCallAttr *CmseNSCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CmseNSCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CmseNSCallAttr *CmseNSCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CmseNSCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CmseNSCallAttr *CmseNSCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CmseNSCallAttr *CmseNSCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CmseNSCallAttr::CmseNSCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::CmseNSCall, false)
  {
}

CmseNSCallAttr *CmseNSCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) CmseNSCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CmseNSCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cmse_nonsecure_call";
    OS << "))";
    break;
  }
}
}

const char *CmseNSCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cmse_nonsecure_call";
  }
}


// CmseNSEntryAttr implementation

CmseNSEntryAttr *CmseNSEntryAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CmseNSEntryAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CmseNSEntryAttr *CmseNSEntryAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CmseNSEntryAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CmseNSEntryAttr *CmseNSEntryAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CmseNSEntryAttr *CmseNSEntryAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CmseNSEntryAttr::CmseNSEntryAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CmseNSEntry, false, false)
  {
}

CmseNSEntryAttr *CmseNSEntryAttr::clone(ASTContext &C) const {
  auto *A = new (C) CmseNSEntryAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CmseNSEntryAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cmse_nonsecure_entry";
    OS << "))";
    break;
  }
}
}

const char *CmseNSEntryAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cmse_nonsecure_entry";
  }
}


// CodeSegAttr implementation

CodeSegAttr *CodeSegAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CodeSegAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CodeSegAttr *CodeSegAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CodeSegAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CodeSegAttr *CodeSegAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

CodeSegAttr *CodeSegAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

CodeSegAttr::CodeSegAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::CodeSeg, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



CodeSegAttr *CodeSegAttr::clone(ASTContext &C) const {
  auto *A = new (C) CodeSegAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CodeSegAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(code_seg";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
}
}

const char *CodeSegAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "code_seg";
  }
}


// ColdAttr implementation

ColdAttr *ColdAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ColdAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ColdAttr *ColdAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ColdAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ColdAttr *ColdAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ColdAttr *ColdAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ColdAttr::ColdAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Cold, false, false)
  {
}

ColdAttr *ColdAttr::clone(ASTContext &C) const {
  auto *A = new (C) ColdAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ColdAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((cold";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::cold";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::cold";
    OS << "]]";
    break;
  }
}
}

const char *ColdAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "cold";
  case 1:
    return "cold";
  case 2:
    return "cold";
  }
}


// CommonAttr implementation

CommonAttr *CommonAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CommonAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CommonAttr *CommonAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CommonAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

CommonAttr *CommonAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

CommonAttr *CommonAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

CommonAttr::CommonAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Common, false, false)
  {
}

CommonAttr *CommonAttr::clone(ASTContext &C) const {
  auto *A = new (C) CommonAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void CommonAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((common";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::common";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::common";
    OS << "]]";
    break;
  }
}
}

const char *CommonAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "common";
  case 1:
    return "common";
  case 2:
    return "common";
  }
}


// ConstAttr implementation

ConstAttr *ConstAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConstAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConstAttr *ConstAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConstAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConstAttr *ConstAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ConstAttr *ConstAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ConstAttr::ConstAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Const, false, false)
  {
}

ConstAttr *ConstAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConstAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConstAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((const";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::const";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::const";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((__const";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::__const";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::__const";
    OS << "]]";
    break;
  }
}
}

const char *ConstAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "const";
  case 1:
    return "const";
  case 2:
    return "const";
  case 3:
    return "__const";
  case 4:
    return "__const";
  case 5:
    return "__const";
  }
}


// ConstInitAttr implementation

ConstInitAttr *ConstInitAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConstInitAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConstInitAttr *ConstInitAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConstInitAttr(Ctx, CommonInfo);
  return A;
}

ConstInitAttr *ConstInitAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ConstInitAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

ConstInitAttr *ConstInitAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ConstInitAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

ConstInitAttr::ConstInitAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ConstInit, false, false)
  {
}

ConstInitAttr::Spelling ConstInitAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_constinit;
    case 1: return GNU_require_constant_initialization;
    case 2: return CXX11_clang_require_constant_initialization;
  }
}
ConstInitAttr *ConstInitAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConstInitAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConstInitAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " constinit";
    OS << "";
    break;
  }
  case 1 : {
    OS << " __attribute__((require_constant_initialization";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[clang::require_constant_initialization";
    OS << "]]";
    break;
  }
}
}

const char *ConstInitAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "constinit";
  case 1:
    return "require_constant_initialization";
  case 2:
    return "require_constant_initialization";
  }
}


// ConstructorAttr implementation

ConstructorAttr *ConstructorAttr::CreateImplicit(ASTContext &Ctx, int Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConstructorAttr(Ctx, CommonInfo, Priority);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConstructorAttr *ConstructorAttr::Create(ASTContext &Ctx, int Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConstructorAttr(Ctx, CommonInfo, Priority);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConstructorAttr *ConstructorAttr::CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Priority, I);
}

ConstructorAttr *ConstructorAttr::Create(ASTContext &Ctx, int Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Priority, I);
}

ConstructorAttr::ConstructorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int Priority
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Constructor, false, false)
              , priority(Priority)
  {
}

ConstructorAttr::ConstructorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Constructor, false, false)
              , priority()
  {
}



ConstructorAttr *ConstructorAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConstructorAttr(C, *this, priority);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConstructorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((constructor";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::constructor";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::constructor";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ConstructorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "constructor";
  case 1:
    return "constructor";
  case 2:
    return "constructor";
  }
}


// ConsumableAttr implementation

ConsumableAttr *ConsumableAttr::CreateImplicit(ASTContext &Ctx, ConsumedState DefaultState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConsumableAttr(Ctx, CommonInfo, DefaultState);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConsumableAttr *ConsumableAttr::Create(ASTContext &Ctx, ConsumedState DefaultState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConsumableAttr(Ctx, CommonInfo, DefaultState);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConsumableAttr *ConsumableAttr::CreateImplicit(ASTContext &Ctx, ConsumedState DefaultState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, DefaultState, I);
}

ConsumableAttr *ConsumableAttr::Create(ASTContext &Ctx, ConsumedState DefaultState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, DefaultState, I);
}

ConsumableAttr::ConsumableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState DefaultState
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Consumable, false, false)
              , defaultState(DefaultState)
  {
}



bool ConsumableAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("unknown", ConsumableAttr::Unknown)
    .Case("consumed", ConsumableAttr::Consumed)
    .Case("unconsumed", ConsumableAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ConsumableAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case ConsumableAttr::Unknown: return "unknown";
  case ConsumableAttr::Consumed: return "consumed";
  case ConsumableAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
ConsumableAttr *ConsumableAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConsumableAttr(C, *this, defaultState);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConsumableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((consumable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ConsumableAttr::ConvertConsumedStateToStr(getDefaultState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::consumable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ConsumableAttr::ConvertConsumedStateToStr(getDefaultState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ConsumableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "consumable";
  case 1:
    return "consumable";
  }
}


// ConsumableAutoCastAttr implementation

ConsumableAutoCastAttr *ConsumableAutoCastAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConsumableAutoCastAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConsumableAutoCastAttr *ConsumableAutoCastAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConsumableAutoCastAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConsumableAutoCastAttr *ConsumableAutoCastAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ConsumableAutoCastAttr *ConsumableAutoCastAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ConsumableAutoCastAttr::ConsumableAutoCastAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ConsumableAutoCast, false, false)
  {
}

ConsumableAutoCastAttr *ConsumableAutoCastAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConsumableAutoCastAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConsumableAutoCastAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((consumable_auto_cast_state";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::consumable_auto_cast_state";
    OS << "]]";
    break;
  }
}
}

const char *ConsumableAutoCastAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "consumable_auto_cast_state";
  case 1:
    return "consumable_auto_cast_state";
  }
}


// ConsumableSetOnReadAttr implementation

ConsumableSetOnReadAttr *ConsumableSetOnReadAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConsumableSetOnReadAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConsumableSetOnReadAttr *ConsumableSetOnReadAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConsumableSetOnReadAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConsumableSetOnReadAttr *ConsumableSetOnReadAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ConsumableSetOnReadAttr *ConsumableSetOnReadAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ConsumableSetOnReadAttr::ConsumableSetOnReadAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ConsumableSetOnRead, false, false)
  {
}

ConsumableSetOnReadAttr *ConsumableSetOnReadAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConsumableSetOnReadAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConsumableSetOnReadAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((consumable_set_state_on_read";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::consumable_set_state_on_read";
    OS << "]]";
    break;
  }
}
}

const char *ConsumableSetOnReadAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "consumable_set_state_on_read";
  case 1:
    return "consumable_set_state_on_read";
  }
}


// ConvergentAttr implementation

ConvergentAttr *ConvergentAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConvergentAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConvergentAttr *ConvergentAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ConvergentAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ConvergentAttr *ConvergentAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ConvergentAttr *ConvergentAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ConvergentAttr::ConvergentAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Convergent, false, false)
  {
}

ConvergentAttr *ConvergentAttr::clone(ASTContext &C) const {
  auto *A = new (C) ConvergentAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ConvergentAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((convergent";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::convergent";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::convergent";
    OS << "]]";
    break;
  }
}
}

const char *ConvergentAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "convergent";
  case 1:
    return "convergent";
  case 2:
    return "convergent";
  }
}


// DLLExportAttr implementation

DLLExportAttr *DLLExportAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLExportAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLExportAttr *DLLExportAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLExportAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLExportAttr *DLLExportAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

DLLExportAttr *DLLExportAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

DLLExportAttr::DLLExportAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DLLExport, false, false)
  {
}

DLLExportAttr *DLLExportAttr::clone(ASTContext &C) const {
  auto *A = new (C) DLLExportAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DLLExportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(dllexport";
    OS << ")";
    break;
  }
  case 1 : {
    OS << " __attribute__((dllexport";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::dllexport";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::dllexport";
    OS << "]]";
    break;
  }
}
}

const char *DLLExportAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "dllexport";
  case 1:
    return "dllexport";
  case 2:
    return "dllexport";
  case 3:
    return "dllexport";
  }
}


// DLLExportStaticLocalAttr implementation

DLLExportStaticLocalAttr *DLLExportStaticLocalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLExportStaticLocalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLExportStaticLocalAttr *DLLExportStaticLocalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLExportStaticLocalAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLExportStaticLocalAttr *DLLExportStaticLocalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

DLLExportStaticLocalAttr *DLLExportStaticLocalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

DLLExportStaticLocalAttr::DLLExportStaticLocalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DLLExportStaticLocal, false, false)
  {
}

DLLExportStaticLocalAttr *DLLExportStaticLocalAttr::clone(ASTContext &C) const {
  auto *A = new (C) DLLExportStaticLocalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DLLExportStaticLocalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *DLLExportStaticLocalAttr::getSpelling() const {
  return "(No spelling)";
}


// DLLImportAttr implementation

DLLImportAttr *DLLImportAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLImportAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLImportAttr *DLLImportAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLImportAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLImportAttr *DLLImportAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

DLLImportAttr *DLLImportAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

DLLImportAttr::DLLImportAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DLLImport, false, false)
  {
}

DLLImportAttr *DLLImportAttr::clone(ASTContext &C) const {
  auto *A = new (C) DLLImportAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DLLImportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(dllimport";
    OS << ")";
    break;
  }
  case 1 : {
    OS << " __attribute__((dllimport";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::dllimport";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::dllimport";
    OS << "]]";
    break;
  }
}
}

const char *DLLImportAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "dllimport";
  case 1:
    return "dllimport";
  case 2:
    return "dllimport";
  case 3:
    return "dllimport";
  }
}


// DLLImportStaticLocalAttr implementation

DLLImportStaticLocalAttr *DLLImportStaticLocalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLImportStaticLocalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLImportStaticLocalAttr *DLLImportStaticLocalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DLLImportStaticLocalAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DLLImportStaticLocalAttr *DLLImportStaticLocalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

DLLImportStaticLocalAttr *DLLImportStaticLocalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

DLLImportStaticLocalAttr::DLLImportStaticLocalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DLLImportStaticLocal, false, false)
  {
}

DLLImportStaticLocalAttr *DLLImportStaticLocalAttr::clone(ASTContext &C) const {
  auto *A = new (C) DLLImportStaticLocalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DLLImportStaticLocalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *DLLImportStaticLocalAttr::getSpelling() const {
  return "(No spelling)";
}


// DeprecatedAttr implementation

DeprecatedAttr *DeprecatedAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, llvm::StringRef Replacement, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DeprecatedAttr(Ctx, CommonInfo, Message, Replacement);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DeprecatedAttr *DeprecatedAttr::Create(ASTContext &Ctx, llvm::StringRef Message, llvm::StringRef Replacement, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DeprecatedAttr(Ctx, CommonInfo, Message, Replacement);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DeprecatedAttr *DeprecatedAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, llvm::StringRef Replacement, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Message, Replacement, I);
}

DeprecatedAttr *DeprecatedAttr::Create(ASTContext &Ctx, llvm::StringRef Message, llvm::StringRef Replacement, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Message, Replacement, I);
}

DeprecatedAttr::DeprecatedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
              , llvm::StringRef Replacement
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Deprecated, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , replacementLength(Replacement.size()),replacement(new (Ctx, 1) char[replacementLength])
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
    if (!Replacement.empty())
      std::memcpy(replacement, Replacement.data(), replacementLength);
}

DeprecatedAttr::DeprecatedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Deprecated, false, false)
              , messageLength(0),message(nullptr)
              , replacementLength(0),replacement(nullptr)
  {
}





DeprecatedAttr *DeprecatedAttr::clone(ASTContext &C) const {
  auto *A = new (C) DeprecatedAttr(C, *this, getMessage(), getReplacement());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DeprecatedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((deprecated";
    OS << "(\"" << getMessage() << "\"";
    if (!getReplacement().empty()) OS << ", \"" << getReplacement() << "\"";
    OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::deprecated";
    OS << "(\"" << getMessage() << "\"";
    OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::deprecated";
    OS << "(\"" << getMessage() << "\"";
    OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(deprecated";
    OS << "(\"" << getMessage() << "\"";
    OS << ")";
    OS << ")";
    break;
  }
  case 4 : {
    OS << " [[deprecated";
    OS << "(\"" << getMessage() << "\"";
    OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[deprecated";
    OS << "(\"" << getMessage() << "\"";
    OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *DeprecatedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "deprecated";
  case 1:
    return "deprecated";
  case 2:
    return "deprecated";
  case 3:
    return "deprecated";
  case 4:
    return "deprecated";
  case 5:
    return "deprecated";
  }
}


// DestructorAttr implementation

DestructorAttr *DestructorAttr::CreateImplicit(ASTContext &Ctx, int Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DestructorAttr(Ctx, CommonInfo, Priority);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DestructorAttr *DestructorAttr::Create(ASTContext &Ctx, int Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DestructorAttr(Ctx, CommonInfo, Priority);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DestructorAttr *DestructorAttr::CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Priority, I);
}

DestructorAttr *DestructorAttr::Create(ASTContext &Ctx, int Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Priority, I);
}

DestructorAttr::DestructorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int Priority
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Destructor, false, false)
              , priority(Priority)
  {
}

DestructorAttr::DestructorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Destructor, false, false)
              , priority()
  {
}



DestructorAttr *DestructorAttr::clone(ASTContext &C) const {
  auto *A = new (C) DestructorAttr(C, *this, priority);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DestructorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((destructor";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::destructor";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::destructor";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *DestructorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "destructor";
  case 1:
    return "destructor";
  case 2:
    return "destructor";
  }
}


// DiagnoseAsBuiltinAttr implementation

DiagnoseAsBuiltinAttr *DiagnoseAsBuiltinAttr::CreateImplicit(ASTContext &Ctx, FunctionDecl * Function, unsigned *ArgIndices, unsigned ArgIndicesSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DiagnoseAsBuiltinAttr(Ctx, CommonInfo, Function, ArgIndices, ArgIndicesSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DiagnoseAsBuiltinAttr *DiagnoseAsBuiltinAttr::Create(ASTContext &Ctx, FunctionDecl * Function, unsigned *ArgIndices, unsigned ArgIndicesSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DiagnoseAsBuiltinAttr(Ctx, CommonInfo, Function, ArgIndices, ArgIndicesSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DiagnoseAsBuiltinAttr *DiagnoseAsBuiltinAttr::CreateImplicit(ASTContext &Ctx, FunctionDecl * Function, unsigned *ArgIndices, unsigned ArgIndicesSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Function, ArgIndices, ArgIndicesSize, I);
}

DiagnoseAsBuiltinAttr *DiagnoseAsBuiltinAttr::Create(ASTContext &Ctx, FunctionDecl * Function, unsigned *ArgIndices, unsigned ArgIndicesSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Function, ArgIndices, ArgIndicesSize, I);
}

DiagnoseAsBuiltinAttr::DiagnoseAsBuiltinAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , FunctionDecl * Function
              , unsigned *ArgIndices, unsigned ArgIndicesSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DiagnoseAsBuiltin, false, false)
              , function(Function)
              , argIndices_Size(ArgIndicesSize), argIndices_(new (Ctx, 16) unsigned[argIndices_Size])
  {
  std::copy(ArgIndices, ArgIndices + argIndices_Size, argIndices_);
}

DiagnoseAsBuiltinAttr::DiagnoseAsBuiltinAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , FunctionDecl * Function
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DiagnoseAsBuiltin, false, false)
              , function(Function)
              , argIndices_Size(0), argIndices_(nullptr)
  {
}





DiagnoseAsBuiltinAttr *DiagnoseAsBuiltinAttr::clone(ASTContext &C) const {
  auto *A = new (C) DiagnoseAsBuiltinAttr(C, *this, function, argIndices_, argIndices_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DiagnoseAsBuiltinAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((diagnose_as_builtin";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFunction()->getNameInfo().getAsString() << "";
    OS << "";
  for (const auto &Val : argIndices()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::diagnose_as_builtin";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFunction()->getNameInfo().getAsString() << "";
    OS << "";
  for (const auto &Val : argIndices()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::diagnose_as_builtin";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFunction()->getNameInfo().getAsString() << "";
    OS << "";
  for (const auto &Val : argIndices()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *DiagnoseAsBuiltinAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "diagnose_as_builtin";
  case 1:
    return "diagnose_as_builtin";
  case 2:
    return "diagnose_as_builtin";
  }
}


// DiagnoseIfAttr implementation

DiagnoseIfAttr *DiagnoseIfAttr::CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, bool ArgDependent, NamedDecl * Parent, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DiagnoseIfAttr(Ctx, CommonInfo, Cond, Message, DiagnosticType, ArgDependent, Parent);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DiagnoseIfAttr *DiagnoseIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, bool ArgDependent, NamedDecl * Parent, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DiagnoseIfAttr(Ctx, CommonInfo, Cond, Message, DiagnosticType, ArgDependent, Parent);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DiagnoseIfAttr *DiagnoseIfAttr::CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, bool ArgDependent, NamedDecl * Parent, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Cond, Message, DiagnosticType, ArgDependent, Parent, I);
}

DiagnoseIfAttr *DiagnoseIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, bool ArgDependent, NamedDecl * Parent, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Cond, Message, DiagnosticType, ArgDependent, Parent, I);
}

DiagnoseIfAttr *DiagnoseIfAttr::CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DiagnoseIfAttr(Ctx, CommonInfo, Cond, Message, DiagnosticType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DiagnoseIfAttr *DiagnoseIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DiagnoseIfAttr(Ctx, CommonInfo, Cond, Message, DiagnosticType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DiagnoseIfAttr *DiagnoseIfAttr::CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Cond, Message, DiagnosticType, I);
}

DiagnoseIfAttr *DiagnoseIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Cond, Message, DiagnosticType, I);
}

DiagnoseIfAttr::DiagnoseIfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Cond
              , llvm::StringRef Message
              , DiagnosticType DiagnosticType
              , bool ArgDependent
              , NamedDecl * Parent
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DiagnoseIf, true, true)
              , cond(Cond)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , diagnosticType(DiagnosticType)
              , argDependent(ArgDependent)
              , parent(Parent)
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

DiagnoseIfAttr::DiagnoseIfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Cond
              , llvm::StringRef Message
              , DiagnosticType DiagnosticType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DiagnoseIf, true, true)
              , cond(Cond)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , diagnosticType(DiagnosticType)
              , argDependent()
              , parent()
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}







bool DiagnoseIfAttr::ConvertStrToDiagnosticType(StringRef Val, DiagnosticType &Out) {
  Optional<DiagnosticType> R = llvm::StringSwitch<Optional<DiagnosticType>>(Val)
    .Case("error", DiagnoseIfAttr::DT_Error)
    .Case("warning", DiagnoseIfAttr::DT_Warning)
    .Default(Optional<DiagnosticType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *DiagnoseIfAttr::ConvertDiagnosticTypeToStr(DiagnosticType Val) {
  switch(Val) {
  case DiagnoseIfAttr::DT_Error: return "error";
  case DiagnoseIfAttr::DT_Warning: return "warning";
  }
  llvm_unreachable("No enumerator with that value");
}




DiagnoseIfAttr *DiagnoseIfAttr::clone(ASTContext &C) const {
  auto *A = new (C) DiagnoseIfAttr(C, *this, cond, getMessage(), diagnosticType, argDependent, parent);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DiagnoseIfAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((diagnose_if";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCond() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << DiagnoseIfAttr::ConvertDiagnosticTypeToStr(getDiagnosticType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *DiagnoseIfAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "diagnose_if";
  }
}


// DisableSanitizerInstrumentationAttr implementation

DisableSanitizerInstrumentationAttr *DisableSanitizerInstrumentationAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DisableSanitizerInstrumentationAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DisableSanitizerInstrumentationAttr *DisableSanitizerInstrumentationAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DisableSanitizerInstrumentationAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DisableSanitizerInstrumentationAttr *DisableSanitizerInstrumentationAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

DisableSanitizerInstrumentationAttr *DisableSanitizerInstrumentationAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

DisableSanitizerInstrumentationAttr::DisableSanitizerInstrumentationAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DisableSanitizerInstrumentation, false, false)
  {
}

DisableSanitizerInstrumentationAttr *DisableSanitizerInstrumentationAttr::clone(ASTContext &C) const {
  auto *A = new (C) DisableSanitizerInstrumentationAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DisableSanitizerInstrumentationAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((disable_sanitizer_instrumentation";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::disable_sanitizer_instrumentation";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::disable_sanitizer_instrumentation";
    OS << "]]";
    break;
  }
}
}

const char *DisableSanitizerInstrumentationAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "disable_sanitizer_instrumentation";
  case 1:
    return "disable_sanitizer_instrumentation";
  case 2:
    return "disable_sanitizer_instrumentation";
  }
}


// DisableTailCallsAttr implementation

DisableTailCallsAttr *DisableTailCallsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DisableTailCallsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DisableTailCallsAttr *DisableTailCallsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) DisableTailCallsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

DisableTailCallsAttr *DisableTailCallsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

DisableTailCallsAttr *DisableTailCallsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

DisableTailCallsAttr::DisableTailCallsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DisableTailCalls, false, false)
  {
}

DisableTailCallsAttr *DisableTailCallsAttr::clone(ASTContext &C) const {
  auto *A = new (C) DisableTailCallsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void DisableTailCallsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((disable_tail_calls";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::disable_tail_calls";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::disable_tail_calls";
    OS << "]]";
    break;
  }
}
}

const char *DisableTailCallsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "disable_tail_calls";
  case 1:
    return "disable_tail_calls";
  case 2:
    return "disable_tail_calls";
  }
}


// EmptyBasesAttr implementation

EmptyBasesAttr *EmptyBasesAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EmptyBasesAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EmptyBasesAttr *EmptyBasesAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EmptyBasesAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EmptyBasesAttr *EmptyBasesAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

EmptyBasesAttr *EmptyBasesAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

EmptyBasesAttr::EmptyBasesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EmptyBases, false, false)
  {
}

EmptyBasesAttr *EmptyBasesAttr::clone(ASTContext &C) const {
  auto *A = new (C) EmptyBasesAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void EmptyBasesAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(empty_bases";
    OS << ")";
    break;
  }
}
}

const char *EmptyBasesAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "empty_bases";
  }
}


// EnableIfAttr implementation

EnableIfAttr *EnableIfAttr::CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnableIfAttr(Ctx, CommonInfo, Cond, Message);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnableIfAttr *EnableIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnableIfAttr(Ctx, CommonInfo, Cond, Message);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnableIfAttr *EnableIfAttr::CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Cond, Message, I);
}

EnableIfAttr *EnableIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Cond, Message, I);
}

EnableIfAttr::EnableIfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Cond
              , llvm::StringRef Message
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnableIf, false, false)
              , cond(Cond)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}





EnableIfAttr *EnableIfAttr::clone(ASTContext &C) const {
  auto *A = new (C) EnableIfAttr(C, *this, cond, getMessage());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void EnableIfAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((enable_if";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCond() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *EnableIfAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "enable_if";
  }
}


// EnforceTCBAttr implementation

EnforceTCBAttr *EnforceTCBAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef TCBName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnforceTCBAttr(Ctx, CommonInfo, TCBName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnforceTCBAttr *EnforceTCBAttr::Create(ASTContext &Ctx, llvm::StringRef TCBName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnforceTCBAttr(Ctx, CommonInfo, TCBName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnforceTCBAttr *EnforceTCBAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef TCBName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TCBName, I);
}

EnforceTCBAttr *EnforceTCBAttr::Create(ASTContext &Ctx, llvm::StringRef TCBName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TCBName, I);
}

EnforceTCBAttr::EnforceTCBAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef TCBName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnforceTCB, false, true)
              , tCBNameLength(TCBName.size()),tCBName(new (Ctx, 1) char[tCBNameLength])
  {
    if (!TCBName.empty())
      std::memcpy(tCBName, TCBName.data(), tCBNameLength);
}



EnforceTCBAttr *EnforceTCBAttr::clone(ASTContext &C) const {
  auto *A = new (C) EnforceTCBAttr(C, *this, getTCBName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void EnforceTCBAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((enforce_tcb";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getTCBName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::enforce_tcb";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getTCBName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::enforce_tcb";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getTCBName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *EnforceTCBAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "enforce_tcb";
  case 1:
    return "enforce_tcb";
  case 2:
    return "enforce_tcb";
  }
}


// EnforceTCBLeafAttr implementation

EnforceTCBLeafAttr *EnforceTCBLeafAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef TCBName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnforceTCBLeafAttr(Ctx, CommonInfo, TCBName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnforceTCBLeafAttr *EnforceTCBLeafAttr::Create(ASTContext &Ctx, llvm::StringRef TCBName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnforceTCBLeafAttr(Ctx, CommonInfo, TCBName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnforceTCBLeafAttr *EnforceTCBLeafAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef TCBName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TCBName, I);
}

EnforceTCBLeafAttr *EnforceTCBLeafAttr::Create(ASTContext &Ctx, llvm::StringRef TCBName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TCBName, I);
}

EnforceTCBLeafAttr::EnforceTCBLeafAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef TCBName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnforceTCBLeaf, false, true)
              , tCBNameLength(TCBName.size()),tCBName(new (Ctx, 1) char[tCBNameLength])
  {
    if (!TCBName.empty())
      std::memcpy(tCBName, TCBName.data(), tCBNameLength);
}



EnforceTCBLeafAttr *EnforceTCBLeafAttr::clone(ASTContext &C) const {
  auto *A = new (C) EnforceTCBLeafAttr(C, *this, getTCBName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void EnforceTCBLeafAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((enforce_tcb_leaf";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getTCBName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::enforce_tcb_leaf";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getTCBName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::enforce_tcb_leaf";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getTCBName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *EnforceTCBLeafAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "enforce_tcb_leaf";
  case 1:
    return "enforce_tcb_leaf";
  case 2:
    return "enforce_tcb_leaf";
  }
}


// EnumExtensibilityAttr implementation

EnumExtensibilityAttr *EnumExtensibilityAttr::CreateImplicit(ASTContext &Ctx, Kind Extensibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnumExtensibilityAttr(Ctx, CommonInfo, Extensibility);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnumExtensibilityAttr *EnumExtensibilityAttr::Create(ASTContext &Ctx, Kind Extensibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) EnumExtensibilityAttr(Ctx, CommonInfo, Extensibility);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

EnumExtensibilityAttr *EnumExtensibilityAttr::CreateImplicit(ASTContext &Ctx, Kind Extensibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Extensibility, I);
}

EnumExtensibilityAttr *EnumExtensibilityAttr::Create(ASTContext &Ctx, Kind Extensibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Extensibility, I);
}

EnumExtensibilityAttr::EnumExtensibilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Kind Extensibility
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnumExtensibility, false, false)
              , extensibility(Extensibility)
  {
}



bool EnumExtensibilityAttr::ConvertStrToKind(StringRef Val, Kind &Out) {
  Optional<Kind> R = llvm::StringSwitch<Optional<Kind>>(Val)
    .Case("closed", EnumExtensibilityAttr::Closed)
    .Case("open", EnumExtensibilityAttr::Open)
    .Default(Optional<Kind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *EnumExtensibilityAttr::ConvertKindToStr(Kind Val) {
  switch(Val) {
  case EnumExtensibilityAttr::Closed: return "closed";
  case EnumExtensibilityAttr::Open: return "open";
  }
  llvm_unreachable("No enumerator with that value");
}
EnumExtensibilityAttr *EnumExtensibilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) EnumExtensibilityAttr(C, *this, extensibility);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void EnumExtensibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((enum_extensibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << EnumExtensibilityAttr::ConvertKindToStr(getExtensibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::enum_extensibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << EnumExtensibilityAttr::ConvertKindToStr(getExtensibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::enum_extensibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << EnumExtensibilityAttr::ConvertKindToStr(getExtensibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *EnumExtensibilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "enum_extensibility";
  case 1:
    return "enum_extensibility";
  case 2:
    return "enum_extensibility";
  }
}


// ErrorAttr implementation

ErrorAttr *ErrorAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef UserDiagnostic, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ErrorAttr(Ctx, CommonInfo, UserDiagnostic);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ErrorAttr *ErrorAttr::Create(ASTContext &Ctx, llvm::StringRef UserDiagnostic, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ErrorAttr(Ctx, CommonInfo, UserDiagnostic);
  return A;
}

ErrorAttr *ErrorAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef UserDiagnostic, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ErrorAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, UserDiagnostic, I);
}

ErrorAttr *ErrorAttr::Create(ASTContext &Ctx, llvm::StringRef UserDiagnostic, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ErrorAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, UserDiagnostic, I);
}

ErrorAttr::ErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef UserDiagnostic
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Error, false, false)
              , userDiagnosticLength(UserDiagnostic.size()),userDiagnostic(new (Ctx, 1) char[userDiagnosticLength])
  {
    if (!UserDiagnostic.empty())
      std::memcpy(userDiagnostic, UserDiagnostic.data(), userDiagnosticLength);
}

ErrorAttr::Spelling ErrorAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_error;
    case 1: return CXX11_gnu_error;
    case 2: return C2x_gnu_error;
    case 3: return GNU_warning;
    case 4: return CXX11_gnu_warning;
    case 5: return C2x_gnu_warning;
  }
}


ErrorAttr *ErrorAttr::clone(ASTContext &C) const {
  auto *A = new (C) ErrorAttr(C, *this, getUserDiagnostic());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ErrorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getUserDiagnostic() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getUserDiagnostic() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getUserDiagnostic() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((warning";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getUserDiagnostic() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::warning";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getUserDiagnostic() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::warning";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getUserDiagnostic() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ErrorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "error";
  case 1:
    return "error";
  case 2:
    return "error";
  case 3:
    return "warning";
  case 4:
    return "warning";
  case 5:
    return "warning";
  }
}


// ExcludeFromExplicitInstantiationAttr implementation

ExcludeFromExplicitInstantiationAttr *ExcludeFromExplicitInstantiationAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ExcludeFromExplicitInstantiationAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ExcludeFromExplicitInstantiationAttr *ExcludeFromExplicitInstantiationAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ExcludeFromExplicitInstantiationAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ExcludeFromExplicitInstantiationAttr *ExcludeFromExplicitInstantiationAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ExcludeFromExplicitInstantiationAttr *ExcludeFromExplicitInstantiationAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ExcludeFromExplicitInstantiationAttr::ExcludeFromExplicitInstantiationAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExcludeFromExplicitInstantiation, false, false)
  {
}

ExcludeFromExplicitInstantiationAttr *ExcludeFromExplicitInstantiationAttr::clone(ASTContext &C) const {
  auto *A = new (C) ExcludeFromExplicitInstantiationAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ExcludeFromExplicitInstantiationAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((exclude_from_explicit_instantiation";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::exclude_from_explicit_instantiation";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::exclude_from_explicit_instantiation";
    OS << "]]";
    break;
  }
}
}

const char *ExcludeFromExplicitInstantiationAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "exclude_from_explicit_instantiation";
  case 1:
    return "exclude_from_explicit_instantiation";
  case 2:
    return "exclude_from_explicit_instantiation";
  }
}


// ExclusiveTrylockFunctionAttr implementation

ExclusiveTrylockFunctionAttr *ExclusiveTrylockFunctionAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ExclusiveTrylockFunctionAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ExclusiveTrylockFunctionAttr *ExclusiveTrylockFunctionAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ExclusiveTrylockFunctionAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ExclusiveTrylockFunctionAttr *ExclusiveTrylockFunctionAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, SuccessValue, Args, ArgsSize, I);
}

ExclusiveTrylockFunctionAttr *ExclusiveTrylockFunctionAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, SuccessValue, Args, ArgsSize, I);
}

ExclusiveTrylockFunctionAttr::ExclusiveTrylockFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExclusiveTrylockFunction, true, true)
              , successValue(SuccessValue)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

ExclusiveTrylockFunctionAttr::ExclusiveTrylockFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExclusiveTrylockFunction, true, true)
              , successValue(SuccessValue)
              , args_Size(0), args_(nullptr)
  {
}





ExclusiveTrylockFunctionAttr *ExclusiveTrylockFunctionAttr::clone(ASTContext &C) const {
  auto *A = new (C) ExclusiveTrylockFunctionAttr(C, *this, successValue, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ExclusiveTrylockFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((exclusive_trylock_function";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *ExclusiveTrylockFunctionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "exclusive_trylock_function";
  }
}


// ExternalSourceSymbolAttr implementation

ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ExternalSourceSymbolAttr(Ctx, CommonInfo, Language, DefinedIn, GeneratedDeclaration);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::Create(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ExternalSourceSymbolAttr(Ctx, CommonInfo, Language, DefinedIn, GeneratedDeclaration);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Language, DefinedIn, GeneratedDeclaration, I);
}

ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::Create(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Language, DefinedIn, GeneratedDeclaration, I);
}

ExternalSourceSymbolAttr::ExternalSourceSymbolAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Language
              , llvm::StringRef DefinedIn
              , bool GeneratedDeclaration
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExternalSourceSymbol, false, false)
              , languageLength(Language.size()),language(new (Ctx, 1) char[languageLength])
              , definedInLength(DefinedIn.size()),definedIn(new (Ctx, 1) char[definedInLength])
              , generatedDeclaration(GeneratedDeclaration)
  {
    if (!Language.empty())
      std::memcpy(language, Language.data(), languageLength);
    if (!DefinedIn.empty())
      std::memcpy(definedIn, DefinedIn.data(), definedInLength);
}

ExternalSourceSymbolAttr::ExternalSourceSymbolAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExternalSourceSymbol, false, false)
              , languageLength(0),language(nullptr)
              , definedInLength(0),definedIn(nullptr)
              , generatedDeclaration()
  {
}







ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::clone(ASTContext &C) const {
  auto *A = new (C) ExternalSourceSymbolAttr(C, *this, getLanguage(), getDefinedIn(), generatedDeclaration);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ExternalSourceSymbolAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((external_source_symbol";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getLanguage() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getDefinedIn() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getGeneratedDeclaration() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::external_source_symbol";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getLanguage() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getDefinedIn() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getGeneratedDeclaration() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::external_source_symbol";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getLanguage() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getDefinedIn() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getGeneratedDeclaration() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ExternalSourceSymbolAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "external_source_symbol";
  case 1:
    return "external_source_symbol";
  case 2:
    return "external_source_symbol";
  }
}


// FallThroughAttr implementation

FallThroughAttr *FallThroughAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FallThroughAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FallThroughAttr *FallThroughAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FallThroughAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FallThroughAttr *FallThroughAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

FallThroughAttr *FallThroughAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

FallThroughAttr::FallThroughAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::FallThrough, false)
  {
}

FallThroughAttr *FallThroughAttr::clone(ASTContext &C) const {
  auto *A = new (C) FallThroughAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FallThroughAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[fallthrough";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[fallthrough";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::fallthrough";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((fallthrough";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::fallthrough";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::fallthrough";
    OS << "]]";
    break;
  }
}
}

const char *FallThroughAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "fallthrough";
  case 1:
    return "fallthrough";
  case 2:
    return "fallthrough";
  case 3:
    return "fallthrough";
  case 4:
    return "fallthrough";
  case 5:
    return "fallthrough";
  }
}


// FastCallAttr implementation

FastCallAttr *FastCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FastCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FastCallAttr *FastCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FastCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FastCallAttr *FastCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

FastCallAttr *FastCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

FastCallAttr::FastCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FastCall, false, false)
  {
}

FastCallAttr *FastCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) FastCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FastCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((fastcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::fastcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::fastcall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __fastcall";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _fastcall";
    OS << "";
    break;
  }
}
}

const char *FastCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "fastcall";
  case 1:
    return "fastcall";
  case 2:
    return "fastcall";
  case 3:
    return "__fastcall";
  case 4:
    return "_fastcall";
  }
}


// FinalAttr implementation

FinalAttr *FinalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FinalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FinalAttr *FinalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FinalAttr(Ctx, CommonInfo);
  return A;
}

FinalAttr *FinalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, FinalAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

FinalAttr *FinalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, FinalAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

FinalAttr::FinalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Final, false, false)
  {
}

FinalAttr::Spelling FinalAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_final;
    case 1: return Keyword_sealed;
  }
}
FinalAttr *FinalAttr::clone(ASTContext &C) const {
  auto *A = new (C) FinalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FinalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " final";
    OS << "";
    break;
  }
  case 1 : {
    OS << " sealed";
    OS << "";
    break;
  }
}
}

const char *FinalAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "final";
  case 1:
    return "sealed";
  }
}


// FlagEnumAttr implementation

FlagEnumAttr *FlagEnumAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FlagEnumAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FlagEnumAttr *FlagEnumAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FlagEnumAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FlagEnumAttr *FlagEnumAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

FlagEnumAttr *FlagEnumAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

FlagEnumAttr::FlagEnumAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FlagEnum, false, false)
  {
}

FlagEnumAttr *FlagEnumAttr::clone(ASTContext &C) const {
  auto *A = new (C) FlagEnumAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FlagEnumAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((flag_enum";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::flag_enum";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::flag_enum";
    OS << "]]";
    break;
  }
}
}

const char *FlagEnumAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "flag_enum";
  case 1:
    return "flag_enum";
  case 2:
    return "flag_enum";
  }
}


// FlattenAttr implementation

FlattenAttr *FlattenAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FlattenAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FlattenAttr *FlattenAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FlattenAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FlattenAttr *FlattenAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

FlattenAttr *FlattenAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

FlattenAttr::FlattenAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Flatten, false, false)
  {
}

FlattenAttr *FlattenAttr::clone(ASTContext &C) const {
  auto *A = new (C) FlattenAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FlattenAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((flatten";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::flatten";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::flatten";
    OS << "]]";
    break;
  }
}
}

const char *FlattenAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "flatten";
  case 1:
    return "flatten";
  case 2:
    return "flatten";
  }
}


// FormatAttr implementation

FormatAttr *FormatAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FormatAttr(Ctx, CommonInfo, Type, FormatIdx, FirstArg);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FormatAttr *FormatAttr::Create(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FormatAttr(Ctx, CommonInfo, Type, FormatIdx, FirstArg);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FormatAttr *FormatAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Type, FormatIdx, FirstArg, I);
}

FormatAttr *FormatAttr::Create(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Type, FormatIdx, FirstArg, I);
}

FormatAttr::FormatAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Type
              , int FormatIdx
              , int FirstArg
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Format, false, false)
              , type(Type)
              , formatIdx(FormatIdx)
              , firstArg(FirstArg)
  {
}







FormatAttr *FormatAttr::clone(ASTContext &C) const {
  auto *A = new (C) FormatAttr(C, *this, type, formatIdx, firstArg);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FormatAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((format";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getType() ? getType()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFormatIdx() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFirstArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::format";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getType() ? getType()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFormatIdx() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFirstArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::format";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getType() ? getType()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFormatIdx() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFirstArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *FormatAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "format";
  case 1:
    return "format";
  case 2:
    return "format";
  }
}


// FormatArgAttr implementation

FormatArgAttr *FormatArgAttr::CreateImplicit(ASTContext &Ctx, ParamIdx FormatIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FormatArgAttr(Ctx, CommonInfo, FormatIdx);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FormatArgAttr *FormatArgAttr::Create(ASTContext &Ctx, ParamIdx FormatIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FormatArgAttr(Ctx, CommonInfo, FormatIdx);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FormatArgAttr *FormatArgAttr::CreateImplicit(ASTContext &Ctx, ParamIdx FormatIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, FormatIdx, I);
}

FormatArgAttr *FormatArgAttr::Create(ASTContext &Ctx, ParamIdx FormatIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, FormatIdx, I);
}

FormatArgAttr::FormatArgAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx FormatIdx
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FormatArg, false, false)
              , formatIdx(FormatIdx)
  {
}



FormatArgAttr *FormatArgAttr::clone(ASTContext &C) const {
  auto *A = new (C) FormatArgAttr(C, *this, formatIdx);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FormatArgAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((format_arg";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFormatIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::format_arg";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFormatIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::format_arg";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getFormatIdx().getSourceIndex() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *FormatArgAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "format_arg";
  case 1:
    return "format_arg";
  case 2:
    return "format_arg";
  }
}


// FunctionReturnThunksAttr implementation

FunctionReturnThunksAttr *FunctionReturnThunksAttr::CreateImplicit(ASTContext &Ctx, Kind ThunkType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FunctionReturnThunksAttr(Ctx, CommonInfo, ThunkType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FunctionReturnThunksAttr *FunctionReturnThunksAttr::Create(ASTContext &Ctx, Kind ThunkType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) FunctionReturnThunksAttr(Ctx, CommonInfo, ThunkType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

FunctionReturnThunksAttr *FunctionReturnThunksAttr::CreateImplicit(ASTContext &Ctx, Kind ThunkType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ThunkType, I);
}

FunctionReturnThunksAttr *FunctionReturnThunksAttr::Create(ASTContext &Ctx, Kind ThunkType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ThunkType, I);
}

FunctionReturnThunksAttr::FunctionReturnThunksAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Kind ThunkType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FunctionReturnThunks, false, false)
              , thunkType(ThunkType)
  {
}



bool FunctionReturnThunksAttr::ConvertStrToKind(StringRef Val, Kind &Out) {
  Optional<Kind> R = llvm::StringSwitch<Optional<Kind>>(Val)
    .Case("keep", FunctionReturnThunksAttr::Keep)
    .Case("thunk-extern", FunctionReturnThunksAttr::Extern)
    .Default(Optional<Kind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *FunctionReturnThunksAttr::ConvertKindToStr(Kind Val) {
  switch(Val) {
  case FunctionReturnThunksAttr::Keep: return "keep";
  case FunctionReturnThunksAttr::Extern: return "thunk-extern";
  }
  llvm_unreachable("No enumerator with that value");
}
FunctionReturnThunksAttr *FunctionReturnThunksAttr::clone(ASTContext &C) const {
  auto *A = new (C) FunctionReturnThunksAttr(C, *this, thunkType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void FunctionReturnThunksAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((function_return";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << FunctionReturnThunksAttr::ConvertKindToStr(getThunkType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::function_return";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << FunctionReturnThunksAttr::ConvertKindToStr(getThunkType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::function_return";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << FunctionReturnThunksAttr::ConvertKindToStr(getThunkType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *FunctionReturnThunksAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "function_return";
  case 1:
    return "function_return";
  case 2:
    return "function_return";
  }
}


// GNUInlineAttr implementation

GNUInlineAttr *GNUInlineAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) GNUInlineAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

GNUInlineAttr *GNUInlineAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) GNUInlineAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

GNUInlineAttr *GNUInlineAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

GNUInlineAttr *GNUInlineAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

GNUInlineAttr::GNUInlineAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::GNUInline, false, false)
  {
}

GNUInlineAttr *GNUInlineAttr::clone(ASTContext &C) const {
  auto *A = new (C) GNUInlineAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void GNUInlineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((gnu_inline";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::gnu_inline";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::gnu_inline";
    OS << "]]";
    break;
  }
}
}

const char *GNUInlineAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "gnu_inline";
  case 1:
    return "gnu_inline";
  case 2:
    return "gnu_inline";
  }
}


// GuardedByAttr implementation

GuardedByAttr *GuardedByAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) GuardedByAttr(Ctx, CommonInfo, Arg);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

GuardedByAttr *GuardedByAttr::Create(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) GuardedByAttr(Ctx, CommonInfo, Arg);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

GuardedByAttr *GuardedByAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Arg, I);
}

GuardedByAttr *GuardedByAttr::Create(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Arg, I);
}

GuardedByAttr::GuardedByAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Arg
             )
  : InheritableAttr(Ctx, CommonInfo, attr::GuardedBy, true, true)
              , arg(Arg)
  {
}



GuardedByAttr *GuardedByAttr::clone(ASTContext &C) const {
  auto *A = new (C) GuardedByAttr(C, *this, arg);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void GuardedByAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((guarded_by";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *GuardedByAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "guarded_by";
  }
}


// GuardedVarAttr implementation

GuardedVarAttr *GuardedVarAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) GuardedVarAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

GuardedVarAttr *GuardedVarAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) GuardedVarAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

GuardedVarAttr *GuardedVarAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

GuardedVarAttr *GuardedVarAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

GuardedVarAttr::GuardedVarAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::GuardedVar, false, false)
  {
}

GuardedVarAttr *GuardedVarAttr::clone(ASTContext &C) const {
  auto *A = new (C) GuardedVarAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void GuardedVarAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((guarded_var";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::guarded_var";
    OS << "]]";
    break;
  }
}
}

const char *GuardedVarAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "guarded_var";
  case 1:
    return "guarded_var";
  }
}


// HIPManagedAttr implementation

HIPManagedAttr *HIPManagedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HIPManagedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HIPManagedAttr *HIPManagedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HIPManagedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HIPManagedAttr *HIPManagedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

HIPManagedAttr *HIPManagedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

HIPManagedAttr::HIPManagedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::HIPManaged, false, false)
  {
}

HIPManagedAttr *HIPManagedAttr::clone(ASTContext &C) const {
  auto *A = new (C) HIPManagedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HIPManagedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((managed";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __declspec(__managed__";
    OS << ")";
    break;
  }
}
}

const char *HIPManagedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "managed";
  case 1:
    return "__managed__";
  }
}


// HLSLNumThreadsAttr implementation

HLSLNumThreadsAttr *HLSLNumThreadsAttr::CreateImplicit(ASTContext &Ctx, int X, int Y, int Z, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLNumThreadsAttr(Ctx, CommonInfo, X, Y, Z);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLNumThreadsAttr *HLSLNumThreadsAttr::Create(ASTContext &Ctx, int X, int Y, int Z, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLNumThreadsAttr(Ctx, CommonInfo, X, Y, Z);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLNumThreadsAttr *HLSLNumThreadsAttr::CreateImplicit(ASTContext &Ctx, int X, int Y, int Z, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, X, Y, Z, I);
}

HLSLNumThreadsAttr *HLSLNumThreadsAttr::Create(ASTContext &Ctx, int X, int Y, int Z, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, X, Y, Z, I);
}

HLSLNumThreadsAttr::HLSLNumThreadsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int X
              , int Y
              , int Z
             )
  : InheritableAttr(Ctx, CommonInfo, attr::HLSLNumThreads, false, false)
              , x(X)
              , y(Y)
              , z(Z)
  {
}







HLSLNumThreadsAttr *HLSLNumThreadsAttr::clone(ASTContext &C) const {
  auto *A = new (C) HLSLNumThreadsAttr(C, *this, x, y, z);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HLSLNumThreadsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "[numthreads";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getX() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getY() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getZ() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]";
    break;
  }
}
}

const char *HLSLNumThreadsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "numthreads";
  }
}


// HLSLResourceAttr implementation

HLSLResourceAttr *HLSLResourceAttr::CreateImplicit(ASTContext &Ctx, ResourceClass ResourceType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLResourceAttr(Ctx, CommonInfo, ResourceType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLResourceAttr *HLSLResourceAttr::Create(ASTContext &Ctx, ResourceClass ResourceType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLResourceAttr(Ctx, CommonInfo, ResourceType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLResourceAttr *HLSLResourceAttr::CreateImplicit(ASTContext &Ctx, ResourceClass ResourceType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ResourceType, I);
}

HLSLResourceAttr *HLSLResourceAttr::Create(ASTContext &Ctx, ResourceClass ResourceType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ResourceType, I);
}

HLSLResourceAttr::HLSLResourceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ResourceClass ResourceType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::HLSLResource, false, false)
              , resourceType(ResourceType)
  {
}



bool HLSLResourceAttr::ConvertStrToResourceClass(StringRef Val, ResourceClass &Out) {
  Optional<ResourceClass> R = llvm::StringSwitch<Optional<ResourceClass>>(Val)
    .Case("SRV", HLSLResourceAttr::SRV)
    .Case("UAV", HLSLResourceAttr::UAV)
    .Case("CBuffer", HLSLResourceAttr::CBuffer)
    .Case("Sampler", HLSLResourceAttr::Sampler)
    .Default(Optional<ResourceClass>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *HLSLResourceAttr::ConvertResourceClassToStr(ResourceClass Val) {
  switch(Val) {
  case HLSLResourceAttr::SRV: return "SRV";
  case HLSLResourceAttr::UAV: return "UAV";
  case HLSLResourceAttr::CBuffer: return "CBuffer";
  case HLSLResourceAttr::Sampler: return "Sampler";
  }
  llvm_unreachable("No enumerator with that value");
}
HLSLResourceAttr *HLSLResourceAttr::clone(ASTContext &C) const {
  auto *A = new (C) HLSLResourceAttr(C, *this, resourceType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HLSLResourceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *HLSLResourceAttr::getSpelling() const {
  return "(No spelling)";
}


// HLSLResourceBindingAttr implementation

HLSLResourceBindingAttr *HLSLResourceBindingAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Slot, llvm::StringRef Space, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLResourceBindingAttr(Ctx, CommonInfo, Slot, Space);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLResourceBindingAttr *HLSLResourceBindingAttr::Create(ASTContext &Ctx, llvm::StringRef Slot, llvm::StringRef Space, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLResourceBindingAttr(Ctx, CommonInfo, Slot, Space);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLResourceBindingAttr *HLSLResourceBindingAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Slot, llvm::StringRef Space, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Slot, Space, I);
}

HLSLResourceBindingAttr *HLSLResourceBindingAttr::Create(ASTContext &Ctx, llvm::StringRef Slot, llvm::StringRef Space, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Slot, Space, I);
}

HLSLResourceBindingAttr::HLSLResourceBindingAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Slot
              , llvm::StringRef Space
             )
  : InheritableAttr(Ctx, CommonInfo, attr::HLSLResourceBinding, false, false)
              , slotLength(Slot.size()),slot(new (Ctx, 1) char[slotLength])
              , spaceLength(Space.size()),space(new (Ctx, 1) char[spaceLength])
  {
    if (!Slot.empty())
      std::memcpy(slot, Slot.data(), slotLength);
    if (!Space.empty())
      std::memcpy(space, Space.data(), spaceLength);
}

HLSLResourceBindingAttr::HLSLResourceBindingAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Slot
             )
  : InheritableAttr(Ctx, CommonInfo, attr::HLSLResourceBinding, false, false)
              , slotLength(Slot.size()),slot(new (Ctx, 1) char[slotLength])
              , spaceLength(0),space(nullptr)
  {
    if (!Slot.empty())
      std::memcpy(slot, Slot.data(), slotLength);
}





HLSLResourceBindingAttr *HLSLResourceBindingAttr::clone(ASTContext &C) const {
  auto *A = new (C) HLSLResourceBindingAttr(C, *this, getSlot(), getSpace());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HLSLResourceBindingAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << ":register";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getSlot() << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getSpace() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "";
    break;
  }
}
}

const char *HLSLResourceBindingAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "register";
  }
}


// HLSLSV_GroupIndexAttr implementation

HLSLSV_GroupIndexAttr *HLSLSV_GroupIndexAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLSV_GroupIndexAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLSV_GroupIndexAttr *HLSLSV_GroupIndexAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLSV_GroupIndexAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLSV_GroupIndexAttr *HLSLSV_GroupIndexAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

HLSLSV_GroupIndexAttr *HLSLSV_GroupIndexAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

HLSLSV_GroupIndexAttr::HLSLSV_GroupIndexAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : HLSLAnnotationAttr(Ctx, CommonInfo, attr::HLSLSV_GroupIndex, false, false)
  {
}

HLSLSV_GroupIndexAttr *HLSLSV_GroupIndexAttr::clone(ASTContext &C) const {
  auto *A = new (C) HLSLSV_GroupIndexAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HLSLSV_GroupIndexAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << ":SV_GroupIndex";
    OS << "";
    break;
  }
}
}

const char *HLSLSV_GroupIndexAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "SV_GroupIndex";
  }
}


// HLSLShaderAttr implementation

HLSLShaderAttr *HLSLShaderAttr::CreateImplicit(ASTContext &Ctx, ShaderType Type, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLShaderAttr(Ctx, CommonInfo, Type);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLShaderAttr *HLSLShaderAttr::Create(ASTContext &Ctx, ShaderType Type, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HLSLShaderAttr(Ctx, CommonInfo, Type);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HLSLShaderAttr *HLSLShaderAttr::CreateImplicit(ASTContext &Ctx, ShaderType Type, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Type, I);
}

HLSLShaderAttr *HLSLShaderAttr::Create(ASTContext &Ctx, ShaderType Type, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Type, I);
}

HLSLShaderAttr::HLSLShaderAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ShaderType Type
             )
  : InheritableAttr(Ctx, CommonInfo, attr::HLSLShader, false, false)
              , type(Type)
  {
}



bool HLSLShaderAttr::ConvertStrToShaderType(StringRef Val, ShaderType &Out) {
  Optional<ShaderType> R = llvm::StringSwitch<Optional<ShaderType>>(Val)
    .Case("pixel", HLSLShaderAttr::Pixel)
    .Case("vertex", HLSLShaderAttr::Vertex)
    .Case("geometry", HLSLShaderAttr::Geometry)
    .Case("hull", HLSLShaderAttr::Hull)
    .Case("domain", HLSLShaderAttr::Domain)
    .Case("compute", HLSLShaderAttr::Compute)
    .Case("library", HLSLShaderAttr::Library)
    .Case("raygeneration", HLSLShaderAttr::RayGeneration)
    .Case("intersection", HLSLShaderAttr::Intersection)
    .Case("anyHit", HLSLShaderAttr::AnyHit)
    .Case("closestHit", HLSLShaderAttr::ClosestHit)
    .Case("miss", HLSLShaderAttr::Miss)
    .Case("callable", HLSLShaderAttr::Callable)
    .Case("mesh", HLSLShaderAttr::Mesh)
    .Case("amplification", HLSLShaderAttr::Amplification)
    .Default(Optional<ShaderType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *HLSLShaderAttr::ConvertShaderTypeToStr(ShaderType Val) {
  switch(Val) {
  case HLSLShaderAttr::Pixel: return "pixel";
  case HLSLShaderAttr::Vertex: return "vertex";
  case HLSLShaderAttr::Geometry: return "geometry";
  case HLSLShaderAttr::Hull: return "hull";
  case HLSLShaderAttr::Domain: return "domain";
  case HLSLShaderAttr::Compute: return "compute";
  case HLSLShaderAttr::Library: return "library";
  case HLSLShaderAttr::RayGeneration: return "raygeneration";
  case HLSLShaderAttr::Intersection: return "intersection";
  case HLSLShaderAttr::AnyHit: return "anyHit";
  case HLSLShaderAttr::ClosestHit: return "closestHit";
  case HLSLShaderAttr::Miss: return "miss";
  case HLSLShaderAttr::Callable: return "callable";
  case HLSLShaderAttr::Mesh: return "mesh";
  case HLSLShaderAttr::Amplification: return "amplification";
  }
  llvm_unreachable("No enumerator with that value");
}
HLSLShaderAttr *HLSLShaderAttr::clone(ASTContext &C) const {
  auto *A = new (C) HLSLShaderAttr(C, *this, type);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HLSLShaderAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "[shader";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << HLSLShaderAttr::ConvertShaderTypeToStr(getType()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]";
    break;
  }
}
}

const char *HLSLShaderAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "shader";
  }
}


// HotAttr implementation

HotAttr *HotAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HotAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HotAttr *HotAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) HotAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

HotAttr *HotAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

HotAttr *HotAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

HotAttr::HotAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Hot, false, false)
  {
}

HotAttr *HotAttr::clone(ASTContext &C) const {
  auto *A = new (C) HotAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void HotAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((hot";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::hot";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::hot";
    OS << "]]";
    break;
  }
}
}

const char *HotAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "hot";
  case 1:
    return "hot";
  case 2:
    return "hot";
  }
}


// IBActionAttr implementation

IBActionAttr *IBActionAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IBActionAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IBActionAttr *IBActionAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IBActionAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IBActionAttr *IBActionAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

IBActionAttr *IBActionAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

IBActionAttr::IBActionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::IBAction, false, false)
  {
}

IBActionAttr *IBActionAttr::clone(ASTContext &C) const {
  auto *A = new (C) IBActionAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void IBActionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ibaction";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ibaction";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ibaction";
    OS << "]]";
    break;
  }
}
}

const char *IBActionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ibaction";
  case 1:
    return "ibaction";
  case 2:
    return "ibaction";
  }
}


// IBOutletAttr implementation

IBOutletAttr *IBOutletAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IBOutletAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IBOutletAttr *IBOutletAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IBOutletAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IBOutletAttr *IBOutletAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

IBOutletAttr *IBOutletAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

IBOutletAttr::IBOutletAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::IBOutlet, false, false)
  {
}

IBOutletAttr *IBOutletAttr::clone(ASTContext &C) const {
  auto *A = new (C) IBOutletAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void IBOutletAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((iboutlet";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::iboutlet";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::iboutlet";
    OS << "]]";
    break;
  }
}
}

const char *IBOutletAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "iboutlet";
  case 1:
    return "iboutlet";
  case 2:
    return "iboutlet";
  }
}


// IBOutletCollectionAttr implementation

IBOutletCollectionAttr *IBOutletCollectionAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * Interface, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IBOutletCollectionAttr(Ctx, CommonInfo, Interface);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IBOutletCollectionAttr *IBOutletCollectionAttr::Create(ASTContext &Ctx, TypeSourceInfo * Interface, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IBOutletCollectionAttr(Ctx, CommonInfo, Interface);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IBOutletCollectionAttr *IBOutletCollectionAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * Interface, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Interface, I);
}

IBOutletCollectionAttr *IBOutletCollectionAttr::Create(ASTContext &Ctx, TypeSourceInfo * Interface, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Interface, I);
}

IBOutletCollectionAttr::IBOutletCollectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * Interface
             )
  : InheritableAttr(Ctx, CommonInfo, attr::IBOutletCollection, false, false)
              , interface_(Interface)
  {
}

IBOutletCollectionAttr::IBOutletCollectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::IBOutletCollection, false, false)
              , interface_()
  {
}



IBOutletCollectionAttr *IBOutletCollectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) IBOutletCollectionAttr(C, *this, interface_);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void IBOutletCollectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((iboutletcollection";
    if (!getInterfaceLoc())
      ++TrailingOmittedArgs;
    if (!(!getInterfaceLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getInterface().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::iboutletcollection";
    if (!getInterfaceLoc())
      ++TrailingOmittedArgs;
    if (!(!getInterfaceLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getInterface().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::iboutletcollection";
    if (!getInterfaceLoc())
      ++TrailingOmittedArgs;
    if (!(!getInterfaceLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getInterface().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *IBOutletCollectionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "iboutletcollection";
  case 1:
    return "iboutletcollection";
  case 2:
    return "iboutletcollection";
  }
}


// IFuncAttr implementation

IFuncAttr *IFuncAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Resolver, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IFuncAttr(Ctx, CommonInfo, Resolver);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IFuncAttr *IFuncAttr::Create(ASTContext &Ctx, llvm::StringRef Resolver, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IFuncAttr(Ctx, CommonInfo, Resolver);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IFuncAttr *IFuncAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Resolver, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Resolver, I);
}

IFuncAttr *IFuncAttr::Create(ASTContext &Ctx, llvm::StringRef Resolver, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Resolver, I);
}

IFuncAttr::IFuncAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Resolver
             )
  : Attr(Ctx, CommonInfo, attr::IFunc, false)
              , resolverLength(Resolver.size()),resolver(new (Ctx, 1) char[resolverLength])
  {
    if (!Resolver.empty())
      std::memcpy(resolver, Resolver.data(), resolverLength);
}



IFuncAttr *IFuncAttr::clone(ASTContext &C) const {
  auto *A = new (C) IFuncAttr(C, *this, getResolver());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void IFuncAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ifunc";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getResolver() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::ifunc";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getResolver() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::ifunc";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getResolver() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *IFuncAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ifunc";
  case 1:
    return "ifunc";
  case 2:
    return "ifunc";
  }
}


// InitPriorityAttr implementation

InitPriorityAttr *InitPriorityAttr::CreateImplicit(ASTContext &Ctx, unsigned Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) InitPriorityAttr(Ctx, CommonInfo, Priority);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

InitPriorityAttr *InitPriorityAttr::Create(ASTContext &Ctx, unsigned Priority, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) InitPriorityAttr(Ctx, CommonInfo, Priority);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

InitPriorityAttr *InitPriorityAttr::CreateImplicit(ASTContext &Ctx, unsigned Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Priority, I);
}

InitPriorityAttr *InitPriorityAttr::Create(ASTContext &Ctx, unsigned Priority, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Priority, I);
}

InitPriorityAttr::InitPriorityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Priority
             )
  : InheritableAttr(Ctx, CommonInfo, attr::InitPriority, false, false)
              , priority(Priority)
  {
}



InitPriorityAttr *InitPriorityAttr::clone(ASTContext &C) const {
  auto *A = new (C) InitPriorityAttr(C, *this, priority);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void InitPriorityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((init_priority";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::init_priority";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getPriority() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *InitPriorityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "init_priority";
  case 1:
    return "init_priority";
  }
}


// InitSegAttr implementation

InitSegAttr *InitSegAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Section, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) InitSegAttr(Ctx, CommonInfo, Section);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

InitSegAttr *InitSegAttr::Create(ASTContext &Ctx, llvm::StringRef Section, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) InitSegAttr(Ctx, CommonInfo, Section);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

InitSegAttr *InitSegAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Section, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Section, I);
}

InitSegAttr *InitSegAttr::Create(ASTContext &Ctx, llvm::StringRef Section, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Section, I);
}

InitSegAttr::InitSegAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Section
             )
  : Attr(Ctx, CommonInfo, attr::InitSeg, false)
              , sectionLength(Section.size()),section(new (Ctx, 1) char[sectionLength])
  {
    if (!Section.empty())
      std::memcpy(section, Section.data(), sectionLength);
}



InitSegAttr *InitSegAttr::clone(ASTContext &C) const {
  auto *A = new (C) InitSegAttr(C, *this, getSection());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void InitSegAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma init_seg";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

const char *InitSegAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "init_seg";
  }
}


// IntelOclBiccAttr implementation

IntelOclBiccAttr *IntelOclBiccAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IntelOclBiccAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IntelOclBiccAttr *IntelOclBiccAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) IntelOclBiccAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

IntelOclBiccAttr *IntelOclBiccAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

IntelOclBiccAttr *IntelOclBiccAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

IntelOclBiccAttr::IntelOclBiccAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::IntelOclBicc, false, false)
  {
}

IntelOclBiccAttr *IntelOclBiccAttr::clone(ASTContext &C) const {
  auto *A = new (C) IntelOclBiccAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void IntelOclBiccAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((intel_ocl_bicc";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::intel_ocl_bicc";
    OS << "]]";
    break;
  }
}
}

const char *IntelOclBiccAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "intel_ocl_bicc";
  case 1:
    return "intel_ocl_bicc";
  }
}


// InternalLinkageAttr implementation

InternalLinkageAttr *InternalLinkageAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) InternalLinkageAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

InternalLinkageAttr *InternalLinkageAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) InternalLinkageAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

InternalLinkageAttr *InternalLinkageAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

InternalLinkageAttr *InternalLinkageAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

InternalLinkageAttr::InternalLinkageAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::InternalLinkage, false, false)
  {
}

InternalLinkageAttr *InternalLinkageAttr::clone(ASTContext &C) const {
  auto *A = new (C) InternalLinkageAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void InternalLinkageAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((internal_linkage";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::internal_linkage";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::internal_linkage";
    OS << "]]";
    break;
  }
}
}

const char *InternalLinkageAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "internal_linkage";
  case 1:
    return "internal_linkage";
  case 2:
    return "internal_linkage";
  }
}


// LTOVisibilityPublicAttr implementation

LTOVisibilityPublicAttr *LTOVisibilityPublicAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LTOVisibilityPublicAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LTOVisibilityPublicAttr *LTOVisibilityPublicAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LTOVisibilityPublicAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LTOVisibilityPublicAttr *LTOVisibilityPublicAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

LTOVisibilityPublicAttr *LTOVisibilityPublicAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

LTOVisibilityPublicAttr::LTOVisibilityPublicAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::LTOVisibilityPublic, false, false)
  {
}

LTOVisibilityPublicAttr *LTOVisibilityPublicAttr::clone(ASTContext &C) const {
  auto *A = new (C) LTOVisibilityPublicAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LTOVisibilityPublicAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((lto_visibility_public";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::lto_visibility_public";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::lto_visibility_public";
    OS << "]]";
    break;
  }
}
}

const char *LTOVisibilityPublicAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "lto_visibility_public";
  case 1:
    return "lto_visibility_public";
  case 2:
    return "lto_visibility_public";
  }
}


// LayoutVersionAttr implementation

LayoutVersionAttr *LayoutVersionAttr::CreateImplicit(ASTContext &Ctx, unsigned Version, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LayoutVersionAttr(Ctx, CommonInfo, Version);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LayoutVersionAttr *LayoutVersionAttr::Create(ASTContext &Ctx, unsigned Version, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LayoutVersionAttr(Ctx, CommonInfo, Version);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LayoutVersionAttr *LayoutVersionAttr::CreateImplicit(ASTContext &Ctx, unsigned Version, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Version, I);
}

LayoutVersionAttr *LayoutVersionAttr::Create(ASTContext &Ctx, unsigned Version, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Version, I);
}

LayoutVersionAttr::LayoutVersionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Version
             )
  : InheritableAttr(Ctx, CommonInfo, attr::LayoutVersion, false, false)
              , version(Version)
  {
}



LayoutVersionAttr *LayoutVersionAttr::clone(ASTContext &C) const {
  auto *A = new (C) LayoutVersionAttr(C, *this, version);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LayoutVersionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(layout_version";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getVersion() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
}
}

const char *LayoutVersionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "layout_version";
  }
}


// LeafAttr implementation

LeafAttr *LeafAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LeafAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LeafAttr *LeafAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LeafAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LeafAttr *LeafAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

LeafAttr *LeafAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

LeafAttr::LeafAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Leaf, false, false)
  {
}

LeafAttr *LeafAttr::clone(ASTContext &C) const {
  auto *A = new (C) LeafAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LeafAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((leaf";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::leaf";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::leaf";
    OS << "]]";
    break;
  }
}
}

const char *LeafAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "leaf";
  case 1:
    return "leaf";
  case 2:
    return "leaf";
  }
}


// LifetimeBoundAttr implementation

LifetimeBoundAttr *LifetimeBoundAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LifetimeBoundAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LifetimeBoundAttr *LifetimeBoundAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LifetimeBoundAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LifetimeBoundAttr *LifetimeBoundAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

LifetimeBoundAttr *LifetimeBoundAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

LifetimeBoundAttr::LifetimeBoundAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::LifetimeBound, false, false)
  {
}

LifetimeBoundAttr *LifetimeBoundAttr::clone(ASTContext &C) const {
  auto *A = new (C) LifetimeBoundAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LifetimeBoundAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((lifetimebound";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::lifetimebound";
    OS << "]]";
    break;
  }
}
}

const char *LifetimeBoundAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "lifetimebound";
  case 1:
    return "lifetimebound";
  }
}


// LikelyAttr implementation

LikelyAttr *LikelyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LikelyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LikelyAttr *LikelyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LikelyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LikelyAttr *LikelyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

LikelyAttr *LikelyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

LikelyAttr::LikelyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::Likely, false)
  {
}

LikelyAttr *LikelyAttr::clone(ASTContext &C) const {
  auto *A = new (C) LikelyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LikelyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[likely";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[clang::likely";
    OS << "]]";
    break;
  }
}
}

const char *LikelyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "likely";
  case 1:
    return "likely";
  }
}


// LoaderUninitializedAttr implementation

LoaderUninitializedAttr *LoaderUninitializedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LoaderUninitializedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LoaderUninitializedAttr *LoaderUninitializedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LoaderUninitializedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LoaderUninitializedAttr *LoaderUninitializedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

LoaderUninitializedAttr *LoaderUninitializedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

LoaderUninitializedAttr::LoaderUninitializedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::LoaderUninitialized, false)
  {
}

LoaderUninitializedAttr *LoaderUninitializedAttr::clone(ASTContext &C) const {
  auto *A = new (C) LoaderUninitializedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LoaderUninitializedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((loader_uninitialized";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::loader_uninitialized";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::loader_uninitialized";
    OS << "]]";
    break;
  }
}
}

const char *LoaderUninitializedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "loader_uninitialized";
  case 1:
    return "loader_uninitialized";
  case 2:
    return "loader_uninitialized";
  }
}


// LockReturnedAttr implementation

LockReturnedAttr *LockReturnedAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LockReturnedAttr(Ctx, CommonInfo, Arg);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LockReturnedAttr *LockReturnedAttr::Create(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LockReturnedAttr(Ctx, CommonInfo, Arg);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LockReturnedAttr *LockReturnedAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Arg, I);
}

LockReturnedAttr *LockReturnedAttr::Create(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Arg, I);
}

LockReturnedAttr::LockReturnedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Arg
             )
  : InheritableAttr(Ctx, CommonInfo, attr::LockReturned, true, false)
              , arg(Arg)
  {
}



LockReturnedAttr *LockReturnedAttr::clone(ASTContext &C) const {
  auto *A = new (C) LockReturnedAttr(C, *this, arg);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LockReturnedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((lock_returned";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *LockReturnedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "lock_returned";
  }
}


// LocksExcludedAttr implementation

LocksExcludedAttr *LocksExcludedAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LocksExcludedAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LocksExcludedAttr *LocksExcludedAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LocksExcludedAttr(Ctx, CommonInfo, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LocksExcludedAttr *LocksExcludedAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

LocksExcludedAttr *LocksExcludedAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Args, ArgsSize, I);
}

LocksExcludedAttr::LocksExcludedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::LocksExcluded, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

LocksExcludedAttr::LocksExcludedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::LocksExcluded, true, true)
              , args_Size(0), args_(nullptr)
  {
}



LocksExcludedAttr *LocksExcludedAttr::clone(ASTContext &C) const {
  auto *A = new (C) LocksExcludedAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LocksExcludedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((locks_excluded";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *LocksExcludedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "locks_excluded";
  }
}


// LoopHintAttr implementation

LoopHintAttr *LoopHintAttr::CreateImplicit(ASTContext &Ctx, OptionType Option, LoopHintState State, Expr * Value, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LoopHintAttr(Ctx, CommonInfo, Option, State, Value);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

LoopHintAttr *LoopHintAttr::Create(ASTContext &Ctx, OptionType Option, LoopHintState State, Expr * Value, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) LoopHintAttr(Ctx, CommonInfo, Option, State, Value);
  return A;
}

LoopHintAttr *LoopHintAttr::CreateImplicit(ASTContext &Ctx, OptionType Option, LoopHintState State, Expr * Value, SourceRange Range, AttributeCommonInfo::Syntax Syntax, LoopHintAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Option, State, Value, I);
}

LoopHintAttr *LoopHintAttr::Create(ASTContext &Ctx, OptionType Option, LoopHintState State, Expr * Value, SourceRange Range, AttributeCommonInfo::Syntax Syntax, LoopHintAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Option, State, Value, I);
}

LoopHintAttr::LoopHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , OptionType Option
              , LoopHintState State
              , Expr * Value
             )
  : Attr(Ctx, CommonInfo, attr::LoopHint, false)
              , option(Option)
              , state(State)
              , value(Value)
  {
}

LoopHintAttr::Spelling LoopHintAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Pragma_clang_loop;
    case 1: return Pragma_unroll;
    case 2: return Pragma_nounroll;
    case 3: return Pragma_unroll_and_jam;
    case 4: return Pragma_nounroll_and_jam;
  }
}


bool LoopHintAttr::ConvertStrToOptionType(StringRef Val, OptionType &Out) {
  Optional<OptionType> R = llvm::StringSwitch<Optional<OptionType>>(Val)
    .Case("vectorize", LoopHintAttr::Vectorize)
    .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
    .Case("interleave", LoopHintAttr::Interleave)
    .Case("interleave_count", LoopHintAttr::InterleaveCount)
    .Case("unroll", LoopHintAttr::Unroll)
    .Case("unroll_count", LoopHintAttr::UnrollCount)
    .Case("unroll_and_jam", LoopHintAttr::UnrollAndJam)
    .Case("unroll_and_jam_count", LoopHintAttr::UnrollAndJamCount)
    .Case("pipeline", LoopHintAttr::PipelineDisabled)
    .Case("pipeline_initiation_interval", LoopHintAttr::PipelineInitiationInterval)
    .Case("distribute", LoopHintAttr::Distribute)
    .Case("vectorize_predicate", LoopHintAttr::VectorizePredicate)
    .Default(Optional<OptionType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *LoopHintAttr::ConvertOptionTypeToStr(OptionType Val) {
  switch(Val) {
  case LoopHintAttr::Vectorize: return "vectorize";
  case LoopHintAttr::VectorizeWidth: return "vectorize_width";
  case LoopHintAttr::Interleave: return "interleave";
  case LoopHintAttr::InterleaveCount: return "interleave_count";
  case LoopHintAttr::Unroll: return "unroll";
  case LoopHintAttr::UnrollCount: return "unroll_count";
  case LoopHintAttr::UnrollAndJam: return "unroll_and_jam";
  case LoopHintAttr::UnrollAndJamCount: return "unroll_and_jam_count";
  case LoopHintAttr::PipelineDisabled: return "pipeline";
  case LoopHintAttr::PipelineInitiationInterval: return "pipeline_initiation_interval";
  case LoopHintAttr::Distribute: return "distribute";
  case LoopHintAttr::VectorizePredicate: return "vectorize_predicate";
  }
  llvm_unreachable("No enumerator with that value");
}


bool LoopHintAttr::ConvertStrToLoopHintState(StringRef Val, LoopHintState &Out) {
  Optional<LoopHintState> R = llvm::StringSwitch<Optional<LoopHintState>>(Val)
    .Case("enable", LoopHintAttr::Enable)
    .Case("disable", LoopHintAttr::Disable)
    .Case("numeric", LoopHintAttr::Numeric)
    .Case("fixed_width", LoopHintAttr::FixedWidth)
    .Case("scalable_width", LoopHintAttr::ScalableWidth)
    .Case("assume_safety", LoopHintAttr::AssumeSafety)
    .Case("full", LoopHintAttr::Full)
    .Default(Optional<LoopHintState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *LoopHintAttr::ConvertLoopHintStateToStr(LoopHintState Val) {
  switch(Val) {
  case LoopHintAttr::Enable: return "enable";
  case LoopHintAttr::Disable: return "disable";
  case LoopHintAttr::Numeric: return "numeric";
  case LoopHintAttr::FixedWidth: return "fixed_width";
  case LoopHintAttr::ScalableWidth: return "scalable_width";
  case LoopHintAttr::AssumeSafety: return "assume_safety";
  case LoopHintAttr::Full: return "full";
  }
  llvm_unreachable("No enumerator with that value");
}


LoopHintAttr *LoopHintAttr::clone(ASTContext &C) const {
  auto *A = new (C) LoopHintAttr(C, *this, option, state, value);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void LoopHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma clang loop";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
  case 1 : {
    OS << "#pragma unroll";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
  case 2 : {
    OS << "#pragma nounroll";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
  case 3 : {
    OS << "#pragma unroll_and_jam";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
  case 4 : {
    OS << "#pragma nounroll_and_jam";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

const char *LoopHintAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "loop";
  case 1:
    return "unroll";
  case 2:
    return "nounroll";
  case 3:
    return "unroll_and_jam";
  case 4:
    return "nounroll_and_jam";
  }
}


// M68kInterruptAttr implementation

M68kInterruptAttr *M68kInterruptAttr::CreateImplicit(ASTContext &Ctx, unsigned Number, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) M68kInterruptAttr(Ctx, CommonInfo, Number);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

M68kInterruptAttr *M68kInterruptAttr::Create(ASTContext &Ctx, unsigned Number, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) M68kInterruptAttr(Ctx, CommonInfo, Number);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

M68kInterruptAttr *M68kInterruptAttr::CreateImplicit(ASTContext &Ctx, unsigned Number, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Number, I);
}

M68kInterruptAttr *M68kInterruptAttr::Create(ASTContext &Ctx, unsigned Number, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Number, I);
}

M68kInterruptAttr::M68kInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Number
             )
  : InheritableAttr(Ctx, CommonInfo, attr::M68kInterrupt, false, false)
              , number(Number)
  {
}



M68kInterruptAttr *M68kInterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) M68kInterruptAttr(C, *this, number);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void M68kInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumber() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *M68kInterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  }
}


// MIGServerRoutineAttr implementation

MIGServerRoutineAttr *MIGServerRoutineAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MIGServerRoutineAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MIGServerRoutineAttr *MIGServerRoutineAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MIGServerRoutineAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MIGServerRoutineAttr *MIGServerRoutineAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MIGServerRoutineAttr *MIGServerRoutineAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MIGServerRoutineAttr::MIGServerRoutineAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MIGServerRoutine, false, false)
  {
}

MIGServerRoutineAttr *MIGServerRoutineAttr::clone(ASTContext &C) const {
  auto *A = new (C) MIGServerRoutineAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MIGServerRoutineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((mig_server_routine";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::mig_server_routine";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::mig_server_routine";
    OS << "]]";
    break;
  }
}
}

const char *MIGServerRoutineAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "mig_server_routine";
  case 1:
    return "mig_server_routine";
  case 2:
    return "mig_server_routine";
  }
}


// MSABIAttr implementation

MSABIAttr *MSABIAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSABIAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSABIAttr *MSABIAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSABIAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSABIAttr *MSABIAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MSABIAttr *MSABIAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MSABIAttr::MSABIAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSABI, false, false)
  {
}

MSABIAttr *MSABIAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSABIAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ms_abi";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::ms_abi";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::ms_abi";
    OS << "]]";
    break;
  }
}
}

const char *MSABIAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ms_abi";
  case 1:
    return "ms_abi";
  case 2:
    return "ms_abi";
  }
}


// MSAllocatorAttr implementation

MSAllocatorAttr *MSAllocatorAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSAllocatorAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSAllocatorAttr *MSAllocatorAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSAllocatorAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSAllocatorAttr *MSAllocatorAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MSAllocatorAttr *MSAllocatorAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MSAllocatorAttr::MSAllocatorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSAllocator, false, false)
  {
}

MSAllocatorAttr *MSAllocatorAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSAllocatorAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSAllocatorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(allocator";
    OS << ")";
    break;
  }
}
}

const char *MSAllocatorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "allocator";
  }
}


// MSInheritanceAttr implementation

MSInheritanceAttr *MSInheritanceAttr::CreateImplicit(ASTContext &Ctx, bool BestCase, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSInheritanceAttr(Ctx, CommonInfo, BestCase);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSInheritanceAttr *MSInheritanceAttr::Create(ASTContext &Ctx, bool BestCase, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSInheritanceAttr(Ctx, CommonInfo, BestCase);
  return A;
}

MSInheritanceAttr *MSInheritanceAttr::CreateImplicit(ASTContext &Ctx, bool BestCase, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MSInheritanceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, BestCase, I);
}

MSInheritanceAttr *MSInheritanceAttr::Create(ASTContext &Ctx, bool BestCase, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MSInheritanceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, BestCase, I);
}

MSInheritanceAttr *MSInheritanceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSInheritanceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSInheritanceAttr *MSInheritanceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSInheritanceAttr(Ctx, CommonInfo);
  return A;
}

MSInheritanceAttr *MSInheritanceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MSInheritanceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

MSInheritanceAttr *MSInheritanceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MSInheritanceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

MSInheritanceAttr::MSInheritanceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , bool BestCase
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSInheritance, false, false)
              , bestCase(BestCase)
  {
}

MSInheritanceAttr::MSInheritanceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSInheritance, false, false)
              , bestCase()
  {
}

MSInheritanceAttr::Spelling MSInheritanceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_single_inheritance;
    case 1: return Keyword_multiple_inheritance;
    case 2: return Keyword_virtual_inheritance;
    case 3: return Keyword_unspecified_inheritance;
  }
}


MSInheritanceAttr *MSInheritanceAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSInheritanceAttr(C, *this, bestCase);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSInheritanceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __single_inheritance";
    OS << "";
    break;
  }
  case 1 : {
    OS << " __multiple_inheritance";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __virtual_inheritance";
    OS << "";
    break;
  }
  case 3 : {
    OS << " __unspecified_inheritance";
    OS << "";
    break;
  }
}
}

const char *MSInheritanceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__single_inheritance";
  case 1:
    return "__multiple_inheritance";
  case 2:
    return "__virtual_inheritance";
  case 3:
    return "__unspecified_inheritance";
  }
}


// MSNoVTableAttr implementation

MSNoVTableAttr *MSNoVTableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSNoVTableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSNoVTableAttr *MSNoVTableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSNoVTableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSNoVTableAttr *MSNoVTableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MSNoVTableAttr *MSNoVTableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MSNoVTableAttr::MSNoVTableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSNoVTable, false, false)
  {
}

MSNoVTableAttr *MSNoVTableAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSNoVTableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSNoVTableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(novtable";
    OS << ")";
    break;
  }
}
}

const char *MSNoVTableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "novtable";
  }
}


// MSP430InterruptAttr implementation

MSP430InterruptAttr *MSP430InterruptAttr::CreateImplicit(ASTContext &Ctx, unsigned Number, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSP430InterruptAttr(Ctx, CommonInfo, Number);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSP430InterruptAttr *MSP430InterruptAttr::Create(ASTContext &Ctx, unsigned Number, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSP430InterruptAttr(Ctx, CommonInfo, Number);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSP430InterruptAttr *MSP430InterruptAttr::CreateImplicit(ASTContext &Ctx, unsigned Number, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Number, I);
}

MSP430InterruptAttr *MSP430InterruptAttr::Create(ASTContext &Ctx, unsigned Number, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Number, I);
}

MSP430InterruptAttr::MSP430InterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Number
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSP430Interrupt, false, false)
              , number(Number)
  {
}



MSP430InterruptAttr *MSP430InterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSP430InterruptAttr(C, *this, number);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSP430InterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumber() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumber() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNumber() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *MSP430InterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// MSStructAttr implementation

MSStructAttr *MSStructAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSStructAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSStructAttr *MSStructAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSStructAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSStructAttr *MSStructAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MSStructAttr *MSStructAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MSStructAttr::MSStructAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSStruct, false, false)
  {
}

MSStructAttr *MSStructAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSStructAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSStructAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ms_struct";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::ms_struct";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::ms_struct";
    OS << "]]";
    break;
  }
}
}

const char *MSStructAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ms_struct";
  case 1:
    return "ms_struct";
  case 2:
    return "ms_struct";
  }
}


// MSVtorDispAttr implementation

MSVtorDispAttr *MSVtorDispAttr::CreateImplicit(ASTContext &Ctx, unsigned Vdm, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSVtorDispAttr(Ctx, CommonInfo, Vdm);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSVtorDispAttr *MSVtorDispAttr::Create(ASTContext &Ctx, unsigned Vdm, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MSVtorDispAttr(Ctx, CommonInfo, Vdm);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MSVtorDispAttr *MSVtorDispAttr::CreateImplicit(ASTContext &Ctx, unsigned Vdm, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Vdm, I);
}

MSVtorDispAttr *MSVtorDispAttr::Create(ASTContext &Ctx, unsigned Vdm, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Vdm, I);
}

MSVtorDispAttr::MSVtorDispAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Vdm
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MSVtorDisp, false, false)
              , vdm(Vdm)
  {
}



MSVtorDispAttr *MSVtorDispAttr::clone(ASTContext &C) const {
  auto *A = new (C) MSVtorDispAttr(C, *this, vdm);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MSVtorDispAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *MSVtorDispAttr::getSpelling() const {
  return "(No spelling)";
}


// MaxFieldAlignmentAttr implementation

MaxFieldAlignmentAttr *MaxFieldAlignmentAttr::CreateImplicit(ASTContext &Ctx, unsigned Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MaxFieldAlignmentAttr(Ctx, CommonInfo, Alignment);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MaxFieldAlignmentAttr *MaxFieldAlignmentAttr::Create(ASTContext &Ctx, unsigned Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MaxFieldAlignmentAttr(Ctx, CommonInfo, Alignment);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MaxFieldAlignmentAttr *MaxFieldAlignmentAttr::CreateImplicit(ASTContext &Ctx, unsigned Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Alignment, I);
}

MaxFieldAlignmentAttr *MaxFieldAlignmentAttr::Create(ASTContext &Ctx, unsigned Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Alignment, I);
}

MaxFieldAlignmentAttr::MaxFieldAlignmentAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Alignment
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MaxFieldAlignment, false, false)
              , alignment(Alignment)
  {
}



MaxFieldAlignmentAttr *MaxFieldAlignmentAttr::clone(ASTContext &C) const {
  auto *A = new (C) MaxFieldAlignmentAttr(C, *this, alignment);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MaxFieldAlignmentAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *MaxFieldAlignmentAttr::getSpelling() const {
  return "(No spelling)";
}


// MayAliasAttr implementation

MayAliasAttr *MayAliasAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MayAliasAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MayAliasAttr *MayAliasAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MayAliasAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MayAliasAttr *MayAliasAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MayAliasAttr *MayAliasAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MayAliasAttr::MayAliasAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MayAlias, false, false)
  {
}

MayAliasAttr *MayAliasAttr::clone(ASTContext &C) const {
  auto *A = new (C) MayAliasAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MayAliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((may_alias";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::may_alias";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::may_alias";
    OS << "]]";
    break;
  }
}
}

const char *MayAliasAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "may_alias";
  case 1:
    return "may_alias";
  case 2:
    return "may_alias";
  }
}


// MaybeUndefAttr implementation

MaybeUndefAttr *MaybeUndefAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MaybeUndefAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MaybeUndefAttr *MaybeUndefAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MaybeUndefAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MaybeUndefAttr *MaybeUndefAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MaybeUndefAttr *MaybeUndefAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MaybeUndefAttr::MaybeUndefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MaybeUndef, false, false)
  {
}

MaybeUndefAttr *MaybeUndefAttr::clone(ASTContext &C) const {
  auto *A = new (C) MaybeUndefAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MaybeUndefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((maybe_undef";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::maybe_undef";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::maybe_undef";
    OS << "]]";
    break;
  }
}
}

const char *MaybeUndefAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "maybe_undef";
  case 1:
    return "maybe_undef";
  case 2:
    return "maybe_undef";
  }
}


// MicroMipsAttr implementation

MicroMipsAttr *MicroMipsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MicroMipsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MicroMipsAttr *MicroMipsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MicroMipsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MicroMipsAttr *MicroMipsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MicroMipsAttr *MicroMipsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MicroMipsAttr::MicroMipsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MicroMips, false, false)
  {
}

MicroMipsAttr *MicroMipsAttr::clone(ASTContext &C) const {
  auto *A = new (C) MicroMipsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MicroMipsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((micromips";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::micromips";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::micromips";
    OS << "]]";
    break;
  }
}
}

const char *MicroMipsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "micromips";
  case 1:
    return "micromips";
  case 2:
    return "micromips";
  }
}


// MinSizeAttr implementation

MinSizeAttr *MinSizeAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MinSizeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MinSizeAttr *MinSizeAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MinSizeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MinSizeAttr *MinSizeAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MinSizeAttr *MinSizeAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MinSizeAttr::MinSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MinSize, false, false)
  {
}

MinSizeAttr *MinSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) MinSizeAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MinSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((minsize";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::minsize";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::minsize";
    OS << "]]";
    break;
  }
}
}

const char *MinSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "minsize";
  case 1:
    return "minsize";
  case 2:
    return "minsize";
  }
}


// MinVectorWidthAttr implementation

MinVectorWidthAttr *MinVectorWidthAttr::CreateImplicit(ASTContext &Ctx, unsigned VectorWidth, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MinVectorWidthAttr(Ctx, CommonInfo, VectorWidth);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MinVectorWidthAttr *MinVectorWidthAttr::Create(ASTContext &Ctx, unsigned VectorWidth, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MinVectorWidthAttr(Ctx, CommonInfo, VectorWidth);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MinVectorWidthAttr *MinVectorWidthAttr::CreateImplicit(ASTContext &Ctx, unsigned VectorWidth, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, VectorWidth, I);
}

MinVectorWidthAttr *MinVectorWidthAttr::Create(ASTContext &Ctx, unsigned VectorWidth, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, VectorWidth, I);
}

MinVectorWidthAttr::MinVectorWidthAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned VectorWidth
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MinVectorWidth, false, false)
              , vectorWidth(VectorWidth)
  {
}



MinVectorWidthAttr *MinVectorWidthAttr::clone(ASTContext &C) const {
  auto *A = new (C) MinVectorWidthAttr(C, *this, vectorWidth);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MinVectorWidthAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((min_vector_width";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getVectorWidth() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::min_vector_width";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getVectorWidth() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::min_vector_width";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getVectorWidth() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *MinVectorWidthAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "min_vector_width";
  case 1:
    return "min_vector_width";
  case 2:
    return "min_vector_width";
  }
}


// Mips16Attr implementation

Mips16Attr *Mips16Attr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Mips16Attr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Mips16Attr *Mips16Attr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Mips16Attr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Mips16Attr *Mips16Attr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

Mips16Attr *Mips16Attr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

Mips16Attr::Mips16Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Mips16, false, false)
  {
}

Mips16Attr *Mips16Attr::clone(ASTContext &C) const {
  auto *A = new (C) Mips16Attr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void Mips16Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((mips16";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::mips16";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::mips16";
    OS << "]]";
    break;
  }
}
}

const char *Mips16Attr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "mips16";
  case 1:
    return "mips16";
  case 2:
    return "mips16";
  }
}


// MipsInterruptAttr implementation

MipsInterruptAttr *MipsInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MipsInterruptAttr(Ctx, CommonInfo, Interrupt);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MipsInterruptAttr *MipsInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MipsInterruptAttr(Ctx, CommonInfo, Interrupt);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MipsInterruptAttr *MipsInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Interrupt, I);
}

MipsInterruptAttr *MipsInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Interrupt, I);
}

MipsInterruptAttr::MipsInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , InterruptType Interrupt
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MipsInterrupt, false, false)
              , interrupt(Interrupt)
  {
}



bool MipsInterruptAttr::ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
  Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
    .Case("vector=sw0", MipsInterruptAttr::sw0)
    .Case("vector=sw1", MipsInterruptAttr::sw1)
    .Case("vector=hw0", MipsInterruptAttr::hw0)
    .Case("vector=hw1", MipsInterruptAttr::hw1)
    .Case("vector=hw2", MipsInterruptAttr::hw2)
    .Case("vector=hw3", MipsInterruptAttr::hw3)
    .Case("vector=hw4", MipsInterruptAttr::hw4)
    .Case("vector=hw5", MipsInterruptAttr::hw5)
    .Case("eic", MipsInterruptAttr::eic)
    .Case("", MipsInterruptAttr::eic)
    .Default(Optional<InterruptType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *MipsInterruptAttr::ConvertInterruptTypeToStr(InterruptType Val) {
  switch(Val) {
  case MipsInterruptAttr::sw0: return "vector=sw0";
  case MipsInterruptAttr::sw1: return "vector=sw1";
  case MipsInterruptAttr::hw0: return "vector=hw0";
  case MipsInterruptAttr::hw1: return "vector=hw1";
  case MipsInterruptAttr::hw2: return "vector=hw2";
  case MipsInterruptAttr::hw3: return "vector=hw3";
  case MipsInterruptAttr::hw4: return "vector=hw4";
  case MipsInterruptAttr::hw5: return "vector=hw5";
  case MipsInterruptAttr::eic: return "eic";
  }
  llvm_unreachable("No enumerator with that value");
}
MipsInterruptAttr *MipsInterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) MipsInterruptAttr(C, *this, interrupt);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MipsInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << MipsInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << MipsInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << MipsInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *MipsInterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// MipsLongCallAttr implementation

MipsLongCallAttr *MipsLongCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MipsLongCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MipsLongCallAttr *MipsLongCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MipsLongCallAttr(Ctx, CommonInfo);
  return A;
}

MipsLongCallAttr *MipsLongCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MipsLongCallAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

MipsLongCallAttr *MipsLongCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MipsLongCallAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

MipsLongCallAttr::MipsLongCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MipsLongCall, false, false)
  {
}

MipsLongCallAttr::Spelling MipsLongCallAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_long_call;
    case 1: return CXX11_gnu_long_call;
    case 2: return C2x_gnu_long_call;
    case 3: return GNU_far;
    case 4: return CXX11_gnu_far;
    case 5: return C2x_gnu_far;
  }
}
MipsLongCallAttr *MipsLongCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) MipsLongCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MipsLongCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((long_call";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::long_call";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::long_call";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((far";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::far";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::far";
    OS << "]]";
    break;
  }
}
}

const char *MipsLongCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "long_call";
  case 1:
    return "long_call";
  case 2:
    return "long_call";
  case 3:
    return "far";
  case 4:
    return "far";
  case 5:
    return "far";
  }
}


// MipsShortCallAttr implementation

MipsShortCallAttr *MipsShortCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MipsShortCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MipsShortCallAttr *MipsShortCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MipsShortCallAttr(Ctx, CommonInfo);
  return A;
}

MipsShortCallAttr *MipsShortCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MipsShortCallAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

MipsShortCallAttr *MipsShortCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, MipsShortCallAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

MipsShortCallAttr::MipsShortCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::MipsShortCall, false, false)
  {
}

MipsShortCallAttr::Spelling MipsShortCallAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_short_call;
    case 1: return CXX11_gnu_short_call;
    case 2: return C2x_gnu_short_call;
    case 3: return GNU_near;
    case 4: return CXX11_gnu_near;
    case 5: return C2x_gnu_near;
  }
}
MipsShortCallAttr *MipsShortCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) MipsShortCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MipsShortCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((short_call";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::short_call";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::short_call";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((near";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::near";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::near";
    OS << "]]";
    break;
  }
}
}

const char *MipsShortCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "short_call";
  case 1:
    return "short_call";
  case 2:
    return "short_call";
  case 3:
    return "near";
  case 4:
    return "near";
  case 5:
    return "near";
  }
}


// ModeAttr implementation

ModeAttr *ModeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Mode, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ModeAttr(Ctx, CommonInfo, Mode);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ModeAttr *ModeAttr::Create(ASTContext &Ctx, IdentifierInfo * Mode, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ModeAttr(Ctx, CommonInfo, Mode);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ModeAttr *ModeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Mode, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Mode, I);
}

ModeAttr *ModeAttr::Create(ASTContext &Ctx, IdentifierInfo * Mode, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Mode, I);
}

ModeAttr::ModeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Mode
             )
  : Attr(Ctx, CommonInfo, attr::Mode, false)
              , mode(Mode)
  {
}



ModeAttr *ModeAttr::clone(ASTContext &C) const {
  auto *A = new (C) ModeAttr(C, *this, mode);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ModeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((mode";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getMode() ? getMode()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::mode";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getMode() ? getMode()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::mode";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getMode() ? getMode()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ModeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "mode";
  case 1:
    return "mode";
  case 2:
    return "mode";
  }
}


// MustTailAttr implementation

MustTailAttr *MustTailAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MustTailAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MustTailAttr *MustTailAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) MustTailAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

MustTailAttr *MustTailAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

MustTailAttr *MustTailAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

MustTailAttr::MustTailAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::MustTail, false)
  {
}

MustTailAttr *MustTailAttr::clone(ASTContext &C) const {
  auto *A = new (C) MustTailAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void MustTailAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((musttail";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::musttail";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::musttail";
    OS << "]]";
    break;
  }
}
}

const char *MustTailAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "musttail";
  case 1:
    return "musttail";
  case 2:
    return "musttail";
  }
}


// NSConsumedAttr implementation

NSConsumedAttr *NSConsumedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSConsumedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSConsumedAttr *NSConsumedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSConsumedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSConsumedAttr *NSConsumedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NSConsumedAttr *NSConsumedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NSConsumedAttr::NSConsumedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::NSConsumed, false, false)
  {
}

NSConsumedAttr *NSConsumedAttr::clone(ASTContext &C) const {
  auto *A = new (C) NSConsumedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NSConsumedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ns_consumed";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ns_consumed";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ns_consumed";
    OS << "]]";
    break;
  }
}
}

const char *NSConsumedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ns_consumed";
  case 1:
    return "ns_consumed";
  case 2:
    return "ns_consumed";
  }
}


// NSConsumesSelfAttr implementation

NSConsumesSelfAttr *NSConsumesSelfAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSConsumesSelfAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSConsumesSelfAttr *NSConsumesSelfAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSConsumesSelfAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSConsumesSelfAttr *NSConsumesSelfAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NSConsumesSelfAttr *NSConsumesSelfAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NSConsumesSelfAttr::NSConsumesSelfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NSConsumesSelf, false, false)
  {
}

NSConsumesSelfAttr *NSConsumesSelfAttr::clone(ASTContext &C) const {
  auto *A = new (C) NSConsumesSelfAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NSConsumesSelfAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ns_consumes_self";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ns_consumes_self";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ns_consumes_self";
    OS << "]]";
    break;
  }
}
}

const char *NSConsumesSelfAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ns_consumes_self";
  case 1:
    return "ns_consumes_self";
  case 2:
    return "ns_consumes_self";
  }
}


// NSErrorDomainAttr implementation

NSErrorDomainAttr *NSErrorDomainAttr::CreateImplicit(ASTContext &Ctx, VarDecl * ErrorDomain, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSErrorDomainAttr(Ctx, CommonInfo, ErrorDomain);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSErrorDomainAttr *NSErrorDomainAttr::Create(ASTContext &Ctx, VarDecl * ErrorDomain, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSErrorDomainAttr(Ctx, CommonInfo, ErrorDomain);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSErrorDomainAttr *NSErrorDomainAttr::CreateImplicit(ASTContext &Ctx, VarDecl * ErrorDomain, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ErrorDomain, I);
}

NSErrorDomainAttr *NSErrorDomainAttr::Create(ASTContext &Ctx, VarDecl * ErrorDomain, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ErrorDomain, I);
}

NSErrorDomainAttr::NSErrorDomainAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , VarDecl * ErrorDomain
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NSErrorDomain, false, false)
              , errorDomain(ErrorDomain)
  {
}



NSErrorDomainAttr *NSErrorDomainAttr::clone(ASTContext &C) const {
  auto *A = new (C) NSErrorDomainAttr(C, *this, errorDomain);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NSErrorDomainAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ns_error_domain";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getErrorDomain()->getName() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *NSErrorDomainAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ns_error_domain";
  }
}


// NSReturnsAutoreleasedAttr implementation

NSReturnsAutoreleasedAttr *NSReturnsAutoreleasedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSReturnsAutoreleasedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSReturnsAutoreleasedAttr *NSReturnsAutoreleasedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSReturnsAutoreleasedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSReturnsAutoreleasedAttr *NSReturnsAutoreleasedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NSReturnsAutoreleasedAttr *NSReturnsAutoreleasedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NSReturnsAutoreleasedAttr::NSReturnsAutoreleasedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NSReturnsAutoreleased, false, false)
  {
}

NSReturnsAutoreleasedAttr *NSReturnsAutoreleasedAttr::clone(ASTContext &C) const {
  auto *A = new (C) NSReturnsAutoreleasedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NSReturnsAutoreleasedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ns_returns_autoreleased";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ns_returns_autoreleased";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ns_returns_autoreleased";
    OS << "]]";
    break;
  }
}
}

const char *NSReturnsAutoreleasedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ns_returns_autoreleased";
  case 1:
    return "ns_returns_autoreleased";
  case 2:
    return "ns_returns_autoreleased";
  }
}


// NSReturnsNotRetainedAttr implementation

NSReturnsNotRetainedAttr *NSReturnsNotRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSReturnsNotRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSReturnsNotRetainedAttr *NSReturnsNotRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSReturnsNotRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSReturnsNotRetainedAttr *NSReturnsNotRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NSReturnsNotRetainedAttr *NSReturnsNotRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NSReturnsNotRetainedAttr::NSReturnsNotRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NSReturnsNotRetained, false, false)
  {
}

NSReturnsNotRetainedAttr *NSReturnsNotRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) NSReturnsNotRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NSReturnsNotRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ns_returns_not_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ns_returns_not_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ns_returns_not_retained";
    OS << "]]";
    break;
  }
}
}

const char *NSReturnsNotRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ns_returns_not_retained";
  case 1:
    return "ns_returns_not_retained";
  case 2:
    return "ns_returns_not_retained";
  }
}


// NSReturnsRetainedAttr implementation

NSReturnsRetainedAttr *NSReturnsRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSReturnsRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSReturnsRetainedAttr *NSReturnsRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NSReturnsRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NSReturnsRetainedAttr *NSReturnsRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NSReturnsRetainedAttr *NSReturnsRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NSReturnsRetainedAttr::NSReturnsRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NSReturnsRetained, false, false)
  {
}

NSReturnsRetainedAttr *NSReturnsRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) NSReturnsRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NSReturnsRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ns_returns_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ns_returns_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ns_returns_retained";
    OS << "]]";
    break;
  }
}
}

const char *NSReturnsRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ns_returns_retained";
  case 1:
    return "ns_returns_retained";
  case 2:
    return "ns_returns_retained";
  }
}


// NakedAttr implementation

NakedAttr *NakedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NakedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NakedAttr *NakedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NakedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NakedAttr *NakedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NakedAttr *NakedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NakedAttr::NakedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Naked, false, false)
  {
}

NakedAttr *NakedAttr::clone(ASTContext &C) const {
  auto *A = new (C) NakedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NakedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((naked";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::naked";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::naked";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(naked";
    OS << ")";
    break;
  }
}
}

const char *NakedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "naked";
  case 1:
    return "naked";
  case 2:
    return "naked";
  case 3:
    return "naked";
  }
}


// NoAliasAttr implementation

NoAliasAttr *NoAliasAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoAliasAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoAliasAttr *NoAliasAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoAliasAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoAliasAttr *NoAliasAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoAliasAttr *NoAliasAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoAliasAttr::NoAliasAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoAlias, false, false)
  {
}

NoAliasAttr *NoAliasAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoAliasAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoAliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(noalias";
    OS << ")";
    break;
  }
}
}

const char *NoAliasAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "noalias";
  }
}


// NoBuiltinAttr implementation

NoBuiltinAttr *NoBuiltinAttr::CreateImplicit(ASTContext &Ctx, StringRef *BuiltinNames, unsigned BuiltinNamesSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoBuiltinAttr(Ctx, CommonInfo, BuiltinNames, BuiltinNamesSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoBuiltinAttr *NoBuiltinAttr::Create(ASTContext &Ctx, StringRef *BuiltinNames, unsigned BuiltinNamesSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoBuiltinAttr(Ctx, CommonInfo, BuiltinNames, BuiltinNamesSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoBuiltinAttr *NoBuiltinAttr::CreateImplicit(ASTContext &Ctx, StringRef *BuiltinNames, unsigned BuiltinNamesSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BuiltinNames, BuiltinNamesSize, I);
}

NoBuiltinAttr *NoBuiltinAttr::Create(ASTContext &Ctx, StringRef *BuiltinNames, unsigned BuiltinNamesSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BuiltinNames, BuiltinNamesSize, I);
}

NoBuiltinAttr::NoBuiltinAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *BuiltinNames, unsigned BuiltinNamesSize
             )
  : Attr(Ctx, CommonInfo, attr::NoBuiltin, false)
              , builtinNames_Size(BuiltinNamesSize), builtinNames_(new (Ctx, 16) StringRef[builtinNames_Size])
  {
  for (size_t I = 0, E = builtinNames_Size; I != E;
       ++I) {
    StringRef Ref = BuiltinNames[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      builtinNames_[I] = StringRef(Mem, Ref.size());
    }
  }
}

NoBuiltinAttr::NoBuiltinAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::NoBuiltin, false)
              , builtinNames_Size(0), builtinNames_(nullptr)
  {
}



NoBuiltinAttr *NoBuiltinAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoBuiltinAttr(C, *this, builtinNames_, builtinNames_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoBuiltinAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_builtin";
    OS << "";
  for (const auto &Val : builtinNames()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::no_builtin";
    OS << "";
  for (const auto &Val : builtinNames()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::no_builtin";
    OS << "";
  for (const auto &Val : builtinNames()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *NoBuiltinAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_builtin";
  case 1:
    return "no_builtin";
  case 2:
    return "no_builtin";
  }
}


// NoCommonAttr implementation

NoCommonAttr *NoCommonAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoCommonAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoCommonAttr *NoCommonAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoCommonAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoCommonAttr *NoCommonAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoCommonAttr *NoCommonAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoCommonAttr::NoCommonAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoCommon, false, false)
  {
}

NoCommonAttr *NoCommonAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoCommonAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoCommonAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nocommon";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nocommon";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nocommon";
    OS << "]]";
    break;
  }
}
}

const char *NoCommonAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nocommon";
  case 1:
    return "nocommon";
  case 2:
    return "nocommon";
  }
}


// NoDebugAttr implementation

NoDebugAttr *NoDebugAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDebugAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDebugAttr *NoDebugAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDebugAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDebugAttr *NoDebugAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoDebugAttr *NoDebugAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoDebugAttr::NoDebugAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoDebug, false, false)
  {
}

NoDebugAttr *NoDebugAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoDebugAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoDebugAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nodebug";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nodebug";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nodebug";
    OS << "]]";
    break;
  }
}
}

const char *NoDebugAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nodebug";
  case 1:
    return "nodebug";
  case 2:
    return "nodebug";
  }
}


// NoDerefAttr implementation

NoDerefAttr *NoDerefAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDerefAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDerefAttr *NoDerefAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDerefAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDerefAttr *NoDerefAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoDerefAttr *NoDerefAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoDerefAttr::NoDerefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::NoDeref, false)
  {
}

NoDerefAttr *NoDerefAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoDerefAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoDerefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((noderef";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::noderef";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::noderef";
    OS << "]]";
    break;
  }
}
}

const char *NoDerefAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "noderef";
  case 1:
    return "noderef";
  case 2:
    return "noderef";
  }
}


// NoDestroyAttr implementation

NoDestroyAttr *NoDestroyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDestroyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDestroyAttr *NoDestroyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDestroyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDestroyAttr *NoDestroyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoDestroyAttr *NoDestroyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoDestroyAttr::NoDestroyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoDestroy, false, false)
  {
}

NoDestroyAttr *NoDestroyAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoDestroyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoDestroyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_destroy";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::no_destroy";
    OS << "]]";
    break;
  }
}
}

const char *NoDestroyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_destroy";
  case 1:
    return "no_destroy";
  }
}


// NoDuplicateAttr implementation

NoDuplicateAttr *NoDuplicateAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDuplicateAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDuplicateAttr *NoDuplicateAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoDuplicateAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoDuplicateAttr *NoDuplicateAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoDuplicateAttr *NoDuplicateAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoDuplicateAttr::NoDuplicateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoDuplicate, false, false)
  {
}

NoDuplicateAttr *NoDuplicateAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoDuplicateAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoDuplicateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((noduplicate";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::noduplicate";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::noduplicate";
    OS << "]]";
    break;
  }
}
}

const char *NoDuplicateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "noduplicate";
  case 1:
    return "noduplicate";
  case 2:
    return "noduplicate";
  }
}


// NoEscapeAttr implementation

NoEscapeAttr *NoEscapeAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoEscapeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoEscapeAttr *NoEscapeAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoEscapeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoEscapeAttr *NoEscapeAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoEscapeAttr *NoEscapeAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoEscapeAttr::NoEscapeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::NoEscape, false)
  {
}

NoEscapeAttr *NoEscapeAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoEscapeAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoEscapeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((noescape";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::noescape";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::noescape";
    OS << "]]";
    break;
  }
}
}

const char *NoEscapeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "noescape";
  case 1:
    return "noescape";
  case 2:
    return "noescape";
  }
}


// NoInlineAttr implementation

NoInlineAttr *NoInlineAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoInlineAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoInlineAttr *NoInlineAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoInlineAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoInlineAttr *NoInlineAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoInlineAttr *NoInlineAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoInlineAttr::NoInlineAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : DeclOrStmtAttr(Ctx, CommonInfo, attr::NoInline, false, false)
  {
}

NoInlineAttr *NoInlineAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoInlineAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoInlineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __noinline__";
    OS << "";
    break;
  }
  case 1 : {
    OS << " __attribute__((noinline";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::noinline";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::noinline";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::noinline";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::noinline";
    OS << "]]";
    break;
  }
  case 6 : {
    OS << " __declspec(noinline";
    OS << ")";
    break;
  }
}
}

const char *NoInlineAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__noinline__";
  case 1:
    return "noinline";
  case 2:
    return "noinline";
  case 3:
    return "noinline";
  case 4:
    return "noinline";
  case 5:
    return "noinline";
  case 6:
    return "noinline";
  }
}


// NoInstrumentFunctionAttr implementation

NoInstrumentFunctionAttr *NoInstrumentFunctionAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoInstrumentFunctionAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoInstrumentFunctionAttr *NoInstrumentFunctionAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoInstrumentFunctionAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoInstrumentFunctionAttr *NoInstrumentFunctionAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoInstrumentFunctionAttr *NoInstrumentFunctionAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoInstrumentFunctionAttr::NoInstrumentFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoInstrumentFunction, false, false)
  {
}

NoInstrumentFunctionAttr *NoInstrumentFunctionAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoInstrumentFunctionAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoInstrumentFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_instrument_function";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::no_instrument_function";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::no_instrument_function";
    OS << "]]";
    break;
  }
}
}

const char *NoInstrumentFunctionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_instrument_function";
  case 1:
    return "no_instrument_function";
  case 2:
    return "no_instrument_function";
  }
}


// NoMergeAttr implementation

NoMergeAttr *NoMergeAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoMergeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoMergeAttr *NoMergeAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoMergeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoMergeAttr *NoMergeAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoMergeAttr *NoMergeAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoMergeAttr::NoMergeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : DeclOrStmtAttr(Ctx, CommonInfo, attr::NoMerge, false, false)
  {
}

NoMergeAttr *NoMergeAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoMergeAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoMergeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nomerge";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::nomerge";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::nomerge";
    OS << "]]";
    break;
  }
}
}

const char *NoMergeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nomerge";
  case 1:
    return "nomerge";
  case 2:
    return "nomerge";
  }
}


// NoMicroMipsAttr implementation

NoMicroMipsAttr *NoMicroMipsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoMicroMipsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoMicroMipsAttr *NoMicroMipsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoMicroMipsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoMicroMipsAttr *NoMicroMipsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoMicroMipsAttr *NoMicroMipsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoMicroMipsAttr::NoMicroMipsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoMicroMips, false, false)
  {
}

NoMicroMipsAttr *NoMicroMipsAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoMicroMipsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoMicroMipsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nomicromips";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nomicromips";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nomicromips";
    OS << "]]";
    break;
  }
}
}

const char *NoMicroMipsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nomicromips";
  case 1:
    return "nomicromips";
  case 2:
    return "nomicromips";
  }
}


// NoMips16Attr implementation

NoMips16Attr *NoMips16Attr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoMips16Attr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoMips16Attr *NoMips16Attr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoMips16Attr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoMips16Attr *NoMips16Attr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoMips16Attr *NoMips16Attr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoMips16Attr::NoMips16Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoMips16, false, false)
  {
}

NoMips16Attr *NoMips16Attr::clone(ASTContext &C) const {
  auto *A = new (C) NoMips16Attr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoMips16Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nomips16";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nomips16";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nomips16";
    OS << "]]";
    break;
  }
}
}

const char *NoMips16Attr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nomips16";
  case 1:
    return "nomips16";
  case 2:
    return "nomips16";
  }
}


// NoProfileFunctionAttr implementation

NoProfileFunctionAttr *NoProfileFunctionAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoProfileFunctionAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoProfileFunctionAttr *NoProfileFunctionAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoProfileFunctionAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoProfileFunctionAttr *NoProfileFunctionAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoProfileFunctionAttr *NoProfileFunctionAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoProfileFunctionAttr::NoProfileFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoProfileFunction, false, false)
  {
}

NoProfileFunctionAttr *NoProfileFunctionAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoProfileFunctionAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoProfileFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_profile_instrument_function";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::no_profile_instrument_function";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::no_profile_instrument_function";
    OS << "]]";
    break;
  }
}
}

const char *NoProfileFunctionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_profile_instrument_function";
  case 1:
    return "no_profile_instrument_function";
  case 2:
    return "no_profile_instrument_function";
  }
}


// NoRandomizeLayoutAttr implementation

NoRandomizeLayoutAttr *NoRandomizeLayoutAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoRandomizeLayoutAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoRandomizeLayoutAttr *NoRandomizeLayoutAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoRandomizeLayoutAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoRandomizeLayoutAttr *NoRandomizeLayoutAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoRandomizeLayoutAttr *NoRandomizeLayoutAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoRandomizeLayoutAttr::NoRandomizeLayoutAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoRandomizeLayout, false, false)
  {
}

NoRandomizeLayoutAttr *NoRandomizeLayoutAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoRandomizeLayoutAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoRandomizeLayoutAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_randomize_layout";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::no_randomize_layout";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::no_randomize_layout";
    OS << "]]";
    break;
  }
}
}

const char *NoRandomizeLayoutAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_randomize_layout";
  case 1:
    return "no_randomize_layout";
  case 2:
    return "no_randomize_layout";
  }
}


// NoReturnAttr implementation

NoReturnAttr *NoReturnAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoReturnAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoReturnAttr *NoReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoReturnAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoReturnAttr *NoReturnAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoReturnAttr *NoReturnAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoReturnAttr::NoReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoReturn, false, false)
  {
}

NoReturnAttr *NoReturnAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoReturnAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((noreturn";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::noreturn";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::noreturn";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(noreturn";
    OS << ")";
    break;
  }
}
}

const char *NoReturnAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "noreturn";
  case 1:
    return "noreturn";
  case 2:
    return "noreturn";
  case 3:
    return "noreturn";
  }
}


// NoSanitizeAttr implementation

NoSanitizeAttr *NoSanitizeAttr::CreateImplicit(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoSanitizeAttr(Ctx, CommonInfo, Sanitizers, SanitizersSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoSanitizeAttr *NoSanitizeAttr::Create(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoSanitizeAttr(Ctx, CommonInfo, Sanitizers, SanitizersSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoSanitizeAttr *NoSanitizeAttr::CreateImplicit(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Sanitizers, SanitizersSize, I);
}

NoSanitizeAttr *NoSanitizeAttr::Create(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Sanitizers, SanitizersSize, I);
}

NoSanitizeAttr::NoSanitizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *Sanitizers, unsigned SanitizersSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSanitize, false, false)
              , sanitizers_Size(SanitizersSize), sanitizers_(new (Ctx, 16) StringRef[sanitizers_Size])
  {
  for (size_t I = 0, E = sanitizers_Size; I != E;
       ++I) {
    StringRef Ref = Sanitizers[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      sanitizers_[I] = StringRef(Mem, Ref.size());
    }
  }
}

NoSanitizeAttr::NoSanitizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSanitize, false, false)
              , sanitizers_Size(0), sanitizers_(nullptr)
  {
}



NoSanitizeAttr *NoSanitizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoSanitizeAttr(C, *this, sanitizers_, sanitizers_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoSanitizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_sanitize";
    OS << "";
  for (const auto &Val : sanitizers()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::no_sanitize";
    OS << "";
  for (const auto &Val : sanitizers()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::no_sanitize";
    OS << "";
  for (const auto &Val : sanitizers()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *NoSanitizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_sanitize";
  case 1:
    return "no_sanitize";
  case 2:
    return "no_sanitize";
  }
}


// NoSpeculativeLoadHardeningAttr implementation

NoSpeculativeLoadHardeningAttr *NoSpeculativeLoadHardeningAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoSpeculativeLoadHardeningAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoSpeculativeLoadHardeningAttr *NoSpeculativeLoadHardeningAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoSpeculativeLoadHardeningAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoSpeculativeLoadHardeningAttr *NoSpeculativeLoadHardeningAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoSpeculativeLoadHardeningAttr *NoSpeculativeLoadHardeningAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoSpeculativeLoadHardeningAttr::NoSpeculativeLoadHardeningAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSpeculativeLoadHardening, false, false)
  {
}

NoSpeculativeLoadHardeningAttr *NoSpeculativeLoadHardeningAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoSpeculativeLoadHardeningAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoSpeculativeLoadHardeningAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_speculative_load_hardening";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::no_speculative_load_hardening";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::no_speculative_load_hardening";
    OS << "]]";
    break;
  }
}
}

const char *NoSpeculativeLoadHardeningAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_speculative_load_hardening";
  case 1:
    return "no_speculative_load_hardening";
  case 2:
    return "no_speculative_load_hardening";
  }
}


// NoSplitStackAttr implementation

NoSplitStackAttr *NoSplitStackAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoSplitStackAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoSplitStackAttr *NoSplitStackAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoSplitStackAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoSplitStackAttr *NoSplitStackAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoSplitStackAttr *NoSplitStackAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoSplitStackAttr::NoSplitStackAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSplitStack, false, false)
  {
}

NoSplitStackAttr *NoSplitStackAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoSplitStackAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoSplitStackAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_split_stack";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::no_split_stack";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::no_split_stack";
    OS << "]]";
    break;
  }
}
}

const char *NoSplitStackAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_split_stack";
  case 1:
    return "no_split_stack";
  case 2:
    return "no_split_stack";
  }
}


// NoStackProtectorAttr implementation

NoStackProtectorAttr *NoStackProtectorAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoStackProtectorAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoStackProtectorAttr *NoStackProtectorAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoStackProtectorAttr(Ctx, CommonInfo);
  return A;
}

NoStackProtectorAttr *NoStackProtectorAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, NoStackProtectorAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

NoStackProtectorAttr *NoStackProtectorAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, NoStackProtectorAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

NoStackProtectorAttr::NoStackProtectorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoStackProtector, false, false)
  {
}

NoStackProtectorAttr::Spelling NoStackProtectorAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_no_stack_protector;
    case 1: return CXX11_clang_no_stack_protector;
    case 2: return C2x_clang_no_stack_protector;
    case 3: return Declspec_safebuffers;
  }
}
NoStackProtectorAttr *NoStackProtectorAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoStackProtectorAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoStackProtectorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_stack_protector";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::no_stack_protector";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::no_stack_protector";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(safebuffers";
    OS << ")";
    break;
  }
}
}

const char *NoStackProtectorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_stack_protector";
  case 1:
    return "no_stack_protector";
  case 2:
    return "no_stack_protector";
  case 3:
    return "safebuffers";
  }
}


// NoThreadSafetyAnalysisAttr implementation

NoThreadSafetyAnalysisAttr *NoThreadSafetyAnalysisAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoThreadSafetyAnalysisAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoThreadSafetyAnalysisAttr *NoThreadSafetyAnalysisAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoThreadSafetyAnalysisAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoThreadSafetyAnalysisAttr *NoThreadSafetyAnalysisAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoThreadSafetyAnalysisAttr *NoThreadSafetyAnalysisAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoThreadSafetyAnalysisAttr::NoThreadSafetyAnalysisAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoThreadSafetyAnalysis, false, false)
  {
}

NoThreadSafetyAnalysisAttr *NoThreadSafetyAnalysisAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoThreadSafetyAnalysisAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoThreadSafetyAnalysisAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((no_thread_safety_analysis";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::no_thread_safety_analysis";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::no_thread_safety_analysis";
    OS << "]]";
    break;
  }
}
}

const char *NoThreadSafetyAnalysisAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_thread_safety_analysis";
  case 1:
    return "no_thread_safety_analysis";
  case 2:
    return "no_thread_safety_analysis";
  }
}


// NoThrowAttr implementation

NoThrowAttr *NoThrowAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoThrowAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoThrowAttr *NoThrowAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoThrowAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoThrowAttr *NoThrowAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoThrowAttr *NoThrowAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoThrowAttr::NoThrowAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoThrow, false, false)
  {
}

NoThrowAttr *NoThrowAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoThrowAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoThrowAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nothrow";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nothrow";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nothrow";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(nothrow";
    OS << ")";
    break;
  }
}
}

const char *NoThrowAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nothrow";
  case 1:
    return "nothrow";
  case 2:
    return "nothrow";
  case 3:
    return "nothrow";
  }
}


// NoUniqueAddressAttr implementation

NoUniqueAddressAttr *NoUniqueAddressAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoUniqueAddressAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoUniqueAddressAttr *NoUniqueAddressAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoUniqueAddressAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoUniqueAddressAttr *NoUniqueAddressAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoUniqueAddressAttr *NoUniqueAddressAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoUniqueAddressAttr::NoUniqueAddressAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoUniqueAddress, false, false)
  {
}

NoUniqueAddressAttr *NoUniqueAddressAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoUniqueAddressAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoUniqueAddressAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[no_unique_address";
    OS << "]]";
    break;
  }
}
}

const char *NoUniqueAddressAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "no_unique_address";
  }
}


// NoUwtableAttr implementation

NoUwtableAttr *NoUwtableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoUwtableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoUwtableAttr *NoUwtableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NoUwtableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NoUwtableAttr *NoUwtableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NoUwtableAttr *NoUwtableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NoUwtableAttr::NoUwtableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoUwtable, false, false)
  {
}

NoUwtableAttr *NoUwtableAttr::clone(ASTContext &C) const {
  auto *A = new (C) NoUwtableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NoUwtableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nouwtable";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::nouwtable";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::nouwtable";
    OS << "]]";
    break;
  }
}
}

const char *NoUwtableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nouwtable";
  case 1:
    return "nouwtable";
  case 2:
    return "nouwtable";
  }
}


// NonNullAttr implementation

NonNullAttr *NonNullAttr::CreateImplicit(ASTContext &Ctx, ParamIdx *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NonNullAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NonNullAttr *NonNullAttr::Create(ASTContext &Ctx, ParamIdx *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NonNullAttr(Ctx, CommonInfo, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NonNullAttr *NonNullAttr::CreateImplicit(ASTContext &Ctx, ParamIdx *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

NonNullAttr *NonNullAttr::Create(ASTContext &Ctx, ParamIdx *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Args, ArgsSize, I);
}

NonNullAttr::NonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx *Args, unsigned ArgsSize
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::NonNull, false, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

NonNullAttr::NonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::NonNull, false, true)
              , args_Size(0), args_(nullptr)
  {
}



NonNullAttr *NonNullAttr::clone(ASTContext &C) const {
  auto *A = new (C) NonNullAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NonNullAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((nonnull";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::nonnull";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::nonnull";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *NonNullAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nonnull";
  case 1:
    return "nonnull";
  case 2:
    return "nonnull";
  }
}


// NotTailCalledAttr implementation

NotTailCalledAttr *NotTailCalledAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NotTailCalledAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NotTailCalledAttr *NotTailCalledAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) NotTailCalledAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

NotTailCalledAttr *NotTailCalledAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

NotTailCalledAttr *NotTailCalledAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

NotTailCalledAttr::NotTailCalledAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NotTailCalled, false, false)
  {
}

NotTailCalledAttr *NotTailCalledAttr::clone(ASTContext &C) const {
  auto *A = new (C) NotTailCalledAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void NotTailCalledAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((not_tail_called";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::not_tail_called";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::not_tail_called";
    OS << "]]";
    break;
  }
}
}

const char *NotTailCalledAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "not_tail_called";
  case 1:
    return "not_tail_called";
  case 2:
    return "not_tail_called";
  }
}


// OMPAllocateDeclAttr implementation

OMPAllocateDeclAttr *OMPAllocateDeclAttr::CreateImplicit(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, Expr * Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPAllocateDeclAttr(Ctx, CommonInfo, AllocatorType, Allocator, Alignment);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPAllocateDeclAttr *OMPAllocateDeclAttr::Create(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, Expr * Alignment, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPAllocateDeclAttr(Ctx, CommonInfo, AllocatorType, Allocator, Alignment);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPAllocateDeclAttr *OMPAllocateDeclAttr::CreateImplicit(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, Expr * Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, AllocatorType, Allocator, Alignment, I);
}

OMPAllocateDeclAttr *OMPAllocateDeclAttr::Create(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, Expr * Alignment, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, AllocatorType, Allocator, Alignment, I);
}

OMPAllocateDeclAttr::OMPAllocateDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , AllocatorTypeTy AllocatorType
              , Expr * Allocator
              , Expr * Alignment
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPAllocateDecl, false, false)
              , allocatorType(AllocatorType)
              , allocator(Allocator)
              , alignment(Alignment)
  {
}



bool OMPAllocateDeclAttr::ConvertStrToAllocatorTypeTy(StringRef Val, AllocatorTypeTy &Out) {
  Optional<AllocatorTypeTy> R = llvm::StringSwitch<Optional<AllocatorTypeTy>>(Val)
    .Case("omp_null_allocator", OMPAllocateDeclAttr::OMPNullMemAlloc)
    .Case("omp_default_mem_alloc", OMPAllocateDeclAttr::OMPDefaultMemAlloc)
    .Case("omp_large_cap_mem_alloc", OMPAllocateDeclAttr::OMPLargeCapMemAlloc)
    .Case("omp_const_mem_alloc", OMPAllocateDeclAttr::OMPConstMemAlloc)
    .Case("omp_high_bw_mem_alloc", OMPAllocateDeclAttr::OMPHighBWMemAlloc)
    .Case("omp_low_lat_mem_alloc", OMPAllocateDeclAttr::OMPLowLatMemAlloc)
    .Case("omp_cgroup_mem_alloc", OMPAllocateDeclAttr::OMPCGroupMemAlloc)
    .Case("omp_pteam_mem_alloc", OMPAllocateDeclAttr::OMPPTeamMemAlloc)
    .Case("omp_thread_mem_alloc", OMPAllocateDeclAttr::OMPThreadMemAlloc)
    .Case("", OMPAllocateDeclAttr::OMPUserDefinedMemAlloc)
    .Default(Optional<AllocatorTypeTy>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorTypeTy Val) {
  switch(Val) {
  case OMPAllocateDeclAttr::OMPNullMemAlloc: return "omp_null_allocator";
  case OMPAllocateDeclAttr::OMPDefaultMemAlloc: return "omp_default_mem_alloc";
  case OMPAllocateDeclAttr::OMPLargeCapMemAlloc: return "omp_large_cap_mem_alloc";
  case OMPAllocateDeclAttr::OMPConstMemAlloc: return "omp_const_mem_alloc";
  case OMPAllocateDeclAttr::OMPHighBWMemAlloc: return "omp_high_bw_mem_alloc";
  case OMPAllocateDeclAttr::OMPLowLatMemAlloc: return "omp_low_lat_mem_alloc";
  case OMPAllocateDeclAttr::OMPCGroupMemAlloc: return "omp_cgroup_mem_alloc";
  case OMPAllocateDeclAttr::OMPPTeamMemAlloc: return "omp_pteam_mem_alloc";
  case OMPAllocateDeclAttr::OMPThreadMemAlloc: return "omp_thread_mem_alloc";
  case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc: return "";
  }
  llvm_unreachable("No enumerator with that value");
}




OMPAllocateDeclAttr *OMPAllocateDeclAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPAllocateDeclAttr(C, *this, allocatorType, allocator, alignment);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPAllocateDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *OMPAllocateDeclAttr::getSpelling() const {
  return "(No spelling)";
}


// OMPCaptureKindAttr implementation

OMPCaptureKindAttr *OMPCaptureKindAttr::CreateImplicit(ASTContext &Ctx, unsigned CaptureKindVal, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPCaptureKindAttr(Ctx, CommonInfo, CaptureKindVal);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPCaptureKindAttr *OMPCaptureKindAttr::Create(ASTContext &Ctx, unsigned CaptureKindVal, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPCaptureKindAttr(Ctx, CommonInfo, CaptureKindVal);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPCaptureKindAttr *OMPCaptureKindAttr::CreateImplicit(ASTContext &Ctx, unsigned CaptureKindVal, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, CaptureKindVal, I);
}

OMPCaptureKindAttr *OMPCaptureKindAttr::Create(ASTContext &Ctx, unsigned CaptureKindVal, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, CaptureKindVal, I);
}

OMPCaptureKindAttr::OMPCaptureKindAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned CaptureKindVal
             )
  : Attr(Ctx, CommonInfo, attr::OMPCaptureKind, false)
              , captureKindVal(CaptureKindVal)
  {
}



OMPCaptureKindAttr *OMPCaptureKindAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPCaptureKindAttr(C, *this, captureKindVal);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPCaptureKindAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *OMPCaptureKindAttr::getSpelling() const {
  return "(No spelling)";
}


// OMPCaptureNoInitAttr implementation

OMPCaptureNoInitAttr *OMPCaptureNoInitAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPCaptureNoInitAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPCaptureNoInitAttr *OMPCaptureNoInitAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPCaptureNoInitAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPCaptureNoInitAttr *OMPCaptureNoInitAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OMPCaptureNoInitAttr *OMPCaptureNoInitAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OMPCaptureNoInitAttr::OMPCaptureNoInitAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPCaptureNoInit, false, false)
  {
}

OMPCaptureNoInitAttr *OMPCaptureNoInitAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPCaptureNoInitAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPCaptureNoInitAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *OMPCaptureNoInitAttr::getSpelling() const {
  return "(No spelling)";
}


// OMPDeclareSimdDeclAttr implementation

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::CreateImplicit(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareSimdDeclAttr(Ctx, CommonInfo, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::Create(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareSimdDeclAttr(Ctx, CommonInfo, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::CreateImplicit(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize, I);
}

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::Create(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize, I);
}

OMPDeclareSimdDeclAttr::OMPDeclareSimdDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , BranchStateTy BranchState
              , Expr * Simdlen
              , Expr * *Uniforms, unsigned UniformsSize
              , Expr * *Aligneds, unsigned AlignedsSize
              , Expr * *Alignments, unsigned AlignmentsSize
              , Expr * *Linears, unsigned LinearsSize
              , unsigned *Modifiers, unsigned ModifiersSize
              , Expr * *Steps, unsigned StepsSize
             )
  : Attr(Ctx, CommonInfo, attr::OMPDeclareSimdDecl, false)
              , branchState(BranchState)
              , simdlen(Simdlen)
              , uniforms_Size(UniformsSize), uniforms_(new (Ctx, 16) Expr *[uniforms_Size])
              , aligneds_Size(AlignedsSize), aligneds_(new (Ctx, 16) Expr *[aligneds_Size])
              , alignments_Size(AlignmentsSize), alignments_(new (Ctx, 16) Expr *[alignments_Size])
              , linears_Size(LinearsSize), linears_(new (Ctx, 16) Expr *[linears_Size])
              , modifiers_Size(ModifiersSize), modifiers_(new (Ctx, 16) unsigned[modifiers_Size])
              , steps_Size(StepsSize), steps_(new (Ctx, 16) Expr *[steps_Size])
  {
  std::copy(Uniforms, Uniforms + uniforms_Size, uniforms_);
  std::copy(Aligneds, Aligneds + aligneds_Size, aligneds_);
  std::copy(Alignments, Alignments + alignments_Size, alignments_);
  std::copy(Linears, Linears + linears_Size, linears_);
  std::copy(Modifiers, Modifiers + modifiers_Size, modifiers_);
  std::copy(Steps, Steps + steps_Size, steps_);
}

OMPDeclareSimdDeclAttr::OMPDeclareSimdDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , BranchStateTy BranchState
              , Expr * Simdlen
             )
  : Attr(Ctx, CommonInfo, attr::OMPDeclareSimdDecl, false)
              , branchState(BranchState)
              , simdlen(Simdlen)
              , uniforms_Size(0), uniforms_(nullptr)
              , aligneds_Size(0), aligneds_(nullptr)
              , alignments_Size(0), alignments_(nullptr)
              , linears_Size(0), linears_(nullptr)
              , modifiers_Size(0), modifiers_(nullptr)
              , steps_Size(0), steps_(nullptr)
  {
}



bool OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(StringRef Val, BranchStateTy &Out) {
  Optional<BranchStateTy> R = llvm::StringSwitch<Optional<BranchStateTy>>(Val)
    .Case("", OMPDeclareSimdDeclAttr::BS_Undefined)
    .Case("inbranch", OMPDeclareSimdDeclAttr::BS_Inbranch)
    .Case("notinbranch", OMPDeclareSimdDeclAttr::BS_Notinbranch)
    .Default(Optional<BranchStateTy>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BranchStateTy Val) {
  switch(Val) {
  case OMPDeclareSimdDeclAttr::BS_Undefined: return "";
  case OMPDeclareSimdDeclAttr::BS_Inbranch: return "inbranch";
  case OMPDeclareSimdDeclAttr::BS_Notinbranch: return "notinbranch";
  }
  llvm_unreachable("No enumerator with that value");
}














OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPDeclareSimdDeclAttr(C, *this, branchState, simdlen, uniforms_, uniforms_Size, aligneds_, aligneds_Size, alignments_, alignments_Size, linears_, linears_Size, modifiers_, modifiers_Size, steps_, steps_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPDeclareSimdDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma omp declare simd";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

const char *OMPDeclareSimdDeclAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "declare simd";
  }
}


// OMPDeclareTargetDeclAttr implementation

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::CreateImplicit(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, Expr * IndirectExpr, bool Indirect, unsigned Level, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareTargetDeclAttr(Ctx, CommonInfo, MapType, DevType, IndirectExpr, Indirect, Level);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::Create(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, Expr * IndirectExpr, bool Indirect, unsigned Level, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareTargetDeclAttr(Ctx, CommonInfo, MapType, DevType, IndirectExpr, Indirect, Level);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::CreateImplicit(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, Expr * IndirectExpr, bool Indirect, unsigned Level, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, MapType, DevType, IndirectExpr, Indirect, Level, I);
}

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::Create(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, Expr * IndirectExpr, bool Indirect, unsigned Level, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, MapType, DevType, IndirectExpr, Indirect, Level, I);
}

OMPDeclareTargetDeclAttr::OMPDeclareTargetDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , MapTypeTy MapType
              , DevTypeTy DevType
              , Expr * IndirectExpr
              , bool Indirect
              , unsigned Level
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareTargetDecl, false, false)
              , mapType(MapType)
              , devType(DevType)
              , indirectExpr(IndirectExpr)
              , indirect(Indirect)
              , level(Level)
  {
}



bool OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(StringRef Val, MapTypeTy &Out) {
  Optional<MapTypeTy> R = llvm::StringSwitch<Optional<MapTypeTy>>(Val)
    .Case("to", OMPDeclareTargetDeclAttr::MT_To)
    .Case("link", OMPDeclareTargetDeclAttr::MT_Link)
    .Default(Optional<MapTypeTy>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPDeclareTargetDeclAttr::ConvertMapTypeTyToStr(MapTypeTy Val) {
  switch(Val) {
  case OMPDeclareTargetDeclAttr::MT_To: return "to";
  case OMPDeclareTargetDeclAttr::MT_Link: return "link";
  }
  llvm_unreachable("No enumerator with that value");
}


bool OMPDeclareTargetDeclAttr::ConvertStrToDevTypeTy(StringRef Val, DevTypeTy &Out) {
  Optional<DevTypeTy> R = llvm::StringSwitch<Optional<DevTypeTy>>(Val)
    .Case("host", OMPDeclareTargetDeclAttr::DT_Host)
    .Case("nohost", OMPDeclareTargetDeclAttr::DT_NoHost)
    .Case("any", OMPDeclareTargetDeclAttr::DT_Any)
    .Default(Optional<DevTypeTy>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DevTypeTy Val) {
  switch(Val) {
  case OMPDeclareTargetDeclAttr::DT_Host: return "host";
  case OMPDeclareTargetDeclAttr::DT_NoHost: return "nohost";
  case OMPDeclareTargetDeclAttr::DT_Any: return "any";
  }
  llvm_unreachable("No enumerator with that value");
}






OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPDeclareTargetDeclAttr(C, *this, mapType, devType, indirectExpr, indirect, level);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPDeclareTargetDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma omp declare target";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

const char *OMPDeclareTargetDeclAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "declare target";
  }
}


// OMPDeclareVariantAttr implementation

OMPDeclareVariantAttr *OMPDeclareVariantAttr::CreateImplicit(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, OMPInteropInfo *AppendArgs, unsigned AppendArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareVariantAttr(Ctx, CommonInfo, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareVariantAttr *OMPDeclareVariantAttr::Create(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, OMPInteropInfo *AppendArgs, unsigned AppendArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareVariantAttr(Ctx, CommonInfo, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareVariantAttr *OMPDeclareVariantAttr::CreateImplicit(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, OMPInteropInfo *AppendArgs, unsigned AppendArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize, I);
}

OMPDeclareVariantAttr *OMPDeclareVariantAttr::Create(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, OMPInteropInfo *AppendArgs, unsigned AppendArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize, I);
}

OMPDeclareVariantAttr::OMPDeclareVariantAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * VariantFuncRef
              , OMPTraitInfo * TraitInfos
              , Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize
              , Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize
              , OMPInteropInfo *AppendArgs, unsigned AppendArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareVariant, false, true)
              , variantFuncRef(VariantFuncRef)
              , traitInfos(TraitInfos)
              , adjustArgsNothing_Size(AdjustArgsNothingSize), adjustArgsNothing_(new (Ctx, 16) Expr *[adjustArgsNothing_Size])
              , adjustArgsNeedDevicePtr_Size(AdjustArgsNeedDevicePtrSize), adjustArgsNeedDevicePtr_(new (Ctx, 16) Expr *[adjustArgsNeedDevicePtr_Size])
              , appendArgs_Size(AppendArgsSize), appendArgs_(new (Ctx, 16) OMPInteropInfo[appendArgs_Size])
  {
  std::copy(AdjustArgsNothing, AdjustArgsNothing + adjustArgsNothing_Size, adjustArgsNothing_);
  std::copy(AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtr + adjustArgsNeedDevicePtr_Size, adjustArgsNeedDevicePtr_);
  std::copy(AppendArgs, AppendArgs + appendArgs_Size, appendArgs_);
}

OMPDeclareVariantAttr::OMPDeclareVariantAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * VariantFuncRef
              , OMPTraitInfo * TraitInfos
              , OMPInteropInfo *AppendArgs, unsigned AppendArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareVariant, false, true)
              , variantFuncRef(VariantFuncRef)
              , traitInfos(TraitInfos)
              , adjustArgsNothing_Size(0), adjustArgsNothing_(nullptr)
              , adjustArgsNeedDevicePtr_Size(0), adjustArgsNeedDevicePtr_(nullptr)
              , appendArgs_Size(AppendArgsSize), appendArgs_(new (Ctx, 16) OMPInteropInfo[appendArgs_Size])
  {
  std::copy(AppendArgs, AppendArgs + appendArgs_Size, appendArgs_);
}











OMPDeclareVariantAttr *OMPDeclareVariantAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPDeclareVariantAttr(C, *this, variantFuncRef, traitInfos, adjustArgsNothing_, adjustArgsNothing_Size, adjustArgsNeedDevicePtr_, adjustArgsNeedDevicePtr_Size, appendArgs_, appendArgs_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPDeclareVariantAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma omp declare variant";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

const char *OMPDeclareVariantAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "declare variant";
  }
}


// OMPReferencedVarAttr implementation

OMPReferencedVarAttr *OMPReferencedVarAttr::CreateImplicit(ASTContext &Ctx, Expr * Ref, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPReferencedVarAttr(Ctx, CommonInfo, Ref);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPReferencedVarAttr *OMPReferencedVarAttr::Create(ASTContext &Ctx, Expr * Ref, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPReferencedVarAttr(Ctx, CommonInfo, Ref);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPReferencedVarAttr *OMPReferencedVarAttr::CreateImplicit(ASTContext &Ctx, Expr * Ref, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Ref, I);
}

OMPReferencedVarAttr *OMPReferencedVarAttr::Create(ASTContext &Ctx, Expr * Ref, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Ref, I);
}

OMPReferencedVarAttr::OMPReferencedVarAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Ref
             )
  : Attr(Ctx, CommonInfo, attr::OMPReferencedVar, false)
              , ref(Ref)
  {
}



OMPReferencedVarAttr *OMPReferencedVarAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPReferencedVarAttr(C, *this, ref);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPReferencedVarAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *OMPReferencedVarAttr::getSpelling() const {
  return "(No spelling)";
}


// OMPThreadPrivateDeclAttr implementation

OMPThreadPrivateDeclAttr *OMPThreadPrivateDeclAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPThreadPrivateDeclAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPThreadPrivateDeclAttr *OMPThreadPrivateDeclAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPThreadPrivateDeclAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPThreadPrivateDeclAttr *OMPThreadPrivateDeclAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OMPThreadPrivateDeclAttr *OMPThreadPrivateDeclAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OMPThreadPrivateDeclAttr::OMPThreadPrivateDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPThreadPrivateDecl, false, false)
  {
}

OMPThreadPrivateDeclAttr *OMPThreadPrivateDeclAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPThreadPrivateDeclAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPThreadPrivateDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *OMPThreadPrivateDeclAttr::getSpelling() const {
  return "(No spelling)";
}


// OSConsumedAttr implementation

OSConsumedAttr *OSConsumedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSConsumedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSConsumedAttr *OSConsumedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSConsumedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSConsumedAttr *OSConsumedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OSConsumedAttr *OSConsumedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OSConsumedAttr::OSConsumedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::OSConsumed, false, false)
  {
}

OSConsumedAttr *OSConsumedAttr::clone(ASTContext &C) const {
  auto *A = new (C) OSConsumedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OSConsumedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((os_consumed";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::os_consumed";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::os_consumed";
    OS << "]]";
    break;
  }
}
}

const char *OSConsumedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "os_consumed";
  case 1:
    return "os_consumed";
  case 2:
    return "os_consumed";
  }
}


// OSConsumesThisAttr implementation

OSConsumesThisAttr *OSConsumesThisAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSConsumesThisAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSConsumesThisAttr *OSConsumesThisAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSConsumesThisAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSConsumesThisAttr *OSConsumesThisAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OSConsumesThisAttr *OSConsumesThisAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OSConsumesThisAttr::OSConsumesThisAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSConsumesThis, false, false)
  {
}

OSConsumesThisAttr *OSConsumesThisAttr::clone(ASTContext &C) const {
  auto *A = new (C) OSConsumesThisAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OSConsumesThisAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((os_consumes_this";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::os_consumes_this";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::os_consumes_this";
    OS << "]]";
    break;
  }
}
}

const char *OSConsumesThisAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "os_consumes_this";
  case 1:
    return "os_consumes_this";
  case 2:
    return "os_consumes_this";
  }
}


// OSReturnsNotRetainedAttr implementation

OSReturnsNotRetainedAttr *OSReturnsNotRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsNotRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsNotRetainedAttr *OSReturnsNotRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsNotRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsNotRetainedAttr *OSReturnsNotRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OSReturnsNotRetainedAttr *OSReturnsNotRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OSReturnsNotRetainedAttr::OSReturnsNotRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsNotRetained, false, false)
  {
}

OSReturnsNotRetainedAttr *OSReturnsNotRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) OSReturnsNotRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OSReturnsNotRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((os_returns_not_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::os_returns_not_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::os_returns_not_retained";
    OS << "]]";
    break;
  }
}
}

const char *OSReturnsNotRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "os_returns_not_retained";
  case 1:
    return "os_returns_not_retained";
  case 2:
    return "os_returns_not_retained";
  }
}


// OSReturnsRetainedAttr implementation

OSReturnsRetainedAttr *OSReturnsRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsRetainedAttr *OSReturnsRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsRetainedAttr *OSReturnsRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OSReturnsRetainedAttr *OSReturnsRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OSReturnsRetainedAttr::OSReturnsRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsRetained, false, false)
  {
}

OSReturnsRetainedAttr *OSReturnsRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) OSReturnsRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OSReturnsRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((os_returns_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::os_returns_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::os_returns_retained";
    OS << "]]";
    break;
  }
}
}

const char *OSReturnsRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "os_returns_retained";
  case 1:
    return "os_returns_retained";
  case 2:
    return "os_returns_retained";
  }
}


// OSReturnsRetainedOnNonZeroAttr implementation

OSReturnsRetainedOnNonZeroAttr *OSReturnsRetainedOnNonZeroAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsRetainedOnNonZeroAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsRetainedOnNonZeroAttr *OSReturnsRetainedOnNonZeroAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsRetainedOnNonZeroAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsRetainedOnNonZeroAttr *OSReturnsRetainedOnNonZeroAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OSReturnsRetainedOnNonZeroAttr *OSReturnsRetainedOnNonZeroAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OSReturnsRetainedOnNonZeroAttr::OSReturnsRetainedOnNonZeroAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsRetainedOnNonZero, false, false)
  {
}

OSReturnsRetainedOnNonZeroAttr *OSReturnsRetainedOnNonZeroAttr::clone(ASTContext &C) const {
  auto *A = new (C) OSReturnsRetainedOnNonZeroAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OSReturnsRetainedOnNonZeroAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((os_returns_retained_on_non_zero";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::os_returns_retained_on_non_zero";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::os_returns_retained_on_non_zero";
    OS << "]]";
    break;
  }
}
}

const char *OSReturnsRetainedOnNonZeroAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "os_returns_retained_on_non_zero";
  case 1:
    return "os_returns_retained_on_non_zero";
  case 2:
    return "os_returns_retained_on_non_zero";
  }
}


// OSReturnsRetainedOnZeroAttr implementation

OSReturnsRetainedOnZeroAttr *OSReturnsRetainedOnZeroAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsRetainedOnZeroAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsRetainedOnZeroAttr *OSReturnsRetainedOnZeroAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OSReturnsRetainedOnZeroAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OSReturnsRetainedOnZeroAttr *OSReturnsRetainedOnZeroAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OSReturnsRetainedOnZeroAttr *OSReturnsRetainedOnZeroAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OSReturnsRetainedOnZeroAttr::OSReturnsRetainedOnZeroAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsRetainedOnZero, false, false)
  {
}

OSReturnsRetainedOnZeroAttr *OSReturnsRetainedOnZeroAttr::clone(ASTContext &C) const {
  auto *A = new (C) OSReturnsRetainedOnZeroAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OSReturnsRetainedOnZeroAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((os_returns_retained_on_zero";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::os_returns_retained_on_zero";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::os_returns_retained_on_zero";
    OS << "]]";
    break;
  }
}
}

const char *OSReturnsRetainedOnZeroAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "os_returns_retained_on_zero";
  case 1:
    return "os_returns_retained_on_zero";
  case 2:
    return "os_returns_retained_on_zero";
  }
}


// ObjCBoxableAttr implementation

ObjCBoxableAttr *ObjCBoxableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBoxableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBoxableAttr *ObjCBoxableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBoxableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBoxableAttr *ObjCBoxableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCBoxableAttr *ObjCBoxableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCBoxableAttr::ObjCBoxableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCBoxable, false)
  {
}

ObjCBoxableAttr *ObjCBoxableAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCBoxableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCBoxableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_boxable";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_boxable";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_boxable";
    OS << "]]";
    break;
  }
}
}

const char *ObjCBoxableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_boxable";
  case 1:
    return "objc_boxable";
  case 2:
    return "objc_boxable";
  }
}


// ObjCBridgeAttr implementation

ObjCBridgeAttr *ObjCBridgeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBridgeAttr(Ctx, CommonInfo, BridgedType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBridgeAttr *ObjCBridgeAttr::Create(ASTContext &Ctx, IdentifierInfo * BridgedType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBridgeAttr(Ctx, CommonInfo, BridgedType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBridgeAttr *ObjCBridgeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BridgedType, I);
}

ObjCBridgeAttr *ObjCBridgeAttr::Create(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BridgedType, I);
}

ObjCBridgeAttr::ObjCBridgeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * BridgedType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCBridge, false, false)
              , bridgedType(BridgedType)
  {
}



ObjCBridgeAttr *ObjCBridgeAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCBridgeAttr(C, *this, bridgedType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCBridgeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_bridge";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBridgedType() ? getBridgedType()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_bridge";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBridgedType() ? getBridgedType()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_bridge";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBridgedType() ? getBridgedType()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCBridgeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_bridge";
  case 1:
    return "objc_bridge";
  case 2:
    return "objc_bridge";
  }
}


// ObjCBridgeMutableAttr implementation

ObjCBridgeMutableAttr *ObjCBridgeMutableAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBridgeMutableAttr(Ctx, CommonInfo, BridgedType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBridgeMutableAttr *ObjCBridgeMutableAttr::Create(ASTContext &Ctx, IdentifierInfo * BridgedType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBridgeMutableAttr(Ctx, CommonInfo, BridgedType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBridgeMutableAttr *ObjCBridgeMutableAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BridgedType, I);
}

ObjCBridgeMutableAttr *ObjCBridgeMutableAttr::Create(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BridgedType, I);
}

ObjCBridgeMutableAttr::ObjCBridgeMutableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * BridgedType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCBridgeMutable, false, false)
              , bridgedType(BridgedType)
  {
}



ObjCBridgeMutableAttr *ObjCBridgeMutableAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCBridgeMutableAttr(C, *this, bridgedType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCBridgeMutableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_bridge_mutable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBridgedType() ? getBridgedType()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_bridge_mutable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBridgedType() ? getBridgedType()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_bridge_mutable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getBridgedType() ? getBridgedType()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCBridgeMutableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_bridge_mutable";
  case 1:
    return "objc_bridge_mutable";
  case 2:
    return "objc_bridge_mutable";
  }
}


// ObjCBridgeRelatedAttr implementation

ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBridgeRelatedAttr(Ctx, CommonInfo, RelatedClass, ClassMethod, InstanceMethod);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::Create(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCBridgeRelatedAttr(Ctx, CommonInfo, RelatedClass, ClassMethod, InstanceMethod);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, RelatedClass, ClassMethod, InstanceMethod, I);
}

ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::Create(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, RelatedClass, ClassMethod, InstanceMethod, I);
}

ObjCBridgeRelatedAttr::ObjCBridgeRelatedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * RelatedClass
              , IdentifierInfo * ClassMethod
              , IdentifierInfo * InstanceMethod
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCBridgeRelated, false, false)
              , relatedClass(RelatedClass)
              , classMethod(ClassMethod)
              , instanceMethod(InstanceMethod)
  {
}







ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCBridgeRelatedAttr(C, *this, relatedClass, classMethod, instanceMethod);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCBridgeRelatedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_bridge_related";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getRelatedClass() ? getRelatedClass()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getClassMethod() ? getClassMethod()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getInstanceMethod() ? getInstanceMethod()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_bridge_related";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getRelatedClass() ? getRelatedClass()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getClassMethod() ? getClassMethod()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getInstanceMethod() ? getInstanceMethod()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_bridge_related";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getRelatedClass() ? getRelatedClass()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getClassMethod() ? getClassMethod()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getInstanceMethod() ? getInstanceMethod()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCBridgeRelatedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_bridge_related";
  case 1:
    return "objc_bridge_related";
  case 2:
    return "objc_bridge_related";
  }
}


// ObjCClassStubAttr implementation

ObjCClassStubAttr *ObjCClassStubAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCClassStubAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCClassStubAttr *ObjCClassStubAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCClassStubAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCClassStubAttr *ObjCClassStubAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCClassStubAttr *ObjCClassStubAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCClassStubAttr::ObjCClassStubAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCClassStub, false)
  {
}

ObjCClassStubAttr *ObjCClassStubAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCClassStubAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCClassStubAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_class_stub";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_class_stub";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_class_stub";
    OS << "]]";
    break;
  }
}
}

const char *ObjCClassStubAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_class_stub";
  case 1:
    return "objc_class_stub";
  case 2:
    return "objc_class_stub";
  }
}


// ObjCDesignatedInitializerAttr implementation

ObjCDesignatedInitializerAttr *ObjCDesignatedInitializerAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCDesignatedInitializerAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCDesignatedInitializerAttr *ObjCDesignatedInitializerAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCDesignatedInitializerAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCDesignatedInitializerAttr *ObjCDesignatedInitializerAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCDesignatedInitializerAttr *ObjCDesignatedInitializerAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCDesignatedInitializerAttr::ObjCDesignatedInitializerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCDesignatedInitializer, false)
  {
}

ObjCDesignatedInitializerAttr *ObjCDesignatedInitializerAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCDesignatedInitializerAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCDesignatedInitializerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_designated_initializer";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_designated_initializer";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_designated_initializer";
    OS << "]]";
    break;
  }
}
}

const char *ObjCDesignatedInitializerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_designated_initializer";
  case 1:
    return "objc_designated_initializer";
  case 2:
    return "objc_designated_initializer";
  }
}


// ObjCDirectAttr implementation

ObjCDirectAttr *ObjCDirectAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCDirectAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCDirectAttr *ObjCDirectAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCDirectAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCDirectAttr *ObjCDirectAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCDirectAttr *ObjCDirectAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCDirectAttr::ObjCDirectAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCDirect, false)
  {
}

ObjCDirectAttr *ObjCDirectAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCDirectAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCDirectAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_direct";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_direct";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_direct";
    OS << "]]";
    break;
  }
}
}

const char *ObjCDirectAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_direct";
  case 1:
    return "objc_direct";
  case 2:
    return "objc_direct";
  }
}


// ObjCDirectMembersAttr implementation

ObjCDirectMembersAttr *ObjCDirectMembersAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCDirectMembersAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCDirectMembersAttr *ObjCDirectMembersAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCDirectMembersAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCDirectMembersAttr *ObjCDirectMembersAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCDirectMembersAttr *ObjCDirectMembersAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCDirectMembersAttr::ObjCDirectMembersAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCDirectMembers, false)
  {
}

ObjCDirectMembersAttr *ObjCDirectMembersAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCDirectMembersAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCDirectMembersAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_direct_members";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_direct_members";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_direct_members";
    OS << "]]";
    break;
  }
}
}

const char *ObjCDirectMembersAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_direct_members";
  case 1:
    return "objc_direct_members";
  case 2:
    return "objc_direct_members";
  }
}


// ObjCExceptionAttr implementation

ObjCExceptionAttr *ObjCExceptionAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCExceptionAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCExceptionAttr *ObjCExceptionAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCExceptionAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCExceptionAttr *ObjCExceptionAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCExceptionAttr *ObjCExceptionAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCExceptionAttr::ObjCExceptionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCException, false, false)
  {
}

ObjCExceptionAttr *ObjCExceptionAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCExceptionAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCExceptionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_exception";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_exception";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_exception";
    OS << "]]";
    break;
  }
}
}

const char *ObjCExceptionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_exception";
  case 1:
    return "objc_exception";
  case 2:
    return "objc_exception";
  }
}


// ObjCExplicitProtocolImplAttr implementation

ObjCExplicitProtocolImplAttr *ObjCExplicitProtocolImplAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCExplicitProtocolImplAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCExplicitProtocolImplAttr *ObjCExplicitProtocolImplAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCExplicitProtocolImplAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCExplicitProtocolImplAttr *ObjCExplicitProtocolImplAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCExplicitProtocolImplAttr *ObjCExplicitProtocolImplAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCExplicitProtocolImplAttr::ObjCExplicitProtocolImplAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCExplicitProtocolImpl, false, false)
  {
}

ObjCExplicitProtocolImplAttr *ObjCExplicitProtocolImplAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCExplicitProtocolImplAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCExplicitProtocolImplAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_protocol_requires_explicit_implementation";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_protocol_requires_explicit_implementation";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_protocol_requires_explicit_implementation";
    OS << "]]";
    break;
  }
}
}

const char *ObjCExplicitProtocolImplAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_protocol_requires_explicit_implementation";
  case 1:
    return "objc_protocol_requires_explicit_implementation";
  case 2:
    return "objc_protocol_requires_explicit_implementation";
  }
}


// ObjCExternallyRetainedAttr implementation

ObjCExternallyRetainedAttr *ObjCExternallyRetainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCExternallyRetainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCExternallyRetainedAttr *ObjCExternallyRetainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCExternallyRetainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCExternallyRetainedAttr *ObjCExternallyRetainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCExternallyRetainedAttr *ObjCExternallyRetainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCExternallyRetainedAttr::ObjCExternallyRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCExternallyRetained, false, false)
  {
}

ObjCExternallyRetainedAttr *ObjCExternallyRetainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCExternallyRetainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCExternallyRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_externally_retained";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_externally_retained";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_externally_retained";
    OS << "]]";
    break;
  }
}
}

const char *ObjCExternallyRetainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_externally_retained";
  case 1:
    return "objc_externally_retained";
  case 2:
    return "objc_externally_retained";
  }
}


// ObjCGCAttr implementation

ObjCGCAttr *ObjCGCAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Kind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCGCAttr(Ctx, CommonInfo, Kind);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCGCAttr *ObjCGCAttr::Create(ASTContext &Ctx, IdentifierInfo * Kind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCGCAttr(Ctx, CommonInfo, Kind);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCGCAttr *ObjCGCAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Kind, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Kind, I);
}

ObjCGCAttr *ObjCGCAttr::Create(ASTContext &Ctx, IdentifierInfo * Kind, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Kind, I);
}

ObjCGCAttr::ObjCGCAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Kind
             )
  : TypeAttr(Ctx, CommonInfo, attr::ObjCGC, false)
              , kind(Kind)
  {
}



ObjCGCAttr *ObjCGCAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCGCAttr(C, *this, kind);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCGCAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_gc";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getKind() ? getKind()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_gc";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getKind() ? getKind()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_gc";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getKind() ? getKind()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCGCAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_gc";
  case 1:
    return "objc_gc";
  case 2:
    return "objc_gc";
  }
}


// ObjCIndependentClassAttr implementation

ObjCIndependentClassAttr *ObjCIndependentClassAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCIndependentClassAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCIndependentClassAttr *ObjCIndependentClassAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCIndependentClassAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCIndependentClassAttr *ObjCIndependentClassAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCIndependentClassAttr *ObjCIndependentClassAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCIndependentClassAttr::ObjCIndependentClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCIndependentClass, false, false)
  {
}

ObjCIndependentClassAttr *ObjCIndependentClassAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCIndependentClassAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCIndependentClassAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_independent_class";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_independent_class";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_independent_class";
    OS << "]]";
    break;
  }
}
}

const char *ObjCIndependentClassAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_independent_class";
  case 1:
    return "objc_independent_class";
  case 2:
    return "objc_independent_class";
  }
}


// ObjCInertUnsafeUnretainedAttr implementation

ObjCInertUnsafeUnretainedAttr *ObjCInertUnsafeUnretainedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCInertUnsafeUnretainedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCInertUnsafeUnretainedAttr *ObjCInertUnsafeUnretainedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCInertUnsafeUnretainedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCInertUnsafeUnretainedAttr *ObjCInertUnsafeUnretainedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCInertUnsafeUnretainedAttr *ObjCInertUnsafeUnretainedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCInertUnsafeUnretainedAttr::ObjCInertUnsafeUnretainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::ObjCInertUnsafeUnretained, false)
  {
}

ObjCInertUnsafeUnretainedAttr *ObjCInertUnsafeUnretainedAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCInertUnsafeUnretainedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCInertUnsafeUnretainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __unsafe_unretained";
    OS << "";
    break;
  }
}
}

const char *ObjCInertUnsafeUnretainedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__unsafe_unretained";
  }
}


// ObjCKindOfAttr implementation

ObjCKindOfAttr *ObjCKindOfAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCKindOfAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCKindOfAttr *ObjCKindOfAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCKindOfAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCKindOfAttr *ObjCKindOfAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCKindOfAttr *ObjCKindOfAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCKindOfAttr::ObjCKindOfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::ObjCKindOf, false)
  {
}

ObjCKindOfAttr *ObjCKindOfAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCKindOfAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCKindOfAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __kindof";
    OS << "";
    break;
  }
}
}

const char *ObjCKindOfAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__kindof";
  }
}


// ObjCMethodFamilyAttr implementation

ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::CreateImplicit(ASTContext &Ctx, FamilyKind Family, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCMethodFamilyAttr(Ctx, CommonInfo, Family);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::Create(ASTContext &Ctx, FamilyKind Family, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCMethodFamilyAttr(Ctx, CommonInfo, Family);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::CreateImplicit(ASTContext &Ctx, FamilyKind Family, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Family, I);
}

ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::Create(ASTContext &Ctx, FamilyKind Family, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Family, I);
}

ObjCMethodFamilyAttr::ObjCMethodFamilyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , FamilyKind Family
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCMethodFamily, false, false)
              , family(Family)
  {
}



bool ObjCMethodFamilyAttr::ConvertStrToFamilyKind(StringRef Val, FamilyKind &Out) {
  Optional<FamilyKind> R = llvm::StringSwitch<Optional<FamilyKind>>(Val)
    .Case("none", ObjCMethodFamilyAttr::OMF_None)
    .Case("alloc", ObjCMethodFamilyAttr::OMF_alloc)
    .Case("copy", ObjCMethodFamilyAttr::OMF_copy)
    .Case("init", ObjCMethodFamilyAttr::OMF_init)
    .Case("mutableCopy", ObjCMethodFamilyAttr::OMF_mutableCopy)
    .Case("new", ObjCMethodFamilyAttr::OMF_new)
    .Default(Optional<FamilyKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ObjCMethodFamilyAttr::ConvertFamilyKindToStr(FamilyKind Val) {
  switch(Val) {
  case ObjCMethodFamilyAttr::OMF_None: return "none";
  case ObjCMethodFamilyAttr::OMF_alloc: return "alloc";
  case ObjCMethodFamilyAttr::OMF_copy: return "copy";
  case ObjCMethodFamilyAttr::OMF_init: return "init";
  case ObjCMethodFamilyAttr::OMF_mutableCopy: return "mutableCopy";
  case ObjCMethodFamilyAttr::OMF_new: return "new";
  }
  llvm_unreachable("No enumerator with that value");
}
ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCMethodFamilyAttr(C, *this, family);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCMethodFamilyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_method_family";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ObjCMethodFamilyAttr::ConvertFamilyKindToStr(getFamily()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_method_family";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ObjCMethodFamilyAttr::ConvertFamilyKindToStr(getFamily()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_method_family";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ObjCMethodFamilyAttr::ConvertFamilyKindToStr(getFamily()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCMethodFamilyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_method_family";
  case 1:
    return "objc_method_family";
  case 2:
    return "objc_method_family";
  }
}


// ObjCNSObjectAttr implementation

ObjCNSObjectAttr *ObjCNSObjectAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCNSObjectAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCNSObjectAttr *ObjCNSObjectAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCNSObjectAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCNSObjectAttr *ObjCNSObjectAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCNSObjectAttr *ObjCNSObjectAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCNSObjectAttr::ObjCNSObjectAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCNSObject, false, false)
  {
}

ObjCNSObjectAttr *ObjCNSObjectAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCNSObjectAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCNSObjectAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((NSObject";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::NSObject";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::NSObject";
    OS << "]]";
    break;
  }
}
}

const char *ObjCNSObjectAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "NSObject";
  case 1:
    return "NSObject";
  case 2:
    return "NSObject";
  }
}


// ObjCNonLazyClassAttr implementation

ObjCNonLazyClassAttr *ObjCNonLazyClassAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCNonLazyClassAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCNonLazyClassAttr *ObjCNonLazyClassAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCNonLazyClassAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCNonLazyClassAttr *ObjCNonLazyClassAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCNonLazyClassAttr *ObjCNonLazyClassAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCNonLazyClassAttr::ObjCNonLazyClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCNonLazyClass, false)
  {
}

ObjCNonLazyClassAttr *ObjCNonLazyClassAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCNonLazyClassAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCNonLazyClassAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_nonlazy_class";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_nonlazy_class";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_nonlazy_class";
    OS << "]]";
    break;
  }
}
}

const char *ObjCNonLazyClassAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_nonlazy_class";
  case 1:
    return "objc_nonlazy_class";
  case 2:
    return "objc_nonlazy_class";
  }
}


// ObjCNonRuntimeProtocolAttr implementation

ObjCNonRuntimeProtocolAttr *ObjCNonRuntimeProtocolAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCNonRuntimeProtocolAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCNonRuntimeProtocolAttr *ObjCNonRuntimeProtocolAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCNonRuntimeProtocolAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCNonRuntimeProtocolAttr *ObjCNonRuntimeProtocolAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCNonRuntimeProtocolAttr *ObjCNonRuntimeProtocolAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCNonRuntimeProtocolAttr::ObjCNonRuntimeProtocolAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCNonRuntimeProtocol, false)
  {
}

ObjCNonRuntimeProtocolAttr *ObjCNonRuntimeProtocolAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCNonRuntimeProtocolAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCNonRuntimeProtocolAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_non_runtime_protocol";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_non_runtime_protocol";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_non_runtime_protocol";
    OS << "]]";
    break;
  }
}
}

const char *ObjCNonRuntimeProtocolAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_non_runtime_protocol";
  case 1:
    return "objc_non_runtime_protocol";
  case 2:
    return "objc_non_runtime_protocol";
  }
}


// ObjCOwnershipAttr implementation

ObjCOwnershipAttr *ObjCOwnershipAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Kind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCOwnershipAttr(Ctx, CommonInfo, Kind);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCOwnershipAttr *ObjCOwnershipAttr::Create(ASTContext &Ctx, IdentifierInfo * Kind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCOwnershipAttr(Ctx, CommonInfo, Kind);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCOwnershipAttr *ObjCOwnershipAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Kind, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Kind, I);
}

ObjCOwnershipAttr *ObjCOwnershipAttr::Create(ASTContext &Ctx, IdentifierInfo * Kind, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Kind, I);
}

ObjCOwnershipAttr::ObjCOwnershipAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Kind
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCOwnership, false, false)
              , kind(Kind)
  {
}



ObjCOwnershipAttr *ObjCOwnershipAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCOwnershipAttr(C, *this, kind);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCOwnershipAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_ownership";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getKind() ? getKind()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_ownership";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getKind() ? getKind()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_ownership";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getKind() ? getKind()->getName() : "") << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCOwnershipAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_ownership";
  case 1:
    return "objc_ownership";
  case 2:
    return "objc_ownership";
  }
}


// ObjCPreciseLifetimeAttr implementation

ObjCPreciseLifetimeAttr *ObjCPreciseLifetimeAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCPreciseLifetimeAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCPreciseLifetimeAttr *ObjCPreciseLifetimeAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCPreciseLifetimeAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCPreciseLifetimeAttr *ObjCPreciseLifetimeAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCPreciseLifetimeAttr *ObjCPreciseLifetimeAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCPreciseLifetimeAttr::ObjCPreciseLifetimeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCPreciseLifetime, false, false)
  {
}

ObjCPreciseLifetimeAttr *ObjCPreciseLifetimeAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCPreciseLifetimeAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCPreciseLifetimeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_precise_lifetime";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_precise_lifetime";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_precise_lifetime";
    OS << "]]";
    break;
  }
}
}

const char *ObjCPreciseLifetimeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_precise_lifetime";
  case 1:
    return "objc_precise_lifetime";
  case 2:
    return "objc_precise_lifetime";
  }
}


// ObjCRequiresPropertyDefsAttr implementation

ObjCRequiresPropertyDefsAttr *ObjCRequiresPropertyDefsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRequiresPropertyDefsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRequiresPropertyDefsAttr *ObjCRequiresPropertyDefsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRequiresPropertyDefsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRequiresPropertyDefsAttr *ObjCRequiresPropertyDefsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCRequiresPropertyDefsAttr *ObjCRequiresPropertyDefsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCRequiresPropertyDefsAttr::ObjCRequiresPropertyDefsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCRequiresPropertyDefs, false, false)
  {
}

ObjCRequiresPropertyDefsAttr *ObjCRequiresPropertyDefsAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCRequiresPropertyDefsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCRequiresPropertyDefsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_requires_property_definitions";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_requires_property_definitions";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_requires_property_definitions";
    OS << "]]";
    break;
  }
}
}

const char *ObjCRequiresPropertyDefsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_requires_property_definitions";
  case 1:
    return "objc_requires_property_definitions";
  case 2:
    return "objc_requires_property_definitions";
  }
}


// ObjCRequiresSuperAttr implementation

ObjCRequiresSuperAttr *ObjCRequiresSuperAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRequiresSuperAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRequiresSuperAttr *ObjCRequiresSuperAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRequiresSuperAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRequiresSuperAttr *ObjCRequiresSuperAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCRequiresSuperAttr *ObjCRequiresSuperAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCRequiresSuperAttr::ObjCRequiresSuperAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCRequiresSuper, false, false)
  {
}

ObjCRequiresSuperAttr *ObjCRequiresSuperAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCRequiresSuperAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCRequiresSuperAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_requires_super";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_requires_super";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_requires_super";
    OS << "]]";
    break;
  }
}
}

const char *ObjCRequiresSuperAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_requires_super";
  case 1:
    return "objc_requires_super";
  case 2:
    return "objc_requires_super";
  }
}


// ObjCReturnsInnerPointerAttr implementation

ObjCReturnsInnerPointerAttr *ObjCReturnsInnerPointerAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCReturnsInnerPointerAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCReturnsInnerPointerAttr *ObjCReturnsInnerPointerAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCReturnsInnerPointerAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCReturnsInnerPointerAttr *ObjCReturnsInnerPointerAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCReturnsInnerPointerAttr *ObjCReturnsInnerPointerAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCReturnsInnerPointerAttr::ObjCReturnsInnerPointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCReturnsInnerPointer, false, false)
  {
}

ObjCReturnsInnerPointerAttr *ObjCReturnsInnerPointerAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCReturnsInnerPointerAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCReturnsInnerPointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_returns_inner_pointer";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_returns_inner_pointer";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_returns_inner_pointer";
    OS << "]]";
    break;
  }
}
}

const char *ObjCReturnsInnerPointerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_returns_inner_pointer";
  case 1:
    return "objc_returns_inner_pointer";
  case 2:
    return "objc_returns_inner_pointer";
  }
}


// ObjCRootClassAttr implementation

ObjCRootClassAttr *ObjCRootClassAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRootClassAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRootClassAttr *ObjCRootClassAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRootClassAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRootClassAttr *ObjCRootClassAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCRootClassAttr *ObjCRootClassAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCRootClassAttr::ObjCRootClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCRootClass, false, false)
  {
}

ObjCRootClassAttr *ObjCRootClassAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCRootClassAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCRootClassAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_root_class";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_root_class";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_root_class";
    OS << "]]";
    break;
  }
}
}

const char *ObjCRootClassAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_root_class";
  case 1:
    return "objc_root_class";
  case 2:
    return "objc_root_class";
  }
}


// ObjCRuntimeNameAttr implementation

ObjCRuntimeNameAttr *ObjCRuntimeNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef MetadataName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRuntimeNameAttr(Ctx, CommonInfo, MetadataName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRuntimeNameAttr *ObjCRuntimeNameAttr::Create(ASTContext &Ctx, llvm::StringRef MetadataName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRuntimeNameAttr(Ctx, CommonInfo, MetadataName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRuntimeNameAttr *ObjCRuntimeNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef MetadataName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, MetadataName, I);
}

ObjCRuntimeNameAttr *ObjCRuntimeNameAttr::Create(ASTContext &Ctx, llvm::StringRef MetadataName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, MetadataName, I);
}

ObjCRuntimeNameAttr::ObjCRuntimeNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef MetadataName
             )
  : Attr(Ctx, CommonInfo, attr::ObjCRuntimeName, false)
              , metadataNameLength(MetadataName.size()),metadataName(new (Ctx, 1) char[metadataNameLength])
  {
    if (!MetadataName.empty())
      std::memcpy(metadataName, MetadataName.data(), metadataNameLength);
}



ObjCRuntimeNameAttr *ObjCRuntimeNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCRuntimeNameAttr(C, *this, getMetadataName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCRuntimeNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_runtime_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMetadataName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_runtime_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMetadataName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_runtime_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMetadataName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ObjCRuntimeNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_runtime_name";
  case 1:
    return "objc_runtime_name";
  case 2:
    return "objc_runtime_name";
  }
}


// ObjCRuntimeVisibleAttr implementation

ObjCRuntimeVisibleAttr *ObjCRuntimeVisibleAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRuntimeVisibleAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRuntimeVisibleAttr *ObjCRuntimeVisibleAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCRuntimeVisibleAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCRuntimeVisibleAttr *ObjCRuntimeVisibleAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCRuntimeVisibleAttr *ObjCRuntimeVisibleAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCRuntimeVisibleAttr::ObjCRuntimeVisibleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCRuntimeVisible, false)
  {
}

ObjCRuntimeVisibleAttr *ObjCRuntimeVisibleAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCRuntimeVisibleAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCRuntimeVisibleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_runtime_visible";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_runtime_visible";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_runtime_visible";
    OS << "]]";
    break;
  }
}
}

const char *ObjCRuntimeVisibleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_runtime_visible";
  case 1:
    return "objc_runtime_visible";
  case 2:
    return "objc_runtime_visible";
  }
}


// ObjCSubclassingRestrictedAttr implementation

ObjCSubclassingRestrictedAttr *ObjCSubclassingRestrictedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCSubclassingRestrictedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCSubclassingRestrictedAttr *ObjCSubclassingRestrictedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ObjCSubclassingRestrictedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ObjCSubclassingRestrictedAttr *ObjCSubclassingRestrictedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ObjCSubclassingRestrictedAttr *ObjCSubclassingRestrictedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ObjCSubclassingRestrictedAttr::ObjCSubclassingRestrictedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCSubclassingRestricted, false, false)
  {
}

ObjCSubclassingRestrictedAttr *ObjCSubclassingRestrictedAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCSubclassingRestrictedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ObjCSubclassingRestrictedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((objc_subclassing_restricted";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::objc_subclassing_restricted";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::objc_subclassing_restricted";
    OS << "]]";
    break;
  }
}
}

const char *ObjCSubclassingRestrictedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "objc_subclassing_restricted";
  case 1:
    return "objc_subclassing_restricted";
  case 2:
    return "objc_subclassing_restricted";
  }
}


// OpenCLAccessAttr implementation

OpenCLAccessAttr *OpenCLAccessAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLAccessAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLAccessAttr *OpenCLAccessAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLAccessAttr(Ctx, CommonInfo);
  return A;
}

OpenCLAccessAttr *OpenCLAccessAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLAccessAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

OpenCLAccessAttr *OpenCLAccessAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLAccessAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

OpenCLAccessAttr::OpenCLAccessAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::OpenCLAccess, false)
  {
}

OpenCLAccessAttr::Spelling OpenCLAccessAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_read_only;
    case 1: return Keyword_read_only;
    case 2: return Keyword_write_only;
    case 3: return Keyword_write_only;
    case 4: return Keyword_read_write;
    case 5: return Keyword_read_write;
  }
}
OpenCLAccessAttr *OpenCLAccessAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLAccessAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLAccessAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __read_only";
    OS << "";
    break;
  }
  case 1 : {
    OS << " read_only";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __write_only";
    OS << "";
    break;
  }
  case 3 : {
    OS << " write_only";
    OS << "";
    break;
  }
  case 4 : {
    OS << " __read_write";
    OS << "";
    break;
  }
  case 5 : {
    OS << " read_write";
    OS << "";
    break;
  }
}
}

const char *OpenCLAccessAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__read_only";
  case 1:
    return "read_only";
  case 2:
    return "__write_only";
  case 3:
    return "write_only";
  case 4:
    return "__read_write";
  case 5:
    return "read_write";
  }
}


// OpenCLConstantAddressSpaceAttr implementation

OpenCLConstantAddressSpaceAttr *OpenCLConstantAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLConstantAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLConstantAddressSpaceAttr *OpenCLConstantAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLConstantAddressSpaceAttr(Ctx, CommonInfo);
  return A;
}

OpenCLConstantAddressSpaceAttr *OpenCLConstantAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLConstantAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

OpenCLConstantAddressSpaceAttr *OpenCLConstantAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLConstantAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

OpenCLConstantAddressSpaceAttr::OpenCLConstantAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLConstantAddressSpace, false)
  {
}

OpenCLConstantAddressSpaceAttr::Spelling OpenCLConstantAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_constant;
    case 1: return Keyword_constant;
    case 2: return GNU_opencl_constant;
    case 3: return CXX11_clang_opencl_constant;
    case 4: return C2x_clang_opencl_constant;
  }
}
OpenCLConstantAddressSpaceAttr *OpenCLConstantAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLConstantAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLConstantAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __constant";
    OS << "";
    break;
  }
  case 1 : {
    OS << " constant";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __attribute__((opencl_constant";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::opencl_constant";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::opencl_constant";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLConstantAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__constant";
  case 1:
    return "constant";
  case 2:
    return "opencl_constant";
  case 3:
    return "opencl_constant";
  case 4:
    return "opencl_constant";
  }
}


// OpenCLGenericAddressSpaceAttr implementation

OpenCLGenericAddressSpaceAttr *OpenCLGenericAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGenericAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLGenericAddressSpaceAttr *OpenCLGenericAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGenericAddressSpaceAttr(Ctx, CommonInfo);
  return A;
}

OpenCLGenericAddressSpaceAttr *OpenCLGenericAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLGenericAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

OpenCLGenericAddressSpaceAttr *OpenCLGenericAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLGenericAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

OpenCLGenericAddressSpaceAttr::OpenCLGenericAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGenericAddressSpace, false)
  {
}

OpenCLGenericAddressSpaceAttr::Spelling OpenCLGenericAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_generic;
    case 1: return Keyword_generic;
    case 2: return GNU_opencl_generic;
    case 3: return CXX11_clang_opencl_generic;
    case 4: return C2x_clang_opencl_generic;
  }
}
OpenCLGenericAddressSpaceAttr *OpenCLGenericAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLGenericAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLGenericAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __generic";
    OS << "";
    break;
  }
  case 1 : {
    OS << " generic";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __attribute__((opencl_generic";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::opencl_generic";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::opencl_generic";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLGenericAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__generic";
  case 1:
    return "generic";
  case 2:
    return "opencl_generic";
  case 3:
    return "opencl_generic";
  case 4:
    return "opencl_generic";
  }
}


// OpenCLGlobalAddressSpaceAttr implementation

OpenCLGlobalAddressSpaceAttr *OpenCLGlobalAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGlobalAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLGlobalAddressSpaceAttr *OpenCLGlobalAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGlobalAddressSpaceAttr(Ctx, CommonInfo);
  return A;
}

OpenCLGlobalAddressSpaceAttr *OpenCLGlobalAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLGlobalAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

OpenCLGlobalAddressSpaceAttr *OpenCLGlobalAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLGlobalAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

OpenCLGlobalAddressSpaceAttr::OpenCLGlobalAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGlobalAddressSpace, false)
  {
}

OpenCLGlobalAddressSpaceAttr::Spelling OpenCLGlobalAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_global;
    case 1: return Keyword_global;
    case 2: return GNU_opencl_global;
    case 3: return CXX11_clang_opencl_global;
    case 4: return C2x_clang_opencl_global;
  }
}
OpenCLGlobalAddressSpaceAttr *OpenCLGlobalAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLGlobalAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLGlobalAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __global";
    OS << "";
    break;
  }
  case 1 : {
    OS << " global";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __attribute__((opencl_global";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::opencl_global";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::opencl_global";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLGlobalAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__global";
  case 1:
    return "global";
  case 2:
    return "opencl_global";
  case 3:
    return "opencl_global";
  case 4:
    return "opencl_global";
  }
}


// OpenCLGlobalDeviceAddressSpaceAttr implementation

OpenCLGlobalDeviceAddressSpaceAttr *OpenCLGlobalDeviceAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGlobalDeviceAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLGlobalDeviceAddressSpaceAttr *OpenCLGlobalDeviceAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGlobalDeviceAddressSpaceAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLGlobalDeviceAddressSpaceAttr *OpenCLGlobalDeviceAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OpenCLGlobalDeviceAddressSpaceAttr *OpenCLGlobalDeviceAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OpenCLGlobalDeviceAddressSpaceAttr::OpenCLGlobalDeviceAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGlobalDeviceAddressSpace, false)
  {
}

OpenCLGlobalDeviceAddressSpaceAttr *OpenCLGlobalDeviceAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLGlobalDeviceAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLGlobalDeviceAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((opencl_global_device";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::opencl_global_device";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::opencl_global_device";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLGlobalDeviceAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "opencl_global_device";
  case 1:
    return "opencl_global_device";
  case 2:
    return "opencl_global_device";
  }
}


// OpenCLGlobalHostAddressSpaceAttr implementation

OpenCLGlobalHostAddressSpaceAttr *OpenCLGlobalHostAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGlobalHostAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLGlobalHostAddressSpaceAttr *OpenCLGlobalHostAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLGlobalHostAddressSpaceAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLGlobalHostAddressSpaceAttr *OpenCLGlobalHostAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OpenCLGlobalHostAddressSpaceAttr *OpenCLGlobalHostAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OpenCLGlobalHostAddressSpaceAttr::OpenCLGlobalHostAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGlobalHostAddressSpace, false)
  {
}

OpenCLGlobalHostAddressSpaceAttr *OpenCLGlobalHostAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLGlobalHostAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLGlobalHostAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((opencl_global_host";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::opencl_global_host";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::opencl_global_host";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLGlobalHostAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "opencl_global_host";
  case 1:
    return "opencl_global_host";
  case 2:
    return "opencl_global_host";
  }
}


// OpenCLIntelReqdSubGroupSizeAttr implementation

OpenCLIntelReqdSubGroupSizeAttr *OpenCLIntelReqdSubGroupSizeAttr::CreateImplicit(ASTContext &Ctx, unsigned SubGroupSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLIntelReqdSubGroupSizeAttr(Ctx, CommonInfo, SubGroupSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLIntelReqdSubGroupSizeAttr *OpenCLIntelReqdSubGroupSizeAttr::Create(ASTContext &Ctx, unsigned SubGroupSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLIntelReqdSubGroupSizeAttr(Ctx, CommonInfo, SubGroupSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLIntelReqdSubGroupSizeAttr *OpenCLIntelReqdSubGroupSizeAttr::CreateImplicit(ASTContext &Ctx, unsigned SubGroupSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, SubGroupSize, I);
}

OpenCLIntelReqdSubGroupSizeAttr *OpenCLIntelReqdSubGroupSizeAttr::Create(ASTContext &Ctx, unsigned SubGroupSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, SubGroupSize, I);
}

OpenCLIntelReqdSubGroupSizeAttr::OpenCLIntelReqdSubGroupSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned SubGroupSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OpenCLIntelReqdSubGroupSize, false, false)
              , subGroupSize(SubGroupSize)
  {
}



OpenCLIntelReqdSubGroupSizeAttr *OpenCLIntelReqdSubGroupSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLIntelReqdSubGroupSizeAttr(C, *this, subGroupSize);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLIntelReqdSubGroupSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((intel_reqd_sub_group_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSubGroupSize() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *OpenCLIntelReqdSubGroupSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "intel_reqd_sub_group_size";
  }
}


// OpenCLKernelAttr implementation

OpenCLKernelAttr *OpenCLKernelAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLKernelAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLKernelAttr *OpenCLKernelAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLKernelAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLKernelAttr *OpenCLKernelAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OpenCLKernelAttr *OpenCLKernelAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OpenCLKernelAttr::OpenCLKernelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OpenCLKernel, false, false)
  {
}

OpenCLKernelAttr *OpenCLKernelAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLKernelAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLKernelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __kernel";
    OS << "";
    break;
  }
  case 1 : {
    OS << " kernel";
    OS << "";
    break;
  }
}
}

const char *OpenCLKernelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__kernel";
  case 1:
    return "kernel";
  }
}


// OpenCLLocalAddressSpaceAttr implementation

OpenCLLocalAddressSpaceAttr *OpenCLLocalAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLLocalAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLLocalAddressSpaceAttr *OpenCLLocalAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLLocalAddressSpaceAttr(Ctx, CommonInfo);
  return A;
}

OpenCLLocalAddressSpaceAttr *OpenCLLocalAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLLocalAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

OpenCLLocalAddressSpaceAttr *OpenCLLocalAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLLocalAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

OpenCLLocalAddressSpaceAttr::OpenCLLocalAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLLocalAddressSpace, false)
  {
}

OpenCLLocalAddressSpaceAttr::Spelling OpenCLLocalAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_local;
    case 1: return Keyword_local;
    case 2: return GNU_opencl_local;
    case 3: return CXX11_clang_opencl_local;
    case 4: return C2x_clang_opencl_local;
  }
}
OpenCLLocalAddressSpaceAttr *OpenCLLocalAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLLocalAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLLocalAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __local";
    OS << "";
    break;
  }
  case 1 : {
    OS << " local";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __attribute__((opencl_local";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::opencl_local";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::opencl_local";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLLocalAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__local";
  case 1:
    return "local";
  case 2:
    return "opencl_local";
  case 3:
    return "opencl_local";
  case 4:
    return "opencl_local";
  }
}


// OpenCLPrivateAddressSpaceAttr implementation

OpenCLPrivateAddressSpaceAttr *OpenCLPrivateAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLPrivateAddressSpaceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLPrivateAddressSpaceAttr *OpenCLPrivateAddressSpaceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLPrivateAddressSpaceAttr(Ctx, CommonInfo);
  return A;
}

OpenCLPrivateAddressSpaceAttr *OpenCLPrivateAddressSpaceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLPrivateAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

OpenCLPrivateAddressSpaceAttr *OpenCLPrivateAddressSpaceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OpenCLPrivateAddressSpaceAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

OpenCLPrivateAddressSpaceAttr::OpenCLPrivateAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLPrivateAddressSpace, false)
  {
}

OpenCLPrivateAddressSpaceAttr::Spelling OpenCLPrivateAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_private;
    case 1: return Keyword_private;
    case 2: return GNU_opencl_private;
    case 3: return CXX11_clang_opencl_private;
    case 4: return C2x_clang_opencl_private;
  }
}
OpenCLPrivateAddressSpaceAttr *OpenCLPrivateAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLPrivateAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLPrivateAddressSpaceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __private";
    OS << "";
    break;
  }
  case 1 : {
    OS << " private";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __attribute__((opencl_private";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::opencl_private";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[clang::opencl_private";
    OS << "]]";
    break;
  }
}
}

const char *OpenCLPrivateAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__private";
  case 1:
    return "private";
  case 2:
    return "opencl_private";
  case 3:
    return "opencl_private";
  case 4:
    return "opencl_private";
  }
}


// OpenCLUnrollHintAttr implementation

OpenCLUnrollHintAttr *OpenCLUnrollHintAttr::CreateImplicit(ASTContext &Ctx, unsigned UnrollHint, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLUnrollHintAttr(Ctx, CommonInfo, UnrollHint);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLUnrollHintAttr *OpenCLUnrollHintAttr::Create(ASTContext &Ctx, unsigned UnrollHint, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OpenCLUnrollHintAttr(Ctx, CommonInfo, UnrollHint);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OpenCLUnrollHintAttr *OpenCLUnrollHintAttr::CreateImplicit(ASTContext &Ctx, unsigned UnrollHint, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, UnrollHint, I);
}

OpenCLUnrollHintAttr *OpenCLUnrollHintAttr::Create(ASTContext &Ctx, unsigned UnrollHint, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, UnrollHint, I);
}

OpenCLUnrollHintAttr::OpenCLUnrollHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned UnrollHint
             )
  : StmtAttr(Ctx, CommonInfo, attr::OpenCLUnrollHint, false)
              , unrollHint(UnrollHint)
  {
}

OpenCLUnrollHintAttr::OpenCLUnrollHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::OpenCLUnrollHint, false)
              , unrollHint()
  {
}



OpenCLUnrollHintAttr *OpenCLUnrollHintAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLUnrollHintAttr(C, *this, unrollHint);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLUnrollHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((opencl_unroll_hint";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getUnrollHint() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *OpenCLUnrollHintAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "opencl_unroll_hint";
  }
}


// OptimizeNoneAttr implementation

OptimizeNoneAttr *OptimizeNoneAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OptimizeNoneAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OptimizeNoneAttr *OptimizeNoneAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OptimizeNoneAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OptimizeNoneAttr *OptimizeNoneAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OptimizeNoneAttr *OptimizeNoneAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OptimizeNoneAttr::OptimizeNoneAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OptimizeNone, false, false)
  {
}

OptimizeNoneAttr *OptimizeNoneAttr::clone(ASTContext &C) const {
  auto *A = new (C) OptimizeNoneAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OptimizeNoneAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((optnone";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::optnone";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::optnone";
    OS << "]]";
    break;
  }
}
}

const char *OptimizeNoneAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "optnone";
  case 1:
    return "optnone";
  case 2:
    return "optnone";
  }
}


// OverloadableAttr implementation

OverloadableAttr *OverloadableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OverloadableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OverloadableAttr *OverloadableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OverloadableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OverloadableAttr *OverloadableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OverloadableAttr *OverloadableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OverloadableAttr::OverloadableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::Overloadable, false)
  {
}

OverloadableAttr *OverloadableAttr::clone(ASTContext &C) const {
  auto *A = new (C) OverloadableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OverloadableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((overloadable";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::overloadable";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::overloadable";
    OS << "]]";
    break;
  }
}
}

const char *OverloadableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "overloadable";
  case 1:
    return "overloadable";
  case 2:
    return "overloadable";
  }
}


// OverrideAttr implementation

OverrideAttr *OverrideAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OverrideAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OverrideAttr *OverrideAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OverrideAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OverrideAttr *OverrideAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

OverrideAttr *OverrideAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

OverrideAttr::OverrideAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Override, false, false)
  {
}

OverrideAttr *OverrideAttr::clone(ASTContext &C) const {
  auto *A = new (C) OverrideAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OverrideAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " override";
    OS << "";
    break;
  }
}
}

const char *OverrideAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "override";
  }
}


// OwnerAttr implementation

OwnerAttr *OwnerAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * DerefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OwnerAttr(Ctx, CommonInfo, DerefType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OwnerAttr *OwnerAttr::Create(ASTContext &Ctx, TypeSourceInfo * DerefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OwnerAttr(Ctx, CommonInfo, DerefType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OwnerAttr *OwnerAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * DerefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, DerefType, I);
}

OwnerAttr *OwnerAttr::Create(ASTContext &Ctx, TypeSourceInfo * DerefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, DerefType, I);
}

OwnerAttr::OwnerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * DerefType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Owner, false, false)
              , derefType(DerefType)
  {
}

OwnerAttr::OwnerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Owner, false, false)
              , derefType()
  {
}



OwnerAttr *OwnerAttr::clone(ASTContext &C) const {
  auto *A = new (C) OwnerAttr(C, *this, derefType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OwnerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[gsl::Owner";
    if (!getDerefTypeLoc())
      ++TrailingOmittedArgs;
    if (!(!getDerefTypeLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getDerefType().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *OwnerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "Owner";
  }
}


// OwnershipAttr implementation

OwnershipAttr *OwnershipAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OwnershipAttr(Ctx, CommonInfo, Module, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OwnershipAttr *OwnershipAttr::Create(ASTContext &Ctx, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OwnershipAttr(Ctx, CommonInfo, Module, Args, ArgsSize);
  return A;
}

OwnershipAttr *OwnershipAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OwnershipAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Module, Args, ArgsSize, I);
}

OwnershipAttr *OwnershipAttr::Create(ASTContext &Ctx, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, OwnershipAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Module, Args, ArgsSize, I);
}

OwnershipAttr::OwnershipAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Module
              , ParamIdx *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Ownership, false, false)
              , module(Module)
              , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

OwnershipAttr::OwnershipAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Module
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Ownership, false, false)
              , module(Module)
              , args_Size(0), args_(nullptr)
  {
}

OwnershipAttr::Spelling OwnershipAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_ownership_holds;
    case 1: return CXX11_clang_ownership_holds;
    case 2: return C2x_clang_ownership_holds;
    case 3: return GNU_ownership_returns;
    case 4: return CXX11_clang_ownership_returns;
    case 5: return C2x_clang_ownership_returns;
    case 6: return GNU_ownership_takes;
    case 7: return CXX11_clang_ownership_takes;
    case 8: return C2x_clang_ownership_takes;
  }
}




OwnershipAttr *OwnershipAttr::clone(ASTContext &C) const {
  auto *A = new (C) OwnershipAttr(C, *this, module, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OwnershipAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ownership_holds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ownership_holds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ownership_holds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((ownership_returns";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::ownership_returns";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::ownership_returns";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 6 : {
    OS << " __attribute__((ownership_takes";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 7 : {
    OS << " [[clang::ownership_takes";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 8 : {
    OS << " [[clang::ownership_takes";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *OwnershipAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ownership_holds";
  case 1:
    return "ownership_holds";
  case 2:
    return "ownership_holds";
  case 3:
    return "ownership_returns";
  case 4:
    return "ownership_returns";
  case 5:
    return "ownership_returns";
  case 6:
    return "ownership_takes";
  case 7:
    return "ownership_takes";
  case 8:
    return "ownership_takes";
  }
}


// PackedAttr implementation

PackedAttr *PackedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PackedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PackedAttr *PackedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PackedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PackedAttr *PackedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PackedAttr *PackedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PackedAttr::PackedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Packed, false, false)
  {
}

PackedAttr *PackedAttr::clone(ASTContext &C) const {
  auto *A = new (C) PackedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PackedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((packed";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::packed";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::packed";
    OS << "]]";
    break;
  }
}
}

const char *PackedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "packed";
  case 1:
    return "packed";
  case 2:
    return "packed";
  }
}


// ParamTypestateAttr implementation

ParamTypestateAttr *ParamTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState ParamState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ParamTypestateAttr(Ctx, CommonInfo, ParamState);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ParamTypestateAttr *ParamTypestateAttr::Create(ASTContext &Ctx, ConsumedState ParamState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ParamTypestateAttr(Ctx, CommonInfo, ParamState);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ParamTypestateAttr *ParamTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState ParamState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ParamState, I);
}

ParamTypestateAttr *ParamTypestateAttr::Create(ASTContext &Ctx, ConsumedState ParamState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ParamState, I);
}

ParamTypestateAttr::ParamTypestateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState ParamState
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ParamTypestate, false, false)
              , paramState(ParamState)
  {
}



bool ParamTypestateAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("unknown", ParamTypestateAttr::Unknown)
    .Case("consumed", ParamTypestateAttr::Consumed)
    .Case("unconsumed", ParamTypestateAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ParamTypestateAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case ParamTypestateAttr::Unknown: return "unknown";
  case ParamTypestateAttr::Consumed: return "consumed";
  case ParamTypestateAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
ParamTypestateAttr *ParamTypestateAttr::clone(ASTContext &C) const {
  auto *A = new (C) ParamTypestateAttr(C, *this, paramState);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ParamTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((param_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ParamTypestateAttr::ConvertConsumedStateToStr(getParamState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::param_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ParamTypestateAttr::ConvertConsumedStateToStr(getParamState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ParamTypestateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "param_typestate";
  case 1:
    return "param_typestate";
  }
}


// PascalAttr implementation

PascalAttr *PascalAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PascalAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PascalAttr *PascalAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PascalAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PascalAttr *PascalAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PascalAttr *PascalAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PascalAttr::PascalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pascal, false, false)
  {
}

PascalAttr *PascalAttr::clone(ASTContext &C) const {
  auto *A = new (C) PascalAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PascalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pascal";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::pascal";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::pascal";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __pascal";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _pascal";
    OS << "";
    break;
  }
}
}

const char *PascalAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pascal";
  case 1:
    return "pascal";
  case 2:
    return "pascal";
  case 3:
    return "__pascal";
  case 4:
    return "_pascal";
  }
}


// PassObjectSizeAttr implementation

PassObjectSizeAttr *PassObjectSizeAttr::CreateImplicit(ASTContext &Ctx, int Type, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PassObjectSizeAttr(Ctx, CommonInfo, Type);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PassObjectSizeAttr *PassObjectSizeAttr::Create(ASTContext &Ctx, int Type, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PassObjectSizeAttr(Ctx, CommonInfo, Type);
  return A;
}

PassObjectSizeAttr *PassObjectSizeAttr::CreateImplicit(ASTContext &Ctx, int Type, SourceRange Range, AttributeCommonInfo::Syntax Syntax, PassObjectSizeAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Type, I);
}

PassObjectSizeAttr *PassObjectSizeAttr::Create(ASTContext &Ctx, int Type, SourceRange Range, AttributeCommonInfo::Syntax Syntax, PassObjectSizeAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Type, I);
}

PassObjectSizeAttr::PassObjectSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int Type
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::PassObjectSize, false, false)
              , type(Type)
  {
}

PassObjectSizeAttr::Spelling PassObjectSizeAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_pass_object_size;
    case 1: return CXX11_clang_pass_object_size;
    case 2: return C2x_clang_pass_object_size;
    case 3: return GNU_pass_dynamic_object_size;
    case 4: return CXX11_clang_pass_dynamic_object_size;
    case 5: return C2x_clang_pass_dynamic_object_size;
  }
}


PassObjectSizeAttr *PassObjectSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) PassObjectSizeAttr(C, *this, type);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PassObjectSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pass_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::pass_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::pass_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((pass_dynamic_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::pass_dynamic_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::pass_dynamic_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PassObjectSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pass_object_size";
  case 1:
    return "pass_object_size";
  case 2:
    return "pass_object_size";
  case 3:
    return "pass_dynamic_object_size";
  case 4:
    return "pass_dynamic_object_size";
  case 5:
    return "pass_dynamic_object_size";
  }
}


// PatchableFunctionEntryAttr implementation

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::CreateImplicit(ASTContext &Ctx, unsigned Count, int Offset, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PatchableFunctionEntryAttr(Ctx, CommonInfo, Count, Offset);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::Create(ASTContext &Ctx, unsigned Count, int Offset, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PatchableFunctionEntryAttr(Ctx, CommonInfo, Count, Offset);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::CreateImplicit(ASTContext &Ctx, unsigned Count, int Offset, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Count, Offset, I);
}

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::Create(ASTContext &Ctx, unsigned Count, int Offset, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Count, Offset, I);
}

PatchableFunctionEntryAttr::PatchableFunctionEntryAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Count
              , int Offset
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PatchableFunctionEntry, false, false)
              , count(Count)
              , offset(Offset)
  {
}

PatchableFunctionEntryAttr::PatchableFunctionEntryAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Count
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PatchableFunctionEntry, false, false)
              , count(Count)
              , offset()
  {
}





PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::clone(ASTContext &C) const {
  auto *A = new (C) PatchableFunctionEntryAttr(C, *this, count, offset);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PatchableFunctionEntryAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((patchable_function_entry";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCount() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::patchable_function_entry";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCount() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::patchable_function_entry";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCount() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PatchableFunctionEntryAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "patchable_function_entry";
  case 1:
    return "patchable_function_entry";
  case 2:
    return "patchable_function_entry";
  }
}


// PcsAttr implementation

PcsAttr *PcsAttr::CreateImplicit(ASTContext &Ctx, PCSType PCS, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PcsAttr(Ctx, CommonInfo, PCS);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PcsAttr *PcsAttr::Create(ASTContext &Ctx, PCSType PCS, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PcsAttr(Ctx, CommonInfo, PCS);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PcsAttr *PcsAttr::CreateImplicit(ASTContext &Ctx, PCSType PCS, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, PCS, I);
}

PcsAttr *PcsAttr::Create(ASTContext &Ctx, PCSType PCS, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, PCS, I);
}

PcsAttr::PcsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , PCSType PCS
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pcs, false, false)
              , pCS(PCS)
  {
}



bool PcsAttr::ConvertStrToPCSType(StringRef Val, PCSType &Out) {
  Optional<PCSType> R = llvm::StringSwitch<Optional<PCSType>>(Val)
    .Case("aapcs", PcsAttr::AAPCS)
    .Case("aapcs-vfp", PcsAttr::AAPCS_VFP)
    .Default(Optional<PCSType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *PcsAttr::ConvertPCSTypeToStr(PCSType Val) {
  switch(Val) {
  case PcsAttr::AAPCS: return "aapcs";
  case PcsAttr::AAPCS_VFP: return "aapcs-vfp";
  }
  llvm_unreachable("No enumerator with that value");
}
PcsAttr *PcsAttr::clone(ASTContext &C) const {
  auto *A = new (C) PcsAttr(C, *this, pCS);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PcsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pcs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << PcsAttr::ConvertPCSTypeToStr(getPCS()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::pcs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << PcsAttr::ConvertPCSTypeToStr(getPCS()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::pcs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << PcsAttr::ConvertPCSTypeToStr(getPCS()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PcsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pcs";
  case 1:
    return "pcs";
  case 2:
    return "pcs";
  }
}


// PointerAttr implementation

PointerAttr *PointerAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * DerefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PointerAttr(Ctx, CommonInfo, DerefType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PointerAttr *PointerAttr::Create(ASTContext &Ctx, TypeSourceInfo * DerefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PointerAttr(Ctx, CommonInfo, DerefType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PointerAttr *PointerAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * DerefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, DerefType, I);
}

PointerAttr *PointerAttr::Create(ASTContext &Ctx, TypeSourceInfo * DerefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, DerefType, I);
}

PointerAttr::PointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * DerefType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pointer, false, false)
              , derefType(DerefType)
  {
}

PointerAttr::PointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pointer, false, false)
              , derefType()
  {
}



PointerAttr *PointerAttr::clone(ASTContext &C) const {
  auto *A = new (C) PointerAttr(C, *this, derefType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[gsl::Pointer";
    if (!getDerefTypeLoc())
      ++TrailingOmittedArgs;
    if (!(!getDerefTypeLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getDerefType().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PointerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "Pointer";
  }
}


// PragmaClangBSSSectionAttr implementation

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangBSSSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangBSSSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangBSSSectionAttr::PragmaClangBSSSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangBSSSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangBSSSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangBSSSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangBSSSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangDataSectionAttr implementation

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangDataSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangDataSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangDataSectionAttr::PragmaClangDataSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangDataSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangDataSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangDataSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangDataSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangRelroSectionAttr implementation

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRelroSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRelroSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangRelroSectionAttr::PragmaClangRelroSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangRelroSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangRelroSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangRelroSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangRelroSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangRodataSectionAttr implementation

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRodataSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRodataSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangRodataSectionAttr::PragmaClangRodataSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangRodataSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangRodataSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangRodataSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangRodataSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangTextSectionAttr implementation

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangTextSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangTextSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangTextSectionAttr::PragmaClangTextSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangTextSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangTextSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangTextSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangTextSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PreferredNameAttr implementation

PreferredNameAttr *PreferredNameAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypedefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreferredNameAttr(Ctx, CommonInfo, TypedefType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreferredNameAttr *PreferredNameAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypedefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreferredNameAttr(Ctx, CommonInfo, TypedefType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreferredNameAttr *PreferredNameAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypedefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TypedefType, I);
}

PreferredNameAttr *PreferredNameAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypedefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TypedefType, I);
}

PreferredNameAttr::PreferredNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * TypedefType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PreferredName, false, true)
              , typedefType(TypedefType)
  {
}



PreferredNameAttr *PreferredNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) PreferredNameAttr(C, *this, typedefType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PreferredNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preferred_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypedefType().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preferred_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypedefType().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PreferredNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preferred_name";
  case 1:
    return "preferred_name";
  }
}


// PreserveAllAttr implementation

PreserveAllAttr *PreserveAllAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveAllAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveAllAttr *PreserveAllAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveAllAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveAllAttr *PreserveAllAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PreserveAllAttr *PreserveAllAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PreserveAllAttr::PreserveAllAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PreserveAll, false, false)
  {
}

PreserveAllAttr *PreserveAllAttr::clone(ASTContext &C) const {
  auto *A = new (C) PreserveAllAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PreserveAllAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preserve_all";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preserve_all";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::preserve_all";
    OS << "]]";
    break;
  }
}
}

const char *PreserveAllAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preserve_all";
  case 1:
    return "preserve_all";
  case 2:
    return "preserve_all";
  }
}


// PreserveMostAttr implementation

PreserveMostAttr *PreserveMostAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveMostAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveMostAttr *PreserveMostAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveMostAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveMostAttr *PreserveMostAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PreserveMostAttr *PreserveMostAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PreserveMostAttr::PreserveMostAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PreserveMost, false, false)
  {
}

PreserveMostAttr *PreserveMostAttr::clone(ASTContext &C) const {
  auto *A = new (C) PreserveMostAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PreserveMostAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preserve_most";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preserve_most";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::preserve_most";
    OS << "]]";
    break;
  }
}
}

const char *PreserveMostAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preserve_most";
  case 1:
    return "preserve_most";
  case 2:
    return "preserve_most";
  }
}


// PtGuardedByAttr implementation

PtGuardedByAttr *PtGuardedByAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedByAttr(Ctx, CommonInfo, Arg);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedByAttr *PtGuardedByAttr::Create(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedByAttr(Ctx, CommonInfo, Arg);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedByAttr *PtGuardedByAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Arg, I);
}

PtGuardedByAttr *PtGuardedByAttr::Create(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Arg, I);
}

PtGuardedByAttr::PtGuardedByAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Arg
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PtGuardedBy, true, true)
              , arg(Arg)
  {
}



PtGuardedByAttr *PtGuardedByAttr::clone(ASTContext &C) const {
  auto *A = new (C) PtGuardedByAttr(C, *this, arg);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PtGuardedByAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pt_guarded_by";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *PtGuardedByAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pt_guarded_by";
  }
}


// PtGuardedVarAttr implementation

PtGuardedVarAttr *PtGuardedVarAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedVarAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedVarAttr *PtGuardedVarAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedVarAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedVarAttr *PtGuardedVarAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PtGuardedVarAttr *PtGuardedVarAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PtGuardedVarAttr::PtGuardedVarAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PtGuardedVar, false, false)
  {
}

PtGuardedVarAttr *PtGuardedVarAttr::clone(ASTContext &C) const {
  auto *A = new (C) PtGuardedVarAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PtGuardedVarAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pt_guarded_var";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::pt_guarded_var";
    OS << "]]";
    break;
  }
}
}

const char *PtGuardedVarAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pt_guarded_var";
  case 1:
    return "pt_guarded_var";
  }
}


// Ptr32Attr implementation

Ptr32Attr *Ptr32Attr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr32Attr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr32Attr *Ptr32Attr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr32Attr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr32Attr *Ptr32Attr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

Ptr32Attr *Ptr32Attr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

Ptr32Attr::Ptr32Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::Ptr32, false)
  {
}

Ptr32Attr *Ptr32Attr::clone(ASTContext &C) const {
  auto *A = new (C) Ptr32Attr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void Ptr32Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __ptr32";
    OS << "";
    break;
  }
}
}

const char *Ptr32Attr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__ptr32";
  }
}


// Ptr64Attr implementation

Ptr64Attr *Ptr64Attr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr64Attr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr64Attr *Ptr64Attr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr64Attr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr64Attr *Ptr64Attr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

Ptr64Attr *Ptr64Attr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

Ptr64Attr::Ptr64Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::Ptr64, false)
  {
}

Ptr64Attr *Ptr64Attr::clone(ASTContext &C) const {
  auto *A = new (C) Ptr64Attr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void Ptr64Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __ptr64";
    OS << "";
    break;
  }
}
}

const char *Ptr64Attr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__ptr64";
  }
}


// PureAttr implementation

PureAttr *PureAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PureAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PureAttr *PureAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PureAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PureAttr *PureAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PureAttr *PureAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PureAttr::PureAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pure, false, false)
  {
}

PureAttr *PureAttr::clone(ASTContext &C) const {
  auto *A = new (C) PureAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PureAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pure";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::pure";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::pure";
    OS << "]]";
    break;
  }
}
}

const char *PureAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pure";
  case 1:
    return "pure";
  case 2:
    return "pure";
  }
}


// RISCVInterruptAttr implementation

RISCVInterruptAttr *RISCVInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RISCVInterruptAttr(Ctx, CommonInfo, Interrupt);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RISCVInterruptAttr *RISCVInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RISCVInterruptAttr(Ctx, CommonInfo, Interrupt);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RISCVInterruptAttr *RISCVInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Interrupt, I);
}

RISCVInterruptAttr *RISCVInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Interrupt, I);
}

RISCVInterruptAttr::RISCVInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , InterruptType Interrupt
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RISCVInterrupt, false, false)
              , interrupt(Interrupt)
  {
}

RISCVInterruptAttr::RISCVInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RISCVInterrupt, false, false)
              , interrupt(InterruptType(0))
  {
}



bool RISCVInterruptAttr::ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
  Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
    .Case("user", RISCVInterruptAttr::user)
    .Case("supervisor", RISCVInterruptAttr::supervisor)
    .Case("machine", RISCVInterruptAttr::machine)
    .Default(Optional<InterruptType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *RISCVInterruptAttr::ConvertInterruptTypeToStr(InterruptType Val) {
  switch(Val) {
  case RISCVInterruptAttr::user: return "user";
  case RISCVInterruptAttr::supervisor: return "supervisor";
  case RISCVInterruptAttr::machine: return "machine";
  }
  llvm_unreachable("No enumerator with that value");
}
RISCVInterruptAttr *RISCVInterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) RISCVInterruptAttr(C, *this, interrupt);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RISCVInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << RISCVInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << RISCVInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << RISCVInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *RISCVInterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// RandomizeLayoutAttr implementation

RandomizeLayoutAttr *RandomizeLayoutAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RandomizeLayoutAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RandomizeLayoutAttr *RandomizeLayoutAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RandomizeLayoutAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RandomizeLayoutAttr *RandomizeLayoutAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

RandomizeLayoutAttr *RandomizeLayoutAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

RandomizeLayoutAttr::RandomizeLayoutAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RandomizeLayout, false, false)
  {
}

RandomizeLayoutAttr *RandomizeLayoutAttr::clone(ASTContext &C) const {
  auto *A = new (C) RandomizeLayoutAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RandomizeLayoutAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((randomize_layout";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::randomize_layout";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::randomize_layout";
    OS << "]]";
    break;
  }
}
}

const char *RandomizeLayoutAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "randomize_layout";
  case 1:
    return "randomize_layout";
  case 2:
    return "randomize_layout";
  }
}


// RegCallAttr implementation

RegCallAttr *RegCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RegCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RegCallAttr *RegCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RegCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RegCallAttr *RegCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

RegCallAttr *RegCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

RegCallAttr::RegCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RegCall, false, false)
  {
}

RegCallAttr *RegCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) RegCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RegCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((regcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::regcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::regcall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __regcall";
    OS << "";
    break;
  }
}
}

const char *RegCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "regcall";
  case 1:
    return "regcall";
  case 2:
    return "regcall";
  case 3:
    return "__regcall";
  }
}


// ReinitializesAttr implementation

ReinitializesAttr *ReinitializesAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReinitializesAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReinitializesAttr *ReinitializesAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReinitializesAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReinitializesAttr *ReinitializesAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ReinitializesAttr *ReinitializesAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ReinitializesAttr::ReinitializesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Reinitializes, false, false)
  {
}

ReinitializesAttr *ReinitializesAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReinitializesAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReinitializesAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((reinitializes";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::reinitializes";
    OS << "]]";
    break;
  }
}
}

const char *ReinitializesAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "reinitializes";
  case 1:
    return "reinitializes";
  }
}


// ReleaseCapabilityAttr implementation

ReleaseCapabilityAttr *ReleaseCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReleaseCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReleaseCapabilityAttr *ReleaseCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReleaseCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  return A;
}

ReleaseCapabilityAttr *ReleaseCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ReleaseCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

ReleaseCapabilityAttr *ReleaseCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, ReleaseCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Args, ArgsSize, I);
}

ReleaseCapabilityAttr::ReleaseCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ReleaseCapability, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

ReleaseCapabilityAttr::ReleaseCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ReleaseCapability, true, true)
              , args_Size(0), args_(nullptr)
  {
}

ReleaseCapabilityAttr::Spelling ReleaseCapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_release_capability;
    case 1: return CXX11_clang_release_capability;
    case 2: return GNU_release_shared_capability;
    case 3: return CXX11_clang_release_shared_capability;
    case 4: return GNU_release_generic_capability;
    case 5: return CXX11_clang_release_generic_capability;
    case 6: return GNU_unlock_function;
    case 7: return CXX11_clang_unlock_function;
  }
}


ReleaseCapabilityAttr *ReleaseCapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReleaseCapabilityAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReleaseCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((release_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::release_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((release_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::release_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " __attribute__((release_generic_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 5 : {
    OS << " [[clang::release_generic_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 6 : {
    OS << " __attribute__((unlock_function";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 7 : {
    OS << " [[clang::unlock_function";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ReleaseCapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "release_capability";
  case 1:
    return "release_capability";
  case 2:
    return "release_shared_capability";
  case 3:
    return "release_shared_capability";
  case 4:
    return "release_generic_capability";
  case 5:
    return "release_generic_capability";
  case 6:
    return "unlock_function";
  case 7:
    return "unlock_function";
  }
}


// ReleaseHandleAttr implementation

ReleaseHandleAttr *ReleaseHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReleaseHandleAttr(Ctx, CommonInfo, HandleType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReleaseHandleAttr *ReleaseHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReleaseHandleAttr(Ctx, CommonInfo, HandleType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReleaseHandleAttr *ReleaseHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, HandleType, I);
}

ReleaseHandleAttr *ReleaseHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, HandleType, I);
}

ReleaseHandleAttr::ReleaseHandleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef HandleType
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::ReleaseHandle, false, false)
              , handleTypeLength(HandleType.size()),handleType(new (Ctx, 1) char[handleTypeLength])
  {
    if (!HandleType.empty())
      std::memcpy(handleType, HandleType.data(), handleTypeLength);
}



ReleaseHandleAttr *ReleaseHandleAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReleaseHandleAttr(C, *this, getHandleType());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReleaseHandleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((release_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::release_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::release_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ReleaseHandleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "release_handle";
  case 1:
    return "release_handle";
  case 2:
    return "release_handle";
  }
}


// RenderScriptKernelAttr implementation

RenderScriptKernelAttr *RenderScriptKernelAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RenderScriptKernelAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RenderScriptKernelAttr *RenderScriptKernelAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RenderScriptKernelAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RenderScriptKernelAttr *RenderScriptKernelAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

RenderScriptKernelAttr *RenderScriptKernelAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

RenderScriptKernelAttr::RenderScriptKernelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::RenderScriptKernel, false)
  {
}

RenderScriptKernelAttr *RenderScriptKernelAttr::clone(ASTContext &C) const {
  auto *A = new (C) RenderScriptKernelAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RenderScriptKernelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((kernel";
    OS << "))";
    break;
  }
}
}

const char *RenderScriptKernelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "kernel";
  }
}


// ReqdWorkGroupSizeAttr implementation

ReqdWorkGroupSizeAttr *ReqdWorkGroupSizeAttr::CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReqdWorkGroupSizeAttr(Ctx, CommonInfo, XDim, YDim, ZDim);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReqdWorkGroupSizeAttr *ReqdWorkGroupSizeAttr::Create(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReqdWorkGroupSizeAttr(Ctx, CommonInfo, XDim, YDim, ZDim);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReqdWorkGroupSizeAttr *ReqdWorkGroupSizeAttr::CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, XDim, YDim, ZDim, I);
}

ReqdWorkGroupSizeAttr *ReqdWorkGroupSizeAttr::Create(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, XDim, YDim, ZDim, I);
}

ReqdWorkGroupSizeAttr::ReqdWorkGroupSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned XDim
              , unsigned YDim
              , unsigned ZDim
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ReqdWorkGroupSize, false, false)
              , xDim(XDim)
              , yDim(YDim)
              , zDim(ZDim)
  {
}







ReqdWorkGroupSizeAttr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReqdWorkGroupSizeAttr(C, *this, xDim, yDim, zDim);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReqdWorkGroupSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((reqd_work_group_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getXDim() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getYDim() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getZDim() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *ReqdWorkGroupSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "reqd_work_group_size";
  }
}


// RequiresCapabilityAttr implementation

RequiresCapabilityAttr *RequiresCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RequiresCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RequiresCapabilityAttr *RequiresCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RequiresCapabilityAttr(Ctx, CommonInfo, Args, ArgsSize);
  return A;
}

RequiresCapabilityAttr *RequiresCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, RequiresCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Args, ArgsSize, I);
}

RequiresCapabilityAttr *RequiresCapabilityAttr::Create(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, RequiresCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Args, ArgsSize, I);
}

RequiresCapabilityAttr::RequiresCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RequiresCapability, true, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

RequiresCapabilityAttr::RequiresCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RequiresCapability, true, true)
              , args_Size(0), args_(nullptr)
  {
}

RequiresCapabilityAttr::Spelling RequiresCapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_requires_capability;
    case 1: return CXX11_clang_requires_capability;
    case 2: return GNU_exclusive_locks_required;
    case 3: return CXX11_clang_exclusive_locks_required;
    case 4: return GNU_requires_shared_capability;
    case 5: return CXX11_clang_requires_shared_capability;
    case 6: return GNU_shared_locks_required;
    case 7: return CXX11_clang_shared_locks_required;
  }
}


RequiresCapabilityAttr *RequiresCapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) RequiresCapabilityAttr(C, *this, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RequiresCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((requires_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::requires_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((exclusive_locks_required";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::exclusive_locks_required";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " __attribute__((requires_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 5 : {
    OS << " [[clang::requires_shared_capability";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 6 : {
    OS << " __attribute__((shared_locks_required";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 7 : {
    OS << " [[clang::shared_locks_required";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *RequiresCapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "requires_capability";
  case 1:
    return "requires_capability";
  case 2:
    return "exclusive_locks_required";
  case 3:
    return "exclusive_locks_required";
  case 4:
    return "requires_shared_capability";
  case 5:
    return "requires_shared_capability";
  case 6:
    return "shared_locks_required";
  case 7:
    return "shared_locks_required";
  }
}


// RestrictAttr implementation

RestrictAttr *RestrictAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RestrictAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RestrictAttr *RestrictAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RestrictAttr(Ctx, CommonInfo);
  return A;
}

RestrictAttr *RestrictAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, RestrictAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

RestrictAttr *RestrictAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, RestrictAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

RestrictAttr::RestrictAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Restrict, false, false)
  {
}

RestrictAttr::Spelling RestrictAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Declspec_restrict;
    case 1: return GNU_malloc;
    case 2: return CXX11_gnu_malloc;
    case 3: return C2x_gnu_malloc;
  }
}
RestrictAttr *RestrictAttr::clone(ASTContext &C) const {
  auto *A = new (C) RestrictAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RestrictAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(restrict";
    OS << ")";
    break;
  }
  case 1 : {
    OS << " __attribute__((malloc";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::malloc";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::malloc";
    OS << "]]";
    break;
  }
}
}

const char *RestrictAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "restrict";
  case 1:
    return "malloc";
  case 2:
    return "malloc";
  case 3:
    return "malloc";
  }
}


// RetainAttr implementation

RetainAttr *RetainAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RetainAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RetainAttr *RetainAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RetainAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RetainAttr *RetainAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

RetainAttr *RetainAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

RetainAttr::RetainAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Retain, false, false)
  {
}

RetainAttr *RetainAttr::clone(ASTContext &C) const {
  auto *A = new (C) RetainAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RetainAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((retain";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::retain";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::retain";
    OS << "]]";
    break;
  }
}
}

const char *RetainAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "retain";
  case 1:
    return "retain";
  case 2:
    return "retain";
  }
}


// ReturnTypestateAttr implementation

ReturnTypestateAttr *ReturnTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState State, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReturnTypestateAttr(Ctx, CommonInfo, State);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReturnTypestateAttr *ReturnTypestateAttr::Create(ASTContext &Ctx, ConsumedState State, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReturnTypestateAttr(Ctx, CommonInfo, State);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReturnTypestateAttr *ReturnTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState State, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, State, I);
}

ReturnTypestateAttr *ReturnTypestateAttr::Create(ASTContext &Ctx, ConsumedState State, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, State, I);
}

ReturnTypestateAttr::ReturnTypestateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState State
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ReturnTypestate, false, false)
              , state(State)
  {
}



bool ReturnTypestateAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("unknown", ReturnTypestateAttr::Unknown)
    .Case("consumed", ReturnTypestateAttr::Consumed)
    .Case("unconsumed", ReturnTypestateAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ReturnTypestateAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case ReturnTypestateAttr::Unknown: return "unknown";
  case ReturnTypestateAttr::Consumed: return "consumed";
  case ReturnTypestateAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
ReturnTypestateAttr *ReturnTypestateAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReturnTypestateAttr(C, *this, state);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReturnTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((return_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ReturnTypestateAttr::ConvertConsumedStateToStr(getState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::return_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ReturnTypestateAttr::ConvertConsumedStateToStr(getState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ReturnTypestateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "return_typestate";
  case 1:
    return "return_typestate";
  }
}


// ReturnsNonNullAttr implementation

ReturnsNonNullAttr *ReturnsNonNullAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReturnsNonNullAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReturnsNonNullAttr *ReturnsNonNullAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReturnsNonNullAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReturnsNonNullAttr *ReturnsNonNullAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ReturnsNonNullAttr *ReturnsNonNullAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ReturnsNonNullAttr::ReturnsNonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ReturnsNonNull, false, false)
  {
}

ReturnsNonNullAttr *ReturnsNonNullAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReturnsNonNullAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReturnsNonNullAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((returns_nonnull";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::returns_nonnull";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::returns_nonnull";
    OS << "]]";
    break;
  }
}
}

const char *ReturnsNonNullAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "returns_nonnull";
  case 1:
    return "returns_nonnull";
  case 2:
    return "returns_nonnull";
  }
}


// ReturnsTwiceAttr implementation

ReturnsTwiceAttr *ReturnsTwiceAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReturnsTwiceAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReturnsTwiceAttr *ReturnsTwiceAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ReturnsTwiceAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ReturnsTwiceAttr *ReturnsTwiceAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ReturnsTwiceAttr *ReturnsTwiceAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ReturnsTwiceAttr::ReturnsTwiceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ReturnsTwice, false, false)
  {
}

ReturnsTwiceAttr *ReturnsTwiceAttr::clone(ASTContext &C) const {
  auto *A = new (C) ReturnsTwiceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ReturnsTwiceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((returns_twice";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::returns_twice";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::returns_twice";
    OS << "]]";
    break;
  }
}
}

const char *ReturnsTwiceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "returns_twice";
  case 1:
    return "returns_twice";
  case 2:
    return "returns_twice";
  }
}


// SPtrAttr implementation

SPtrAttr *SPtrAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SPtrAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SPtrAttr *SPtrAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SPtrAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SPtrAttr *SPtrAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SPtrAttr *SPtrAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SPtrAttr::SPtrAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::SPtr, false)
  {
}

SPtrAttr *SPtrAttr::clone(ASTContext &C) const {
  auto *A = new (C) SPtrAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SPtrAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __sptr";
    OS << "";
    break;
  }
}
}

const char *SPtrAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__sptr";
  }
}


// SYCLKernelAttr implementation

SYCLKernelAttr *SYCLKernelAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SYCLKernelAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SYCLKernelAttr *SYCLKernelAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SYCLKernelAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SYCLKernelAttr *SYCLKernelAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SYCLKernelAttr *SYCLKernelAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SYCLKernelAttr::SYCLKernelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SYCLKernel, false, false)
  {
}

SYCLKernelAttr *SYCLKernelAttr::clone(ASTContext &C) const {
  auto *A = new (C) SYCLKernelAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SYCLKernelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((sycl_kernel";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::sycl_kernel";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::sycl_kernel";
    OS << "]]";
    break;
  }
}
}

const char *SYCLKernelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "sycl_kernel";
  case 1:
    return "sycl_kernel";
  case 2:
    return "sycl_kernel";
  }
}


// SYCLSpecialClassAttr implementation

SYCLSpecialClassAttr *SYCLSpecialClassAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SYCLSpecialClassAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SYCLSpecialClassAttr *SYCLSpecialClassAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SYCLSpecialClassAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SYCLSpecialClassAttr *SYCLSpecialClassAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SYCLSpecialClassAttr *SYCLSpecialClassAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SYCLSpecialClassAttr::SYCLSpecialClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SYCLSpecialClass, false, false)
  {
}

SYCLSpecialClassAttr *SYCLSpecialClassAttr::clone(ASTContext &C) const {
  auto *A = new (C) SYCLSpecialClassAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SYCLSpecialClassAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((sycl_special_class";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::sycl_special_class";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::sycl_special_class";
    OS << "]]";
    break;
  }
}
}

const char *SYCLSpecialClassAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "sycl_special_class";
  case 1:
    return "sycl_special_class";
  case 2:
    return "sycl_special_class";
  }
}


// ScopedLockableAttr implementation

ScopedLockableAttr *ScopedLockableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ScopedLockableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ScopedLockableAttr *ScopedLockableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ScopedLockableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ScopedLockableAttr *ScopedLockableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ScopedLockableAttr *ScopedLockableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ScopedLockableAttr::ScopedLockableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ScopedLockable, false, false)
  {
}

ScopedLockableAttr *ScopedLockableAttr::clone(ASTContext &C) const {
  auto *A = new (C) ScopedLockableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ScopedLockableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((scoped_lockable";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::scoped_lockable";
    OS << "]]";
    break;
  }
}
}

const char *ScopedLockableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "scoped_lockable";
  case 1:
    return "scoped_lockable";
  }
}


// SectionAttr implementation

SectionAttr *SectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SectionAttr *SectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SectionAttr(Ctx, CommonInfo, Name);
  return A;
}

SectionAttr *SectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax, SectionAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Name, I);
}

SectionAttr *SectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax, SectionAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Name, I);
}

SectionAttr::SectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Section, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}

SectionAttr::Spelling SectionAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_section;
    case 1: return CXX11_gnu_section;
    case 2: return C2x_gnu_section;
    case 3: return Declspec_allocate;
  }
}


SectionAttr *SectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) SectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((section";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::section";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::section";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __declspec(allocate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
}
}

const char *SectionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "section";
  case 1:
    return "section";
  case 2:
    return "section";
  case 3:
    return "allocate";
  }
}


// SelectAnyAttr implementation

SelectAnyAttr *SelectAnyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SelectAnyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SelectAnyAttr *SelectAnyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SelectAnyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SelectAnyAttr *SelectAnyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SelectAnyAttr *SelectAnyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SelectAnyAttr::SelectAnyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SelectAny, false, false)
  {
}

SelectAnyAttr *SelectAnyAttr::clone(ASTContext &C) const {
  auto *A = new (C) SelectAnyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SelectAnyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(selectany";
    OS << ")";
    break;
  }
  case 1 : {
    OS << " __attribute__((selectany";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::selectany";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::selectany";
    OS << "]]";
    break;
  }
}
}

const char *SelectAnyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "selectany";
  case 1:
    return "selectany";
  case 2:
    return "selectany";
  case 3:
    return "selectany";
  }
}


// SentinelAttr implementation

SentinelAttr *SentinelAttr::CreateImplicit(ASTContext &Ctx, int Sentinel, int NullPos, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SentinelAttr(Ctx, CommonInfo, Sentinel, NullPos);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SentinelAttr *SentinelAttr::Create(ASTContext &Ctx, int Sentinel, int NullPos, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SentinelAttr(Ctx, CommonInfo, Sentinel, NullPos);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SentinelAttr *SentinelAttr::CreateImplicit(ASTContext &Ctx, int Sentinel, int NullPos, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Sentinel, NullPos, I);
}

SentinelAttr *SentinelAttr::Create(ASTContext &Ctx, int Sentinel, int NullPos, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Sentinel, NullPos, I);
}

SentinelAttr::SentinelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int Sentinel
              , int NullPos
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Sentinel, false, false)
              , sentinel(Sentinel)
              , nullPos(NullPos)
  {
}

SentinelAttr::SentinelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Sentinel, false, false)
              , sentinel()
              , nullPos()
  {
}





SentinelAttr *SentinelAttr::clone(ASTContext &C) const {
  auto *A = new (C) SentinelAttr(C, *this, sentinel, nullPos);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SentinelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((sentinel";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSentinel() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNullPos() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::sentinel";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSentinel() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNullPos() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::sentinel";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSentinel() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getNullPos() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *SentinelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "sentinel";
  case 1:
    return "sentinel";
  case 2:
    return "sentinel";
  }
}


// SetTypestateAttr implementation

SetTypestateAttr *SetTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState NewState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SetTypestateAttr(Ctx, CommonInfo, NewState);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SetTypestateAttr *SetTypestateAttr::Create(ASTContext &Ctx, ConsumedState NewState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SetTypestateAttr(Ctx, CommonInfo, NewState);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SetTypestateAttr *SetTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState NewState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, NewState, I);
}

SetTypestateAttr *SetTypestateAttr::Create(ASTContext &Ctx, ConsumedState NewState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, NewState, I);
}

SetTypestateAttr::SetTypestateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState NewState
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SetTypestate, false, false)
              , newState(NewState)
  {
}



bool SetTypestateAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("unknown", SetTypestateAttr::Unknown)
    .Case("consumed", SetTypestateAttr::Consumed)
    .Case("unconsumed", SetTypestateAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SetTypestateAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case SetTypestateAttr::Unknown: return "unknown";
  case SetTypestateAttr::Consumed: return "consumed";
  case SetTypestateAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
SetTypestateAttr *SetTypestateAttr::clone(ASTContext &C) const {
  auto *A = new (C) SetTypestateAttr(C, *this, newState);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SetTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((set_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SetTypestateAttr::ConvertConsumedStateToStr(getNewState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::set_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SetTypestateAttr::ConvertConsumedStateToStr(getNewState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *SetTypestateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "set_typestate";
  case 1:
    return "set_typestate";
  }
}


// SharedTrylockFunctionAttr implementation

SharedTrylockFunctionAttr *SharedTrylockFunctionAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SharedTrylockFunctionAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SharedTrylockFunctionAttr *SharedTrylockFunctionAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SharedTrylockFunctionAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SharedTrylockFunctionAttr *SharedTrylockFunctionAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, SuccessValue, Args, ArgsSize, I);
}

SharedTrylockFunctionAttr *SharedTrylockFunctionAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, SuccessValue, Args, ArgsSize, I);
}

SharedTrylockFunctionAttr::SharedTrylockFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SharedTrylockFunction, true, true)
              , successValue(SuccessValue)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

SharedTrylockFunctionAttr::SharedTrylockFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SharedTrylockFunction, true, true)
              , successValue(SuccessValue)
              , args_Size(0), args_(nullptr)
  {
}





SharedTrylockFunctionAttr *SharedTrylockFunctionAttr::clone(ASTContext &C) const {
  auto *A = new (C) SharedTrylockFunctionAttr(C, *this, successValue, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SharedTrylockFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((shared_trylock_function";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SharedTrylockFunctionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "shared_trylock_function";
  }
}


// SpeculativeLoadHardeningAttr implementation

SpeculativeLoadHardeningAttr *SpeculativeLoadHardeningAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SpeculativeLoadHardeningAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SpeculativeLoadHardeningAttr *SpeculativeLoadHardeningAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SpeculativeLoadHardeningAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SpeculativeLoadHardeningAttr *SpeculativeLoadHardeningAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SpeculativeLoadHardeningAttr *SpeculativeLoadHardeningAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SpeculativeLoadHardeningAttr::SpeculativeLoadHardeningAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SpeculativeLoadHardening, false, false)
  {
}

SpeculativeLoadHardeningAttr *SpeculativeLoadHardeningAttr::clone(ASTContext &C) const {
  auto *A = new (C) SpeculativeLoadHardeningAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SpeculativeLoadHardeningAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((speculative_load_hardening";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::speculative_load_hardening";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::speculative_load_hardening";
    OS << "]]";
    break;
  }
}
}

const char *SpeculativeLoadHardeningAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "speculative_load_hardening";
  case 1:
    return "speculative_load_hardening";
  case 2:
    return "speculative_load_hardening";
  }
}


// StandaloneDebugAttr implementation

StandaloneDebugAttr *StandaloneDebugAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StandaloneDebugAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StandaloneDebugAttr *StandaloneDebugAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StandaloneDebugAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StandaloneDebugAttr *StandaloneDebugAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

StandaloneDebugAttr *StandaloneDebugAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

StandaloneDebugAttr::StandaloneDebugAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::StandaloneDebug, false, false)
  {
}

StandaloneDebugAttr *StandaloneDebugAttr::clone(ASTContext &C) const {
  auto *A = new (C) StandaloneDebugAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void StandaloneDebugAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((standalone_debug";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::standalone_debug";
    OS << "]]";
    break;
  }
}
}

const char *StandaloneDebugAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "standalone_debug";
  case 1:
    return "standalone_debug";
  }
}


// StdCallAttr implementation

StdCallAttr *StdCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StdCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StdCallAttr *StdCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StdCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StdCallAttr *StdCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

StdCallAttr *StdCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

StdCallAttr::StdCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::StdCall, false, false)
  {
}

StdCallAttr *StdCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) StdCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void StdCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((stdcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::stdcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::stdcall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __stdcall";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _stdcall";
    OS << "";
    break;
  }
}
}

const char *StdCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "stdcall";
  case 1:
    return "stdcall";
  case 2:
    return "stdcall";
  case 3:
    return "__stdcall";
  case 4:
    return "_stdcall";
  }
}


// StrictFPAttr implementation

StrictFPAttr *StrictFPAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StrictFPAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StrictFPAttr *StrictFPAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StrictFPAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StrictFPAttr *StrictFPAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

StrictFPAttr *StrictFPAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

StrictFPAttr::StrictFPAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::StrictFP, false, false)
  {
}

StrictFPAttr *StrictFPAttr::clone(ASTContext &C) const {
  auto *A = new (C) StrictFPAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void StrictFPAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *StrictFPAttr::getSpelling() const {
  return "(No spelling)";
}


// StrictGuardStackCheckAttr implementation

StrictGuardStackCheckAttr *StrictGuardStackCheckAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StrictGuardStackCheckAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StrictGuardStackCheckAttr *StrictGuardStackCheckAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) StrictGuardStackCheckAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

StrictGuardStackCheckAttr *StrictGuardStackCheckAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

StrictGuardStackCheckAttr *StrictGuardStackCheckAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

StrictGuardStackCheckAttr::StrictGuardStackCheckAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::StrictGuardStackCheck, false, false)
  {
}

StrictGuardStackCheckAttr *StrictGuardStackCheckAttr::clone(ASTContext &C) const {
  auto *A = new (C) StrictGuardStackCheckAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void StrictGuardStackCheckAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(strict_gs_check";
    OS << ")";
    break;
  }
}
}

const char *StrictGuardStackCheckAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "strict_gs_check";
  }
}


// SuppressAttr implementation

SuppressAttr *SuppressAttr::CreateImplicit(ASTContext &Ctx, StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SuppressAttr(Ctx, CommonInfo, DiagnosticIdentifiers, DiagnosticIdentifiersSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SuppressAttr *SuppressAttr::Create(ASTContext &Ctx, StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SuppressAttr(Ctx, CommonInfo, DiagnosticIdentifiers, DiagnosticIdentifiersSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SuppressAttr *SuppressAttr::CreateImplicit(ASTContext &Ctx, StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, DiagnosticIdentifiers, DiagnosticIdentifiersSize, I);
}

SuppressAttr *SuppressAttr::Create(ASTContext &Ctx, StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, DiagnosticIdentifiers, DiagnosticIdentifiersSize, I);
}

SuppressAttr::SuppressAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize
             )
  : StmtAttr(Ctx, CommonInfo, attr::Suppress, false)
              , diagnosticIdentifiers_Size(DiagnosticIdentifiersSize), diagnosticIdentifiers_(new (Ctx, 16) StringRef[diagnosticIdentifiers_Size])
  {
  for (size_t I = 0, E = diagnosticIdentifiers_Size; I != E;
       ++I) {
    StringRef Ref = DiagnosticIdentifiers[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      diagnosticIdentifiers_[I] = StringRef(Mem, Ref.size());
    }
  }
}

SuppressAttr::SuppressAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::Suppress, false)
              , diagnosticIdentifiers_Size(0), diagnosticIdentifiers_(nullptr)
  {
}



SuppressAttr *SuppressAttr::clone(ASTContext &C) const {
  auto *A = new (C) SuppressAttr(C, *this, diagnosticIdentifiers_, diagnosticIdentifiers_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SuppressAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[gsl::suppress";
    OS << "";
  for (const auto &Val : diagnosticIdentifiers()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *SuppressAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "suppress";
  }
}


// SwiftAsyncAttr implementation

SwiftAsyncAttr *SwiftAsyncAttr::CreateImplicit(ASTContext &Ctx, Kind Kind, ParamIdx CompletionHandlerIndex, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncAttr(Ctx, CommonInfo, Kind, CompletionHandlerIndex);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncAttr *SwiftAsyncAttr::Create(ASTContext &Ctx, Kind Kind, ParamIdx CompletionHandlerIndex, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncAttr(Ctx, CommonInfo, Kind, CompletionHandlerIndex);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncAttr *SwiftAsyncAttr::CreateImplicit(ASTContext &Ctx, Kind Kind, ParamIdx CompletionHandlerIndex, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Kind, CompletionHandlerIndex, I);
}

SwiftAsyncAttr *SwiftAsyncAttr::Create(ASTContext &Ctx, Kind Kind, ParamIdx CompletionHandlerIndex, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Kind, CompletionHandlerIndex, I);
}

SwiftAsyncAttr::SwiftAsyncAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Kind Kind
              , ParamIdx CompletionHandlerIndex
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsync, false, false)
              , kind(Kind)
              , completionHandlerIndex(CompletionHandlerIndex)
  {
}

SwiftAsyncAttr::SwiftAsyncAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Kind Kind
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsync, false, false)
              , kind(Kind)
              , completionHandlerIndex()
  {
}



bool SwiftAsyncAttr::ConvertStrToKind(StringRef Val, Kind &Out) {
  Optional<Kind> R = llvm::StringSwitch<Optional<Kind>>(Val)
    .Case("none", SwiftAsyncAttr::None)
    .Case("swift_private", SwiftAsyncAttr::SwiftPrivate)
    .Case("not_swift_private", SwiftAsyncAttr::NotSwiftPrivate)
    .Default(Optional<Kind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftAsyncAttr::ConvertKindToStr(Kind Val) {
  switch(Val) {
  case SwiftAsyncAttr::None: return "none";
  case SwiftAsyncAttr::SwiftPrivate: return "swift_private";
  case SwiftAsyncAttr::NotSwiftPrivate: return "not_swift_private";
  }
  llvm_unreachable("No enumerator with that value");
}


SwiftAsyncAttr *SwiftAsyncAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncAttr(C, *this, kind, completionHandlerIndex);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async";
    if (!getCompletionHandlerIndex().isValid())
      ++TrailingOmittedArgs;
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncAttr::ConvertKindToStr(getKind()) << "\"";
    if (!(!getCompletionHandlerIndex().isValid())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCompletionHandlerIndex().getSourceIndex() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_async";
    if (!getCompletionHandlerIndex().isValid())
      ++TrailingOmittedArgs;
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncAttr::ConvertKindToStr(getKind()) << "\"";
    if (!(!getCompletionHandlerIndex().isValid())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCompletionHandlerIndex().getSourceIndex() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_async";
    if (!getCompletionHandlerIndex().isValid())
      ++TrailingOmittedArgs;
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncAttr::ConvertKindToStr(getKind()) << "\"";
    if (!(!getCompletionHandlerIndex().isValid())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCompletionHandlerIndex().getSourceIndex() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async";
  case 1:
    return "swift_async";
  case 2:
    return "swift_async";
  }
}


// SwiftAsyncCallAttr implementation

SwiftAsyncCallAttr *SwiftAsyncCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftAsyncCallAttr::SwiftAsyncCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncCall, false, false)
  {
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swiftasynccall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swiftasynccall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swiftasynccall";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swiftasynccall";
  case 1:
    return "swiftasynccall";
  case 2:
    return "swiftasynccall";
  }
}


// SwiftAsyncContextAttr implementation

SwiftAsyncContextAttr *SwiftAsyncContextAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncContextAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncContextAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftAsyncContextAttr::SwiftAsyncContextAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftAsyncContext, false, false)
  {
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncContextAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncContextAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async_context";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_async_context";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_async_context";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncContextAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async_context";
  case 1:
    return "swift_async_context";
  case 2:
    return "swift_async_context";
  }
}


// SwiftAsyncErrorAttr implementation

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncErrorAttr(Ctx, CommonInfo, Convention, HandlerParamIdx);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncErrorAttr(Ctx, CommonInfo, Convention, HandlerParamIdx);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Convention, HandlerParamIdx, I);
}

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Convention, HandlerParamIdx, I);
}

SwiftAsyncErrorAttr::SwiftAsyncErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConventionKind Convention
              , unsigned HandlerParamIdx
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncError, false, false)
              , convention(Convention)
              , handlerParamIdx(HandlerParamIdx)
  {
}

SwiftAsyncErrorAttr::SwiftAsyncErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConventionKind Convention
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncError, false, false)
              , convention(Convention)
              , handlerParamIdx()
  {
}



bool SwiftAsyncErrorAttr::ConvertStrToConventionKind(StringRef Val, ConventionKind &Out) {
  Optional<ConventionKind> R = llvm::StringSwitch<Optional<ConventionKind>>(Val)
    .Case("none", SwiftAsyncErrorAttr::None)
    .Case("nonnull_error", SwiftAsyncErrorAttr::NonNullError)
    .Case("zero_argument", SwiftAsyncErrorAttr::ZeroArgument)
    .Case("nonzero_argument", SwiftAsyncErrorAttr::NonZeroArgument)
    .Default(Optional<ConventionKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftAsyncErrorAttr::ConvertConventionKindToStr(ConventionKind Val) {
  switch(Val) {
  case SwiftAsyncErrorAttr::None: return "none";
  case SwiftAsyncErrorAttr::NonNullError: return "nonnull_error";
  case SwiftAsyncErrorAttr::ZeroArgument: return "zero_argument";
  case SwiftAsyncErrorAttr::NonZeroArgument: return "nonzero_argument";
  }
  llvm_unreachable("No enumerator with that value");
}


SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncErrorAttr(C, *this, convention, handlerParamIdx);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncErrorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getHandlerParamIdx() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_async_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getHandlerParamIdx() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_async_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getHandlerParamIdx() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncErrorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async_error";
  case 1:
    return "swift_async_error";
  case 2:
    return "swift_async_error";
  }
}


// SwiftAsyncNameAttr implementation

SwiftAsyncNameAttr *SwiftAsyncNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncNameAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncNameAttr *SwiftAsyncNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncNameAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncNameAttr *SwiftAsyncNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

SwiftAsyncNameAttr *SwiftAsyncNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

SwiftAsyncNameAttr::SwiftAsyncNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncName, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



SwiftAsyncNameAttr *SwiftAsyncNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncNameAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftAsyncNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async_name";
  }
}


// SwiftAttrAttr implementation

SwiftAttrAttr *SwiftAttrAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Attribute, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAttrAttr(Ctx, CommonInfo, Attribute);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAttrAttr *SwiftAttrAttr::Create(ASTContext &Ctx, llvm::StringRef Attribute, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAttrAttr(Ctx, CommonInfo, Attribute);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAttrAttr *SwiftAttrAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Attribute, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Attribute, I);
}

SwiftAttrAttr *SwiftAttrAttr::Create(ASTContext &Ctx, llvm::StringRef Attribute, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Attribute, I);
}

SwiftAttrAttr::SwiftAttrAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Attribute
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAttr, false, false)
              , attributeLength(Attribute.size()),attribute(new (Ctx, 1) char[attributeLength])
  {
    if (!Attribute.empty())
      std::memcpy(attribute, Attribute.data(), attributeLength);
}



SwiftAttrAttr *SwiftAttrAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAttrAttr(C, *this, getAttribute());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAttrAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_attr";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAttribute() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftAttrAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_attr";
  }
}


// SwiftBridgeAttr implementation

SwiftBridgeAttr *SwiftBridgeAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef SwiftType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgeAttr(Ctx, CommonInfo, SwiftType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgeAttr *SwiftBridgeAttr::Create(ASTContext &Ctx, llvm::StringRef SwiftType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgeAttr(Ctx, CommonInfo, SwiftType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgeAttr *SwiftBridgeAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef SwiftType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, SwiftType, I);
}

SwiftBridgeAttr *SwiftBridgeAttr::Create(ASTContext &Ctx, llvm::StringRef SwiftType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, SwiftType, I);
}

SwiftBridgeAttr::SwiftBridgeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef SwiftType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftBridge, false, false)
              , swiftTypeLength(SwiftType.size()),swiftType(new (Ctx, 1) char[swiftTypeLength])
  {
    if (!SwiftType.empty())
      std::memcpy(swiftType, SwiftType.data(), swiftTypeLength);
}



SwiftBridgeAttr *SwiftBridgeAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftBridgeAttr(C, *this, getSwiftType());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftBridgeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_bridge";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getSwiftType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftBridgeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_bridge";
  }
}


// SwiftBridgedTypedefAttr implementation

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgedTypedefAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgedTypedefAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftBridgedTypedefAttr::SwiftBridgedTypedefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftBridgedTypedef, false, false)
  {
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftBridgedTypedefAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftBridgedTypedefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_bridged_typedef";
    OS << "))";
    break;
  }
}
}

const char *SwiftBridgedTypedefAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_bridged_typedef";
  }
}


// SwiftCallAttr implementation

SwiftCallAttr *SwiftCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftCallAttr *SwiftCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftCallAttr *SwiftCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftCallAttr *SwiftCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftCallAttr::SwiftCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftCall, false, false)
  {
}

SwiftCallAttr *SwiftCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swiftcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swiftcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swiftcall";
    OS << "]]";
    break;
  }
}
}

const char *SwiftCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swiftcall";
  case 1:
    return "swiftcall";
  case 2:
    return "swiftcall";
  }
}


// SwiftContextAttr implementation

SwiftContextAttr *SwiftContextAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftContextAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftContextAttr *SwiftContextAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftContextAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftContextAttr *SwiftContextAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftContextAttr *SwiftContextAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftContextAttr::SwiftContextAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftContext, false, false)
  {
}

SwiftContextAttr *SwiftContextAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftContextAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftContextAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_context";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_context";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_context";
    OS << "]]";
    break;
  }
}
}

const char *SwiftContextAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_context";
  case 1:
    return "swift_context";
  case 2:
    return "swift_context";
  }
}


// SwiftErrorAttr implementation

SwiftErrorAttr *SwiftErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorAttr(Ctx, CommonInfo, Convention);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorAttr *SwiftErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorAttr(Ctx, CommonInfo, Convention);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorAttr *SwiftErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Convention, I);
}

SwiftErrorAttr *SwiftErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Convention, I);
}

SwiftErrorAttr::SwiftErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConventionKind Convention
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftError, false, false)
              , convention(Convention)
  {
}



bool SwiftErrorAttr::ConvertStrToConventionKind(StringRef Val, ConventionKind &Out) {
  Optional<ConventionKind> R = llvm::StringSwitch<Optional<ConventionKind>>(Val)
    .Case("none", SwiftErrorAttr::None)
    .Case("nonnull_error", SwiftErrorAttr::NonNullError)
    .Case("null_result", SwiftErrorAttr::NullResult)
    .Case("zero_result", SwiftErrorAttr::ZeroResult)
    .Case("nonzero_result", SwiftErrorAttr::NonZeroResult)
    .Default(Optional<ConventionKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftErrorAttr::ConvertConventionKindToStr(ConventionKind Val) {
  switch(Val) {
  case SwiftErrorAttr::None: return "none";
  case SwiftErrorAttr::NonNullError: return "nonnull_error";
  case SwiftErrorAttr::NullResult: return "null_result";
  case SwiftErrorAttr::ZeroResult: return "zero_result";
  case SwiftErrorAttr::NonZeroResult: return "nonzero_result";
  }
  llvm_unreachable("No enumerator with that value");
}
SwiftErrorAttr *SwiftErrorAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftErrorAttr(C, *this, convention);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftErrorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftErrorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_error";
  }
}


// SwiftErrorResultAttr implementation

SwiftErrorResultAttr *SwiftErrorResultAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorResultAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorResultAttr *SwiftErrorResultAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorResultAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorResultAttr *SwiftErrorResultAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftErrorResultAttr *SwiftErrorResultAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftErrorResultAttr::SwiftErrorResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftErrorResult, false, false)
  {
}

SwiftErrorResultAttr *SwiftErrorResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftErrorResultAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftErrorResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_error_result";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_error_result";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_error_result";
    OS << "]]";
    break;
  }
}
}

const char *SwiftErrorResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_error_result";
  case 1:
    return "swift_error_result";
  case 2:
    return "swift_error_result";
  }
}


// SwiftIndirectResultAttr implementation

SwiftIndirectResultAttr *SwiftIndirectResultAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftIndirectResultAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftIndirectResultAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftIndirectResultAttr::SwiftIndirectResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftIndirectResult, false, false)
  {
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftIndirectResultAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftIndirectResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_indirect_result";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_indirect_result";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_indirect_result";
    OS << "]]";
    break;
  }
}
}

const char *SwiftIndirectResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_indirect_result";
  case 1:
    return "swift_indirect_result";
  case 2:
    return "swift_indirect_result";
  }
}


// SwiftNameAttr implementation

SwiftNameAttr *SwiftNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNameAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftNameAttr *SwiftNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNameAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftNameAttr *SwiftNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

SwiftNameAttr *SwiftNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

SwiftNameAttr::SwiftNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftName, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



SwiftNameAttr *SwiftNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftNameAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_name";
  }
}


// SwiftNewTypeAttr implementation

SwiftNewTypeAttr *SwiftNewTypeAttr::CreateImplicit(ASTContext &Ctx, NewtypeKind NewtypeKind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNewTypeAttr(Ctx, CommonInfo, NewtypeKind);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftNewTypeAttr *SwiftNewTypeAttr::Create(ASTContext &Ctx, NewtypeKind NewtypeKind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNewTypeAttr(Ctx, CommonInfo, NewtypeKind);
  return A;
}

SwiftNewTypeAttr *SwiftNewTypeAttr::CreateImplicit(ASTContext &Ctx, NewtypeKind NewtypeKind, SourceRange Range, AttributeCommonInfo::Syntax Syntax, SwiftNewTypeAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, NewtypeKind, I);
}

SwiftNewTypeAttr *SwiftNewTypeAttr::Create(ASTContext &Ctx, NewtypeKind NewtypeKind, SourceRange Range, AttributeCommonInfo::Syntax Syntax, SwiftNewTypeAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, NewtypeKind, I);
}

SwiftNewTypeAttr::SwiftNewTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , NewtypeKind NewtypeKind
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftNewType, false, false)
              , newtypeKind(NewtypeKind)
  {
}

SwiftNewTypeAttr::Spelling SwiftNewTypeAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_swift_newtype;
    case 1: return GNU_swift_wrapper;
  }
}


bool SwiftNewTypeAttr::ConvertStrToNewtypeKind(StringRef Val, NewtypeKind &Out) {
  Optional<NewtypeKind> R = llvm::StringSwitch<Optional<NewtypeKind>>(Val)
    .Case("struct", SwiftNewTypeAttr::NK_Struct)
    .Case("enum", SwiftNewTypeAttr::NK_Enum)
    .Default(Optional<NewtypeKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftNewTypeAttr::ConvertNewtypeKindToStr(NewtypeKind Val) {
  switch(Val) {
  case SwiftNewTypeAttr::NK_Struct: return "struct";
  case SwiftNewTypeAttr::NK_Enum: return "enum";
  }
  llvm_unreachable("No enumerator with that value");
}
SwiftNewTypeAttr *SwiftNewTypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftNewTypeAttr(C, *this, newtypeKind);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftNewTypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_newtype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftNewTypeAttr::ConvertNewtypeKindToStr(getNewtypeKind()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __attribute__((swift_wrapper";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftNewTypeAttr::ConvertNewtypeKindToStr(getNewtypeKind()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftNewTypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_newtype";
  case 1:
    return "swift_wrapper";
  }
}


// SwiftObjCMembersAttr implementation

SwiftObjCMembersAttr *SwiftObjCMembersAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftObjCMembersAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftObjCMembersAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftObjCMembersAttr::SwiftObjCMembersAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::SwiftObjCMembers, false)
  {
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftObjCMembersAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftObjCMembersAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_objc_members";
    OS << "))";
    break;
  }
}
}

const char *SwiftObjCMembersAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_objc_members";
  }
}


// SwiftPrivateAttr implementation

SwiftPrivateAttr *SwiftPrivateAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftPrivateAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftPrivateAttr *SwiftPrivateAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftPrivateAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftPrivateAttr *SwiftPrivateAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftPrivateAttr *SwiftPrivateAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftPrivateAttr::SwiftPrivateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftPrivate, false, false)
  {
}

SwiftPrivateAttr *SwiftPrivateAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftPrivateAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftPrivateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_private";
    OS << "))";
    break;
  }
}
}

const char *SwiftPrivateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_private";
  }
}


// SysVABIAttr implementation

SysVABIAttr *SysVABIAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SysVABIAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SysVABIAttr *SysVABIAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SysVABIAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SysVABIAttr *SysVABIAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SysVABIAttr *SysVABIAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SysVABIAttr::SysVABIAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SysVABI, false, false)
  {
}

SysVABIAttr *SysVABIAttr::clone(ASTContext &C) const {
  auto *A = new (C) SysVABIAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SysVABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((sysv_abi";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::sysv_abi";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::sysv_abi";
    OS << "]]";
    break;
  }
}
}

const char *SysVABIAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "sysv_abi";
  case 1:
    return "sysv_abi";
  case 2:
    return "sysv_abi";
  }
}


// TLSModelAttr implementation

TLSModelAttr *TLSModelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TLSModelAttr(Ctx, CommonInfo, Model);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TLSModelAttr *TLSModelAttr::Create(ASTContext &Ctx, llvm::StringRef Model, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TLSModelAttr(Ctx, CommonInfo, Model);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TLSModelAttr *TLSModelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Model, I);
}

TLSModelAttr *TLSModelAttr::Create(ASTContext &Ctx, llvm::StringRef Model, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Model, I);
}

TLSModelAttr::TLSModelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Model
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TLSModel, false, false)
              , modelLength(Model.size()),model(new (Ctx, 1) char[modelLength])
  {
    if (!Model.empty())
      std::memcpy(model, Model.data(), modelLength);
}



TLSModelAttr *TLSModelAttr::clone(ASTContext &C) const {
  auto *A = new (C) TLSModelAttr(C, *this, getModel());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TLSModelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((tls_model";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getModel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::tls_model";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getModel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::tls_model";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getModel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TLSModelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "tls_model";
  case 1:
    return "tls_model";
  case 2:
    return "tls_model";
  }
}


// TargetAttr implementation

TargetAttr *TargetAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef FeaturesStr, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetAttr(Ctx, CommonInfo, FeaturesStr);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetAttr *TargetAttr::Create(ASTContext &Ctx, llvm::StringRef FeaturesStr, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetAttr(Ctx, CommonInfo, FeaturesStr);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetAttr *TargetAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef FeaturesStr, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, FeaturesStr, I);
}

TargetAttr *TargetAttr::Create(ASTContext &Ctx, llvm::StringRef FeaturesStr, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, FeaturesStr, I);
}

TargetAttr::TargetAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef FeaturesStr
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Target, false, false)
              , featuresStrLength(FeaturesStr.size()),featuresStr(new (Ctx, 1) char[featuresStrLength])
  {
    if (!FeaturesStr.empty())
      std::memcpy(featuresStr, FeaturesStr.data(), featuresStrLength);
}



TargetAttr *TargetAttr::clone(ASTContext &C) const {
  auto *A = new (C) TargetAttr(C, *this, getFeaturesStr());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TargetAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((target";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getFeaturesStr() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::target";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getFeaturesStr() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::target";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getFeaturesStr() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TargetAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "target";
  case 1:
    return "target";
  case 2:
    return "target";
  }
}


// TargetClonesAttr implementation

TargetClonesAttr *TargetClonesAttr::CreateImplicit(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetClonesAttr(Ctx, CommonInfo, FeaturesStrs, FeaturesStrsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetClonesAttr *TargetClonesAttr::Create(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetClonesAttr(Ctx, CommonInfo, FeaturesStrs, FeaturesStrsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetClonesAttr *TargetClonesAttr::CreateImplicit(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, FeaturesStrs, FeaturesStrsSize, I);
}

TargetClonesAttr *TargetClonesAttr::Create(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, FeaturesStrs, FeaturesStrsSize, I);
}

TargetClonesAttr::TargetClonesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *FeaturesStrs, unsigned FeaturesStrsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TargetClones, false, false)
              , featuresStrs_Size(FeaturesStrsSize), featuresStrs_(new (Ctx, 16) StringRef[featuresStrs_Size])
  {
  for (size_t I = 0, E = featuresStrs_Size; I != E;
       ++I) {
    StringRef Ref = FeaturesStrs[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      featuresStrs_[I] = StringRef(Mem, Ref.size());
    }
  }
}

TargetClonesAttr::TargetClonesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TargetClones, false, false)
              , featuresStrs_Size(0), featuresStrs_(nullptr)
  {
}



TargetClonesAttr *TargetClonesAttr::clone(ASTContext &C) const {
  auto *A = new (C) TargetClonesAttr(C, *this, featuresStrs_, featuresStrs_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TargetClonesAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((target_clones";
    OS << "";
  for (const auto &Val : featuresStrs()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::target_clones";
    OS << "";
  for (const auto &Val : featuresStrs()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::target_clones";
    OS << "";
  for (const auto &Val : featuresStrs()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TargetClonesAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "target_clones";
  case 1:
    return "target_clones";
  case 2:
    return "target_clones";
  }
}


// TestTypestateAttr implementation

TestTypestateAttr *TestTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState TestState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TestTypestateAttr(Ctx, CommonInfo, TestState);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TestTypestateAttr *TestTypestateAttr::Create(ASTContext &Ctx, ConsumedState TestState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TestTypestateAttr(Ctx, CommonInfo, TestState);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TestTypestateAttr *TestTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState TestState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TestState, I);
}

TestTypestateAttr *TestTypestateAttr::Create(ASTContext &Ctx, ConsumedState TestState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TestState, I);
}

TestTypestateAttr::TestTypestateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState TestState
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TestTypestate, false, false)
              , testState(TestState)
  {
}



bool TestTypestateAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("consumed", TestTypestateAttr::Consumed)
    .Case("unconsumed", TestTypestateAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *TestTypestateAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case TestTypestateAttr::Consumed: return "consumed";
  case TestTypestateAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
TestTypestateAttr *TestTypestateAttr::clone(ASTContext &C) const {
  auto *A = new (C) TestTypestateAttr(C, *this, testState);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TestTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((test_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TestTypestateAttr::ConvertConsumedStateToStr(getTestState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::test_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TestTypestateAttr::ConvertConsumedStateToStr(getTestState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TestTypestateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "test_typestate";
  case 1:
    return "test_typestate";
  }
}


// ThisCallAttr implementation

ThisCallAttr *ThisCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThisCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThisCallAttr *ThisCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThisCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThisCallAttr *ThisCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ThisCallAttr *ThisCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ThisCallAttr::ThisCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ThisCall, false, false)
  {
}

ThisCallAttr *ThisCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) ThisCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ThisCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((thiscall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::thiscall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::thiscall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __thiscall";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _thiscall";
    OS << "";
    break;
  }
}
}

const char *ThisCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "thiscall";
  case 1:
    return "thiscall";
  case 2:
    return "thiscall";
  case 3:
    return "__thiscall";
  case 4:
    return "_thiscall";
  }
}


// ThreadAttr implementation

ThreadAttr *ThreadAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThreadAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThreadAttr *ThreadAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThreadAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThreadAttr *ThreadAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ThreadAttr *ThreadAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ThreadAttr::ThreadAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::Thread, false)
  {
}

ThreadAttr *ThreadAttr::clone(ASTContext &C) const {
  auto *A = new (C) ThreadAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ThreadAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(thread";
    OS << ")";
    break;
  }
}
}

const char *ThreadAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "thread";
  }
}


// TransparentUnionAttr implementation

TransparentUnionAttr *TransparentUnionAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TransparentUnionAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TransparentUnionAttr *TransparentUnionAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TransparentUnionAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TransparentUnionAttr *TransparentUnionAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TransparentUnionAttr *TransparentUnionAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TransparentUnionAttr::TransparentUnionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TransparentUnion, false, false)
  {
}

TransparentUnionAttr *TransparentUnionAttr::clone(ASTContext &C) const {
  auto *A = new (C) TransparentUnionAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TransparentUnionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((transparent_union";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::transparent_union";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::transparent_union";
    OS << "]]";
    break;
  }
}
}

const char *TransparentUnionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "transparent_union";
  case 1:
    return "transparent_union";
  case 2:
    return "transparent_union";
  }
}


// TrivialABIAttr implementation

TrivialABIAttr *TrivialABIAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TrivialABIAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TrivialABIAttr *TrivialABIAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TrivialABIAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TrivialABIAttr *TrivialABIAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TrivialABIAttr *TrivialABIAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TrivialABIAttr::TrivialABIAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TrivialABI, false, false)
  {
}

TrivialABIAttr *TrivialABIAttr::clone(ASTContext &C) const {
  auto *A = new (C) TrivialABIAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TrivialABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((trivial_abi";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::trivial_abi";
    OS << "]]";
    break;
  }
}
}

const char *TrivialABIAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "trivial_abi";
  case 1:
    return "trivial_abi";
  }
}


// TryAcquireCapabilityAttr implementation

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TryAcquireCapabilityAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TryAcquireCapabilityAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  return A;
}

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, TryAcquireCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, SuccessValue, Args, ArgsSize, I);
}

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, TryAcquireCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, SuccessValue, Args, ArgsSize, I);
}

TryAcquireCapabilityAttr::TryAcquireCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TryAcquireCapability, true, true)
              , successValue(SuccessValue)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

TryAcquireCapabilityAttr::TryAcquireCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TryAcquireCapability, true, true)
              , successValue(SuccessValue)
              , args_Size(0), args_(nullptr)
  {
}

TryAcquireCapabilityAttr::Spelling TryAcquireCapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_try_acquire_capability;
    case 1: return CXX11_clang_try_acquire_capability;
    case 2: return GNU_try_acquire_shared_capability;
    case 3: return CXX11_clang_try_acquire_shared_capability;
  }
}




TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) TryAcquireCapabilityAttr(C, *this, successValue, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TryAcquireCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((try_acquire_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::try_acquire_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((try_acquire_shared_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::try_acquire_shared_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TryAcquireCapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "try_acquire_capability";
  case 1:
    return "try_acquire_capability";
  case 2:
    return "try_acquire_shared_capability";
  case 3:
    return "try_acquire_shared_capability";
  }
}


// TypeNonNullAttr implementation

TypeNonNullAttr *TypeNonNullAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNonNullAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNonNullAttr *TypeNonNullAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNonNullAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNonNullAttr *TypeNonNullAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNonNullAttr *TypeNonNullAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNonNullAttr::TypeNonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNonNull, false)
  {
}

TypeNonNullAttr *TypeNonNullAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNonNullAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNonNullAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Nonnull";
    OS << "";
    break;
  }
}
}

const char *TypeNonNullAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Nonnull";
  }
}


// TypeNullUnspecifiedAttr implementation

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullUnspecifiedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullUnspecifiedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNullUnspecifiedAttr::TypeNullUnspecifiedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNullUnspecified, false)
  {
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNullUnspecifiedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNullUnspecifiedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Null_unspecified";
    OS << "";
    break;
  }
}
}

const char *TypeNullUnspecifiedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Null_unspecified";
  }
}


// TypeNullableAttr implementation

TypeNullableAttr *TypeNullableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableAttr *TypeNullableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableAttr *TypeNullableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNullableAttr *TypeNullableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNullableAttr::TypeNullableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNullable, false)
  {
}

TypeNullableAttr *TypeNullableAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNullableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNullableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Nullable";
    OS << "";
    break;
  }
}
}

const char *TypeNullableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Nullable";
  }
}


// TypeNullableResultAttr implementation

TypeNullableResultAttr *TypeNullableResultAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableResultAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableResultAttr *TypeNullableResultAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableResultAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableResultAttr *TypeNullableResultAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNullableResultAttr *TypeNullableResultAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNullableResultAttr::TypeNullableResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNullableResult, false)
  {
}

TypeNullableResultAttr *TypeNullableResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNullableResultAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNullableResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Nullable_result";
    OS << "";
    break;
  }
}
}

const char *TypeNullableResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Nullable_result";
  }
}


// TypeTagForDatatypeAttr implementation

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeTagForDatatypeAttr(Ctx, CommonInfo, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeTagForDatatypeAttr(Ctx, CommonInfo, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, I);
}

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, I);
}

TypeTagForDatatypeAttr::TypeTagForDatatypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * ArgumentKind
              , TypeSourceInfo * MatchingCType
              , bool LayoutCompatible
              , bool MustBeNull
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TypeTagForDatatype, false, false)
              , argumentKind(ArgumentKind)
              , matchingCType(MatchingCType)
              , layoutCompatible(LayoutCompatible)
              , mustBeNull(MustBeNull)
  {
}









TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeTagForDatatypeAttr(C, *this, argumentKind, matchingCType, layoutCompatible, mustBeNull);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeTagForDatatypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((type_tag_for_datatype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMatchingCType().getAsString() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getLayoutCompatible() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMustBeNull() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::type_tag_for_datatype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMatchingCType().getAsString() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getLayoutCompatible() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMustBeNull() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::type_tag_for_datatype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMatchingCType().getAsString() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getLayoutCompatible() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMustBeNull() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TypeTagForDatatypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "type_tag_for_datatype";
  case 1:
    return "type_tag_for_datatype";
  case 2:
    return "type_tag_for_datatype";
  }
}


// TypeVisibilityAttr implementation

TypeVisibilityAttr *TypeVisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeVisibilityAttr(Ctx, CommonInfo, Visibility);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeVisibilityAttr *TypeVisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeVisibilityAttr(Ctx, CommonInfo, Visibility);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeVisibilityAttr *TypeVisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Visibility, I);
}

TypeVisibilityAttr *TypeVisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Visibility, I);
}

TypeVisibilityAttr::TypeVisibilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , VisibilityType Visibility
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TypeVisibility, false, false)
              , visibility(Visibility)
  {
}



bool TypeVisibilityAttr::ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
  Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
    .Case("default", TypeVisibilityAttr::Default)
    .Case("hidden", TypeVisibilityAttr::Hidden)
    .Case("internal", TypeVisibilityAttr::Hidden)
    .Case("protected", TypeVisibilityAttr::Protected)
    .Default(Optional<VisibilityType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *TypeVisibilityAttr::ConvertVisibilityTypeToStr(VisibilityType Val) {
  switch(Val) {
  case TypeVisibilityAttr::Default: return "default";
  case TypeVisibilityAttr::Hidden: return "hidden";
  case TypeVisibilityAttr::Protected: return "protected";
  }
  llvm_unreachable("No enumerator with that value");
}
TypeVisibilityAttr *TypeVisibilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeVisibilityAttr(C, *this, visibility);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeVisibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((type_visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TypeVisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::type_visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TypeVisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::type_visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TypeVisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TypeVisibilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "type_visibility";
  case 1:
    return "type_visibility";
  case 2:
    return "type_visibility";
  }
}


// UPtrAttr implementation

UPtrAttr *UPtrAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UPtrAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UPtrAttr *UPtrAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UPtrAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UPtrAttr *UPtrAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UPtrAttr *UPtrAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UPtrAttr::UPtrAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::UPtr, false)
  {
}

UPtrAttr *UPtrAttr::clone(ASTContext &C) const {
  auto *A = new (C) UPtrAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UPtrAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __uptr";
    OS << "";
    break;
  }
}
}

const char *UPtrAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__uptr";
  }
}


// UnavailableAttr implementation

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message, ImplicitReason);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message, ImplicitReason);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Message, ImplicitReason, I);
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Message, ImplicitReason, I);
}

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Message, I);
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Message, I);
}

UnavailableAttr::UnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
              , ImplicitReason ImplicitReason
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unavailable, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , implicitReason(ImplicitReason)
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

UnavailableAttr::UnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unavailable, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , implicitReason(ImplicitReason(0))
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

UnavailableAttr::UnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unavailable, false, false)
              , messageLength(0),message(nullptr)
              , implicitReason(ImplicitReason(0))
  {
}





UnavailableAttr *UnavailableAttr::clone(ASTContext &C) const {
  auto *A = new (C) UnavailableAttr(C, *this, getMessage(), implicitReason);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UnavailableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((unavailable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::unavailable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::unavailable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *UnavailableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "unavailable";
  case 1:
    return "unavailable";
  case 2:
    return "unavailable";
  }
}


// UninitializedAttr implementation

UninitializedAttr *UninitializedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UninitializedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UninitializedAttr *UninitializedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UninitializedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UninitializedAttr *UninitializedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UninitializedAttr *UninitializedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UninitializedAttr::UninitializedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Uninitialized, false, false)
  {
}

UninitializedAttr *UninitializedAttr::clone(ASTContext &C) const {
  auto *A = new (C) UninitializedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UninitializedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((uninitialized";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::uninitialized";
    OS << "]]";
    break;
  }
}
}

const char *UninitializedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "uninitialized";
  case 1:
    return "uninitialized";
  }
}


// UnlikelyAttr implementation

UnlikelyAttr *UnlikelyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnlikelyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnlikelyAttr *UnlikelyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnlikelyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnlikelyAttr *UnlikelyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UnlikelyAttr *UnlikelyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UnlikelyAttr::UnlikelyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::Unlikely, false)
  {
}

UnlikelyAttr *UnlikelyAttr::clone(ASTContext &C) const {
  auto *A = new (C) UnlikelyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UnlikelyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[unlikely";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[clang::unlikely";
    OS << "]]";
    break;
  }
}
}

const char *UnlikelyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "unlikely";
  case 1:
    return "unlikely";
  }
}


// UnusedAttr implementation

UnusedAttr *UnusedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnusedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnusedAttr *UnusedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnusedAttr(Ctx, CommonInfo);
  return A;
}

UnusedAttr *UnusedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, UnusedAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

UnusedAttr *UnusedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, UnusedAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

UnusedAttr::UnusedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unused, false, false)
  {
}

UnusedAttr::Spelling UnusedAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return CXX11_maybe_unused;
    case 1: return GNU_unused;
    case 2: return CXX11_gnu_unused;
    case 3: return C2x_gnu_unused;
    case 4: return C2x_maybe_unused;
  }
}
UnusedAttr *UnusedAttr::clone(ASTContext &C) const {
  auto *A = new (C) UnusedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UnusedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[maybe_unused";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " __attribute__((unused";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::unused";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::unused";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[maybe_unused";
    OS << "]]";
    break;
  }
}
}

const char *UnusedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "maybe_unused";
  case 1:
    return "unused";
  case 2:
    return "unused";
  case 3:
    return "unused";
  case 4:
    return "maybe_unused";
  }
}


// UseHandleAttr implementation

UseHandleAttr *UseHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UseHandleAttr(Ctx, CommonInfo, HandleType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UseHandleAttr *UseHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UseHandleAttr(Ctx, CommonInfo, HandleType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UseHandleAttr *UseHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, HandleType, I);
}

UseHandleAttr *UseHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, HandleType, I);
}

UseHandleAttr::UseHandleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef HandleType
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::UseHandle, false, false)
              , handleTypeLength(HandleType.size()),handleType(new (Ctx, 1) char[handleTypeLength])
  {
    if (!HandleType.empty())
      std::memcpy(handleType, HandleType.data(), handleTypeLength);
}



UseHandleAttr *UseHandleAttr::clone(ASTContext &C) const {
  auto *A = new (C) UseHandleAttr(C, *this, getHandleType());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UseHandleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((use_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::use_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::use_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *UseHandleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "use_handle";
  case 1:
    return "use_handle";
  case 2:
    return "use_handle";
  }
}


// UsedAttr implementation

UsedAttr *UsedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsedAttr *UsedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsedAttr *UsedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UsedAttr *UsedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UsedAttr::UsedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Used, false, false)
  {
}

UsedAttr *UsedAttr::clone(ASTContext &C) const {
  auto *A = new (C) UsedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UsedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((used";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::used";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::used";
    OS << "]]";
    break;
  }
}
}

const char *UsedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "used";
  case 1:
    return "used";
  case 2:
    return "used";
  }
}


// UsingIfExistsAttr implementation

UsingIfExistsAttr *UsingIfExistsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsingIfExistsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsingIfExistsAttr *UsingIfExistsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsingIfExistsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsingIfExistsAttr *UsingIfExistsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UsingIfExistsAttr *UsingIfExistsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UsingIfExistsAttr::UsingIfExistsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::UsingIfExists, false, false)
  {
}

UsingIfExistsAttr *UsingIfExistsAttr::clone(ASTContext &C) const {
  auto *A = new (C) UsingIfExistsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UsingIfExistsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((using_if_exists";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::using_if_exists";
    OS << "]]";
    break;
  }
}
}

const char *UsingIfExistsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "using_if_exists";
  case 1:
    return "using_if_exists";
  }
}


// UuidAttr implementation

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid, GuidDecl);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid, GuidDecl);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Guid, GuidDecl, I);
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Guid, GuidDecl, I);
}

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Guid, I);
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Guid, I);
}

UuidAttr::UuidAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Guid
              , MSGuidDecl * GuidDecl
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Uuid, false, false)
              , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength])
              , guidDecl(GuidDecl)
  {
    if (!Guid.empty())
      std::memcpy(guid, Guid.data(), guidLength);
}

UuidAttr::UuidAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Guid
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Uuid, false, false)
              , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength])
              , guidDecl()
  {
    if (!Guid.empty())
      std::memcpy(guid, Guid.data(), guidLength);
}





UuidAttr *UuidAttr::clone(ASTContext &C) const {
  auto *A = new (C) UuidAttr(C, *this, getGuid(), guidDecl);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UuidAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(uuid";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getGuid() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
  case 1 : {
    OS << "[uuid";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getGuid() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]";
    break;
  }
}
}

const char *UuidAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "uuid";
  case 1:
    return "uuid";
  }
}


// VecReturnAttr implementation

VecReturnAttr *VecReturnAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecReturnAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecReturnAttr *VecReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecReturnAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecReturnAttr *VecReturnAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

VecReturnAttr *VecReturnAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

VecReturnAttr::VecReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::VecReturn, false, false)
  {
}

VecReturnAttr *VecReturnAttr::clone(ASTContext &C) const {
  auto *A = new (C) VecReturnAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VecReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((vecreturn";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::vecreturn";
    OS << "]]";
    break;
  }
}
}

const char *VecReturnAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "vecreturn";
  case 1:
    return "vecreturn";
  }
}


// VecTypeHintAttr implementation

VecTypeHintAttr *VecTypeHintAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecTypeHintAttr(Ctx, CommonInfo, TypeHint);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecTypeHintAttr *VecTypeHintAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypeHint, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecTypeHintAttr(Ctx, CommonInfo, TypeHint);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecTypeHintAttr *VecTypeHintAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TypeHint, I);
}

VecTypeHintAttr *VecTypeHintAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TypeHint, I);
}

VecTypeHintAttr::VecTypeHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * TypeHint
             )
  : InheritableAttr(Ctx, CommonInfo, attr::VecTypeHint, false, false)
              , typeHint(TypeHint)
  {
}



VecTypeHintAttr *VecTypeHintAttr::clone(ASTContext &C) const {
  auto *A = new (C) VecTypeHintAttr(C, *this, typeHint);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VecTypeHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((vec_type_hint";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeHint().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *VecTypeHintAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "vec_type_hint";
  }
}


// VectorCallAttr implementation

VectorCallAttr *VectorCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VectorCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VectorCallAttr *VectorCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VectorCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VectorCallAttr *VectorCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

VectorCallAttr *VectorCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

VectorCallAttr::VectorCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::VectorCall, false, false)
  {
}

VectorCallAttr *VectorCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) VectorCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VectorCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((vectorcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::vectorcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::vectorcall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __vectorcall";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _vectorcall";
    OS << "";
    break;
  }
}
}

const char *VectorCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "vectorcall";
  case 1:
    return "vectorcall";
  case 2:
    return "vectorcall";
  case 3:
    return "__vectorcall";
  case 4:
    return "_vectorcall";
  }
}


// VisibilityAttr implementation

VisibilityAttr *VisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VisibilityAttr(Ctx, CommonInfo, Visibility);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VisibilityAttr *VisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VisibilityAttr(Ctx, CommonInfo, Visibility);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VisibilityAttr *VisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Visibility, I);
}

VisibilityAttr *VisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Visibility, I);
}

VisibilityAttr::VisibilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , VisibilityType Visibility
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Visibility, false, false)
              , visibility(Visibility)
  {
}



bool VisibilityAttr::ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
  Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
    .Case("default", VisibilityAttr::Default)
    .Case("hidden", VisibilityAttr::Hidden)
    .Case("internal", VisibilityAttr::Hidden)
    .Case("protected", VisibilityAttr::Protected)
    .Default(Optional<VisibilityType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *VisibilityAttr::ConvertVisibilityTypeToStr(VisibilityType Val) {
  switch(Val) {
  case VisibilityAttr::Default: return "default";
  case VisibilityAttr::Hidden: return "hidden";
  case VisibilityAttr::Protected: return "protected";
  }
  llvm_unreachable("No enumerator with that value");
}
VisibilityAttr *VisibilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) VisibilityAttr(C, *this, visibility);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VisibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << VisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << VisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << VisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *VisibilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "visibility";
  case 1:
    return "visibility";
  case 2:
    return "visibility";
  }
}


// WarnUnusedAttr implementation

WarnUnusedAttr *WarnUnusedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WarnUnusedAttr *WarnUnusedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WarnUnusedAttr *WarnUnusedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

WarnUnusedAttr *WarnUnusedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

WarnUnusedAttr::WarnUnusedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WarnUnused, false, false)
  {
}

WarnUnusedAttr *WarnUnusedAttr::clone(ASTContext &C) const {
  auto *A = new (C) WarnUnusedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WarnUnusedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((warn_unused";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::warn_unused";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::warn_unused";
    OS << "]]";
    break;
  }
}
}

const char *WarnUnusedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "warn_unused";
  case 1:
    return "warn_unused";
  case 2:
    return "warn_unused";
  }
}


// WarnUnusedResultAttr implementation

WarnUnusedResultAttr *WarnUnusedResultAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedResultAttr(Ctx, CommonInfo, Message);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WarnUnusedResultAttr *WarnUnusedResultAttr::Create(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedResultAttr(Ctx, CommonInfo, Message);
  return A;
}

WarnUnusedResultAttr *WarnUnusedResultAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax, WarnUnusedResultAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Message, I);
}

WarnUnusedResultAttr *WarnUnusedResultAttr::Create(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax, WarnUnusedResultAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Message, I);
}

WarnUnusedResultAttr::WarnUnusedResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WarnUnusedResult, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

WarnUnusedResultAttr::WarnUnusedResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WarnUnusedResult, false, false)
              , messageLength(0),message(nullptr)
  {
}

WarnUnusedResultAttr::Spelling WarnUnusedResultAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return CXX11_nodiscard;
    case 1: return C2x_nodiscard;
    case 2: return CXX11_clang_warn_unused_result;
    case 3: return GNU_warn_unused_result;
    case 4: return CXX11_gnu_warn_unused_result;
    case 5: return C2x_gnu_warn_unused_result;
  }
}


WarnUnusedResultAttr *WarnUnusedResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) WarnUnusedResultAttr(C, *this, getMessage());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WarnUnusedResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[nodiscard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[nodiscard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WarnUnusedResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nodiscard";
  case 1:
    return "nodiscard";
  case 2:
    return "warn_unused_result";
  case 3:
    return "warn_unused_result";
  case 4:
    return "warn_unused_result";
  case 5:
    return "warn_unused_result";
  }
}


// WeakAttr implementation

WeakAttr *WeakAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakAttr *WeakAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakAttr *WeakAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

WeakAttr *WeakAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

WeakAttr::WeakAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Weak, false, false)
  {
}

WeakAttr *WeakAttr::clone(ASTContext &C) const {
  auto *A = new (C) WeakAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WeakAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((weak";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::weak";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::weak";
    OS << "]]";
    break;
  }
}
}

const char *WeakAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "weak";
  case 1:
    return "weak";
  case 2:
    return "weak";
  }
}


// WeakImportAttr implementation

WeakImportAttr *WeakImportAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakImportAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakImportAttr *WeakImportAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakImportAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakImportAttr *WeakImportAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

WeakImportAttr *WeakImportAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

WeakImportAttr::WeakImportAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WeakImport, false, false)
  {
}

WeakImportAttr *WeakImportAttr::clone(ASTContext &C) const {
  auto *A = new (C) WeakImportAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WeakImportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((weak_import";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::weak_import";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::weak_import";
    OS << "]]";
    break;
  }
}
}

const char *WeakImportAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "weak_import";
  case 1:
    return "weak_import";
  case 2:
    return "weak_import";
  }
}


// WeakRefAttr implementation

WeakRefAttr *WeakRefAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakRefAttr(Ctx, CommonInfo, Aliasee);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakRefAttr *WeakRefAttr::Create(ASTContext &Ctx, llvm::StringRef Aliasee, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakRefAttr(Ctx, CommonInfo, Aliasee);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakRefAttr *WeakRefAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Aliasee, I);
}

WeakRefAttr *WeakRefAttr::Create(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Aliasee, I);
}

WeakRefAttr::WeakRefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Aliasee
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WeakRef, false, false)
              , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
  {
    if (!Aliasee.empty())
      std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
}

WeakRefAttr::WeakRefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WeakRef, false, false)
              , aliaseeLength(0),aliasee(nullptr)
  {
}



WeakRefAttr *WeakRefAttr::clone(ASTContext &C) const {
  auto *A = new (C) WeakRefAttr(C, *this, getAliasee());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WeakRefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((weakref";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::weakref";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::weakref";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WeakRefAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "weakref";
  case 1:
    return "weakref";
  case 2:
    return "weakref";
  }
}


// WebAssemblyExportNameAttr implementation

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ExportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyExportNameAttr(Ctx, CommonInfo, ExportName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ExportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyExportNameAttr(Ctx, CommonInfo, ExportName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ExportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ExportName, I);
}

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ExportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ExportName, I);
}

WebAssemblyExportNameAttr::WebAssemblyExportNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef ExportName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WebAssemblyExportName, false, false)
              , exportNameLength(ExportName.size()),exportName(new (Ctx, 1) char[exportNameLength])
  {
    if (!ExportName.empty())
      std::memcpy(exportName, ExportName.data(), exportNameLength);
}



WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) WebAssemblyExportNameAttr(C, *this, getExportName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WebAssemblyExportNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((export_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getExportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::export_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getExportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::export_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getExportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WebAssemblyExportNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "export_name";
  case 1:
    return "export_name";
  case 2:
    return "export_name";
  }
}


// WebAssemblyImportModuleAttr implementation

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportModule, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportModuleAttr(Ctx, CommonInfo, ImportModule);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::Create(ASTContext &Ctx, llvm::StringRef ImportModule, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportModuleAttr(Ctx, CommonInfo, ImportModule);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportModule, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ImportModule, I);
}

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::Create(ASTContext &Ctx, llvm::StringRef ImportModule, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ImportModule, I);
}

WebAssemblyImportModuleAttr::WebAssemblyImportModuleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef ImportModule
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WebAssemblyImportModule, false, false)
              , importModuleLength(ImportModule.size()),importModule(new (Ctx, 1) char[importModuleLength])
  {
    if (!ImportModule.empty())
      std::memcpy(importModule, ImportModule.data(), importModuleLength);
}



WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::clone(ASTContext &C) const {
  auto *A = new (C) WebAssemblyImportModuleAttr(C, *this, getImportModule());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WebAssemblyImportModuleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((import_module";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportModule() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::import_module";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportModule() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::import_module";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportModule() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WebAssemblyImportModuleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "import_module";
  case 1:
    return "import_module";
  case 2:
    return "import_module";
  }
}


// WebAssemblyImportNameAttr implementation

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportNameAttr(Ctx, CommonInfo, ImportName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ImportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportNameAttr(Ctx, CommonInfo, ImportName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ImportName, I);
}

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ImportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ImportName, I);
}

WebAssemblyImportNameAttr::WebAssemblyImportNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef ImportName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WebAssemblyImportName, false, false)
              , importNameLength(ImportName.size()),importName(new (Ctx, 1) char[importNameLength])
  {
    if (!ImportName.empty())
      std::memcpy(importName, ImportName.data(), importNameLength);
}



WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) WebAssemblyImportNameAttr(C, *this, getImportName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WebAssemblyImportNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((import_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::import_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::import_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WebAssemblyImportNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "import_name";
  case 1:
    return "import_name";
  case 2:
    return "import_name";
  }
}


// WorkGroupSizeHintAttr implementation

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WorkGroupSizeHintAttr(Ctx, CommonInfo, XDim, YDim, ZDim);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::Create(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WorkGroupSizeHintAttr(Ctx, CommonInfo, XDim, YDim, ZDim);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, XDim, YDim, ZDim, I);
}

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::Create(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, XDim, YDim, ZDim, I);
}

WorkGroupSizeHintAttr::WorkGroupSizeHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned XDim
              , unsigned YDim
              , unsigned ZDim
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WorkGroupSizeHint, false, false)
              , xDim(XDim)
              , yDim(YDim)
              , zDim(ZDim)
  {
}







WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::clone(ASTContext &C) const {
  auto *A = new (C) WorkGroupSizeHintAttr(C, *this, xDim, yDim, zDim);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WorkGroupSizeHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((work_group_size_hint";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getXDim() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getYDim() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getZDim() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *WorkGroupSizeHintAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "work_group_size_hint";
  }
}


// X86ForceAlignArgPointerAttr implementation

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) X86ForceAlignArgPointerAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) X86ForceAlignArgPointerAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

X86ForceAlignArgPointerAttr::X86ForceAlignArgPointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::X86ForceAlignArgPointer, false, false)
  {
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::clone(ASTContext &C) const {
  auto *A = new (C) X86ForceAlignArgPointerAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void X86ForceAlignArgPointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((force_align_arg_pointer";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::force_align_arg_pointer";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::force_align_arg_pointer";
    OS << "]]";
    break;
  }
}
}

const char *X86ForceAlignArgPointerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "force_align_arg_pointer";
  case 1:
    return "force_align_arg_pointer";
  case 2:
    return "force_align_arg_pointer";
  }
}


// XRayInstrumentAttr implementation

XRayInstrumentAttr *XRayInstrumentAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayInstrumentAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

XRayInstrumentAttr *XRayInstrumentAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayInstrumentAttr(Ctx, CommonInfo);
  return A;
}

XRayInstrumentAttr *XRayInstrumentAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, XRayInstrumentAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

XRayInstrumentAttr *XRayInstrumentAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, XRayInstrumentAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

XRayInstrumentAttr::XRayInstrumentAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::XRayInstrument, false, false)
  {
}

XRayInstrumentAttr::Spelling XRayInstrumentAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_xray_always_instrument;
    case 1: return CXX11_clang_xray_always_instrument;
    case 2: return C2x_clang_xray_always_instrument;
    case 3: return GNU_xray_never_instrument;
    case 4: return CXX11_clang_xray_never_instrument;
    case 5: return C2x_clang_xray_never_instrument;
  }
}
XRayInstrumentAttr *XRayInstrumentAttr::clone(ASTContext &C) const {
  auto *A = new (C) XRayInstrumentAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void XRayInstrumentAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((xray_always_instrument";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::xray_always_instrument";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::xray_always_instrument";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((xray_never_instrument";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::xray_never_instrument";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::xray_never_instrument";
    OS << "]]";
    break;
  }
}
}

const char *XRayInstrumentAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "xray_always_instrument";
  case 1:
    return "xray_always_instrument";
  case 2:
    return "xray_always_instrument";
  case 3:
    return "xray_never_instrument";
  case 4:
    return "xray_never_instrument";
  case 5:
    return "xray_never_instrument";
  }
}


// XRayLogArgsAttr implementation

XRayLogArgsAttr *XRayLogArgsAttr::CreateImplicit(ASTContext &Ctx, unsigned ArgumentCount, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayLogArgsAttr(Ctx, CommonInfo, ArgumentCount);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

XRayLogArgsAttr *XRayLogArgsAttr::Create(ASTContext &Ctx, unsigned ArgumentCount, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayLogArgsAttr(Ctx, CommonInfo, ArgumentCount);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

XRayLogArgsAttr *XRayLogArgsAttr::CreateImplicit(ASTContext &Ctx, unsigned ArgumentCount, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ArgumentCount, I);
}

XRayLogArgsAttr *XRayLogArgsAttr::Create(ASTContext &Ctx, unsigned ArgumentCount, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ArgumentCount, I);
}

XRayLogArgsAttr::XRayLogArgsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned ArgumentCount
             )
  : InheritableAttr(Ctx, CommonInfo, attr::XRayLogArgs, false, false)
              , argumentCount(ArgumentCount)
  {
}



XRayLogArgsAttr *XRayLogArgsAttr::clone(ASTContext &C) const {
  auto *A = new (C) XRayLogArgsAttr(C, *this, argumentCount);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void XRayLogArgsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((xray_log_args";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentCount() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::xray_log_args";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentCount() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::xray_log_args";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentCount() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *XRayLogArgsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "xray_log_args";
  case 1:
    return "xray_log_args";
  case 2:
    return "xray_log_args";
  }
}


// ZeroCallUsedRegsAttr implementation

ZeroCallUsedRegsAttr *ZeroCallUsedRegsAttr::CreateImplicit(ASTContext &Ctx, ZeroCallUsedRegsKind ZeroCallUsedRegs, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ZeroCallUsedRegsAttr(Ctx, CommonInfo, ZeroCallUsedRegs);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ZeroCallUsedRegsAttr *ZeroCallUsedRegsAttr::Create(ASTContext &Ctx, ZeroCallUsedRegsKind ZeroCallUsedRegs, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ZeroCallUsedRegsAttr(Ctx, CommonInfo, ZeroCallUsedRegs);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ZeroCallUsedRegsAttr *ZeroCallUsedRegsAttr::CreateImplicit(ASTContext &Ctx, ZeroCallUsedRegsKind ZeroCallUsedRegs, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ZeroCallUsedRegs, I);
}

ZeroCallUsedRegsAttr *ZeroCallUsedRegsAttr::Create(ASTContext &Ctx, ZeroCallUsedRegsKind ZeroCallUsedRegs, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ZeroCallUsedRegs, I);
}

ZeroCallUsedRegsAttr::ZeroCallUsedRegsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ZeroCallUsedRegsKind ZeroCallUsedRegs
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ZeroCallUsedRegs, false, false)
              , zeroCallUsedRegs(ZeroCallUsedRegs)
  {
}



bool ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(StringRef Val, ZeroCallUsedRegsKind &Out) {
  Optional<ZeroCallUsedRegsKind> R = llvm::StringSwitch<Optional<ZeroCallUsedRegsKind>>(Val)
    .Case("skip", ZeroCallUsedRegsAttr::Skip)
    .Case("used-gpr-arg", ZeroCallUsedRegsAttr::UsedGPRArg)
    .Case("used-gpr", ZeroCallUsedRegsAttr::UsedGPR)
    .Case("used-arg", ZeroCallUsedRegsAttr::UsedArg)
    .Case("used", ZeroCallUsedRegsAttr::Used)
    .Case("all-gpr-arg", ZeroCallUsedRegsAttr::AllGPRArg)
    .Case("all-gpr", ZeroCallUsedRegsAttr::AllGPR)
    .Case("all-arg", ZeroCallUsedRegsAttr::AllArg)
    .Case("all", ZeroCallUsedRegsAttr::All)
    .Default(Optional<ZeroCallUsedRegsKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(ZeroCallUsedRegsKind Val) {
  switch(Val) {
  case ZeroCallUsedRegsAttr::Skip: return "skip";
  case ZeroCallUsedRegsAttr::UsedGPRArg: return "used-gpr-arg";
  case ZeroCallUsedRegsAttr::UsedGPR: return "used-gpr";
  case ZeroCallUsedRegsAttr::UsedArg: return "used-arg";
  case ZeroCallUsedRegsAttr::Used: return "used";
  case ZeroCallUsedRegsAttr::AllGPRArg: return "all-gpr-arg";
  case ZeroCallUsedRegsAttr::AllGPR: return "all-gpr";
  case ZeroCallUsedRegsAttr::AllArg: return "all-arg";
  case ZeroCallUsedRegsAttr::All: return "all";
  }
  llvm_unreachable("No enumerator with that value");
}
ZeroCallUsedRegsAttr *ZeroCallUsedRegsAttr::clone(ASTContext &C) const {
  auto *A = new (C) ZeroCallUsedRegsAttr(C, *this, zeroCallUsedRegs);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ZeroCallUsedRegsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((zero_call_used_regs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(getZeroCallUsedRegs()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::zero_call_used_regs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(getZeroCallUsedRegs()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::zero_call_used_regs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(getZeroCallUsedRegs()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *ZeroCallUsedRegsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "zero_call_used_regs";
  case 1:
    return "zero_call_used_regs";
  case 2:
    return "zero_call_used_regs";
  }
}

const char *Attr::getSpelling() const {
  switch (getKind()) {
  case attr::AArch64SVEPcs:
    return cast<AArch64SVEPcsAttr>(this)->getSpelling();
  case attr::AArch64VectorPcs:
    return cast<AArch64VectorPcsAttr>(this)->getSpelling();
  case attr::AMDGPUFlatWorkGroupSize:
    return cast<AMDGPUFlatWorkGroupSizeAttr>(this)->getSpelling();
  case attr::AMDGPUKernelCall:
    return cast<AMDGPUKernelCallAttr>(this)->getSpelling();
  case attr::AMDGPUNumSGPR:
    return cast<AMDGPUNumSGPRAttr>(this)->getSpelling();
  case attr::AMDGPUNumVGPR:
    return cast<AMDGPUNumVGPRAttr>(this)->getSpelling();
  case attr::AMDGPUWavesPerEU:
    return cast<AMDGPUWavesPerEUAttr>(this)->getSpelling();
  case attr::ARMInterrupt:
    return cast<ARMInterruptAttr>(this)->getSpelling();
  case attr::AVRInterrupt:
    return cast<AVRInterruptAttr>(this)->getSpelling();
  case attr::AVRSignal:
    return cast<AVRSignalAttr>(this)->getSpelling();
  case attr::AbiTag:
    return cast<AbiTagAttr>(this)->getSpelling();
  case attr::AcquireCapability:
    return cast<AcquireCapabilityAttr>(this)->getSpelling();
  case attr::AcquireHandle:
    return cast<AcquireHandleAttr>(this)->getSpelling();
  case attr::AcquiredAfter:
    return cast<AcquiredAfterAttr>(this)->getSpelling();
  case attr::AcquiredBefore:
    return cast<AcquiredBeforeAttr>(this)->getSpelling();
  case attr::AddressSpace:
    return cast<AddressSpaceAttr>(this)->getSpelling();
  case attr::Alias:
    return cast<AliasAttr>(this)->getSpelling();
  case attr::AlignMac68k:
    return cast<AlignMac68kAttr>(this)->getSpelling();
  case attr::AlignNatural:
    return cast<AlignNaturalAttr>(this)->getSpelling();
  case attr::AlignValue:
    return cast<AlignValueAttr>(this)->getSpelling();
  case attr::Aligned:
    return cast<AlignedAttr>(this)->getSpelling();
  case attr::AllocAlign:
    return cast<AllocAlignAttr>(this)->getSpelling();
  case attr::AllocSize:
    return cast<AllocSizeAttr>(this)->getSpelling();
  case attr::AlwaysDestroy:
    return cast<AlwaysDestroyAttr>(this)->getSpelling();
  case attr::AlwaysInline:
    return cast<AlwaysInlineAttr>(this)->getSpelling();
  case attr::AnalyzerNoReturn:
    return cast<AnalyzerNoReturnAttr>(this)->getSpelling();
  case attr::Annotate:
    return cast<AnnotateAttr>(this)->getSpelling();
  case attr::AnnotateType:
    return cast<AnnotateTypeAttr>(this)->getSpelling();
  case attr::AnyX86Interrupt:
    return cast<AnyX86InterruptAttr>(this)->getSpelling();
  case attr::AnyX86NoCallerSavedRegisters:
    return cast<AnyX86NoCallerSavedRegistersAttr>(this)->getSpelling();
  case attr::AnyX86NoCfCheck:
    return cast<AnyX86NoCfCheckAttr>(this)->getSpelling();
  case attr::ArcWeakrefUnavailable:
    return cast<ArcWeakrefUnavailableAttr>(this)->getSpelling();
  case attr::ArgumentWithTypeTag:
    return cast<ArgumentWithTypeTagAttr>(this)->getSpelling();
  case attr::ArmBuiltinAlias:
    return cast<ArmBuiltinAliasAttr>(this)->getSpelling();
  case attr::ArmMveStrictPolymorphism:
    return cast<ArmMveStrictPolymorphismAttr>(this)->getSpelling();
  case attr::Artificial:
    return cast<ArtificialAttr>(this)->getSpelling();
  case attr::AsmLabel:
    return cast<AsmLabelAttr>(this)->getSpelling();
  case attr::AssertCapability:
    return cast<AssertCapabilityAttr>(this)->getSpelling();
  case attr::AssertExclusiveLock:
    return cast<AssertExclusiveLockAttr>(this)->getSpelling();
  case attr::AssertSharedLock:
    return cast<AssertSharedLockAttr>(this)->getSpelling();
  case attr::AssumeAligned:
    return cast<AssumeAlignedAttr>(this)->getSpelling();
  case attr::Assumption:
    return cast<AssumptionAttr>(this)->getSpelling();
  case attr::Availability:
    return cast<AvailabilityAttr>(this)->getSpelling();
  case attr::BPFPreserveAccessIndex:
    return cast<BPFPreserveAccessIndexAttr>(this)->getSpelling();
  case attr::BTFDeclTag:
    return cast<BTFDeclTagAttr>(this)->getSpelling();
  case attr::BTFTypeTag:
    return cast<BTFTypeTagAttr>(this)->getSpelling();
  case attr::Blocks:
    return cast<BlocksAttr>(this)->getSpelling();
  case attr::Builtin:
    return cast<BuiltinAttr>(this)->getSpelling();
  case attr::BuiltinAlias:
    return cast<BuiltinAliasAttr>(this)->getSpelling();
  case attr::C11NoReturn:
    return cast<C11NoReturnAttr>(this)->getSpelling();
  case attr::CDecl:
    return cast<CDeclAttr>(this)->getSpelling();
  case attr::CFAuditedTransfer:
    return cast<CFAuditedTransferAttr>(this)->getSpelling();
  case attr::CFConsumed:
    return cast<CFConsumedAttr>(this)->getSpelling();
  case attr::CFGuard:
    return cast<CFGuardAttr>(this)->getSpelling();
  case attr::CFICanonicalJumpTable:
    return cast<CFICanonicalJumpTableAttr>(this)->getSpelling();
  case attr::CFReturnsNotRetained:
    return cast<CFReturnsNotRetainedAttr>(this)->getSpelling();
  case attr::CFReturnsRetained:
    return cast<CFReturnsRetainedAttr>(this)->getSpelling();
  case attr::CFUnknownTransfer:
    return cast<CFUnknownTransferAttr>(this)->getSpelling();
  case attr::CPUDispatch:
    return cast<CPUDispatchAttr>(this)->getSpelling();
  case attr::CPUSpecific:
    return cast<CPUSpecificAttr>(this)->getSpelling();
  case attr::CUDAConstant:
    return cast<CUDAConstantAttr>(this)->getSpelling();
  case attr::CUDADevice:
    return cast<CUDADeviceAttr>(this)->getSpelling();
  case attr::CUDADeviceBuiltinSurfaceType:
    return cast<CUDADeviceBuiltinSurfaceTypeAttr>(this)->getSpelling();
  case attr::CUDADeviceBuiltinTextureType:
    return cast<CUDADeviceBuiltinTextureTypeAttr>(this)->getSpelling();
  case attr::CUDAGlobal:
    return cast<CUDAGlobalAttr>(this)->getSpelling();
  case attr::CUDAHost:
    return cast<CUDAHostAttr>(this)->getSpelling();
  case attr::CUDAInvalidTarget:
    return cast<CUDAInvalidTargetAttr>(this)->getSpelling();
  case attr::CUDALaunchBounds:
    return cast<CUDALaunchBoundsAttr>(this)->getSpelling();
  case attr::CUDAShared:
    return cast<CUDASharedAttr>(this)->getSpelling();
  case attr::CXX11NoReturn:
    return cast<CXX11NoReturnAttr>(this)->getSpelling();
  case attr::CallableWhen:
    return cast<CallableWhenAttr>(this)->getSpelling();
  case attr::Callback:
    return cast<CallbackAttr>(this)->getSpelling();
  case attr::CalledOnce:
    return cast<CalledOnceAttr>(this)->getSpelling();
  case attr::Capability:
    return cast<CapabilityAttr>(this)->getSpelling();
  case attr::CapturedRecord:
    return cast<CapturedRecordAttr>(this)->getSpelling();
  case attr::CarriesDependency:
    return cast<CarriesDependencyAttr>(this)->getSpelling();
  case attr::Cleanup:
    return cast<CleanupAttr>(this)->getSpelling();
  case attr::CmseNSCall:
    return cast<CmseNSCallAttr>(this)->getSpelling();
  case attr::CmseNSEntry:
    return cast<CmseNSEntryAttr>(this)->getSpelling();
  case attr::CodeSeg:
    return cast<CodeSegAttr>(this)->getSpelling();
  case attr::Cold:
    return cast<ColdAttr>(this)->getSpelling();
  case attr::Common:
    return cast<CommonAttr>(this)->getSpelling();
  case attr::Const:
    return cast<ConstAttr>(this)->getSpelling();
  case attr::ConstInit:
    return cast<ConstInitAttr>(this)->getSpelling();
  case attr::Constructor:
    return cast<ConstructorAttr>(this)->getSpelling();
  case attr::Consumable:
    return cast<ConsumableAttr>(this)->getSpelling();
  case attr::ConsumableAutoCast:
    return cast<ConsumableAutoCastAttr>(this)->getSpelling();
  case attr::ConsumableSetOnRead:
    return cast<ConsumableSetOnReadAttr>(this)->getSpelling();
  case attr::Convergent:
    return cast<ConvergentAttr>(this)->getSpelling();
  case attr::DLLExport:
    return cast<DLLExportAttr>(this)->getSpelling();
  case attr::DLLExportStaticLocal:
    return cast<DLLExportStaticLocalAttr>(this)->getSpelling();
  case attr::DLLImport:
    return cast<DLLImportAttr>(this)->getSpelling();
  case attr::DLLImportStaticLocal:
    return cast<DLLImportStaticLocalAttr>(this)->getSpelling();
  case attr::Deprecated:
    return cast<DeprecatedAttr>(this)->getSpelling();
  case attr::Destructor:
    return cast<DestructorAttr>(this)->getSpelling();
  case attr::DiagnoseAsBuiltin:
    return cast<DiagnoseAsBuiltinAttr>(this)->getSpelling();
  case attr::DiagnoseIf:
    return cast<DiagnoseIfAttr>(this)->getSpelling();
  case attr::DisableSanitizerInstrumentation:
    return cast<DisableSanitizerInstrumentationAttr>(this)->getSpelling();
  case attr::DisableTailCalls:
    return cast<DisableTailCallsAttr>(this)->getSpelling();
  case attr::EmptyBases:
    return cast<EmptyBasesAttr>(this)->getSpelling();
  case attr::EnableIf:
    return cast<EnableIfAttr>(this)->getSpelling();
  case attr::EnforceTCB:
    return cast<EnforceTCBAttr>(this)->getSpelling();
  case attr::EnforceTCBLeaf:
    return cast<EnforceTCBLeafAttr>(this)->getSpelling();
  case attr::EnumExtensibility:
    return cast<EnumExtensibilityAttr>(this)->getSpelling();
  case attr::Error:
    return cast<ErrorAttr>(this)->getSpelling();
  case attr::ExcludeFromExplicitInstantiation:
    return cast<ExcludeFromExplicitInstantiationAttr>(this)->getSpelling();
  case attr::ExclusiveTrylockFunction:
    return cast<ExclusiveTrylockFunctionAttr>(this)->getSpelling();
  case attr::ExternalSourceSymbol:
    return cast<ExternalSourceSymbolAttr>(this)->getSpelling();
  case attr::FallThrough:
    return cast<FallThroughAttr>(this)->getSpelling();
  case attr::FastCall:
    return cast<FastCallAttr>(this)->getSpelling();
  case attr::Final:
    return cast<FinalAttr>(this)->getSpelling();
  case attr::FlagEnum:
    return cast<FlagEnumAttr>(this)->getSpelling();
  case attr::Flatten:
    return cast<FlattenAttr>(this)->getSpelling();
  case attr::Format:
    return cast<FormatAttr>(this)->getSpelling();
  case attr::FormatArg:
    return cast<FormatArgAttr>(this)->getSpelling();
  case attr::FunctionReturnThunks:
    return cast<FunctionReturnThunksAttr>(this)->getSpelling();
  case attr::GNUInline:
    return cast<GNUInlineAttr>(this)->getSpelling();
  case attr::GuardedBy:
    return cast<GuardedByAttr>(this)->getSpelling();
  case attr::GuardedVar:
    return cast<GuardedVarAttr>(this)->getSpelling();
  case attr::HIPManaged:
    return cast<HIPManagedAttr>(this)->getSpelling();
  case attr::HLSLNumThreads:
    return cast<HLSLNumThreadsAttr>(this)->getSpelling();
  case attr::HLSLResource:
    return cast<HLSLResourceAttr>(this)->getSpelling();
  case attr::HLSLResourceBinding:
    return cast<HLSLResourceBindingAttr>(this)->getSpelling();
  case attr::HLSLSV_GroupIndex:
    return cast<HLSLSV_GroupIndexAttr>(this)->getSpelling();
  case attr::HLSLShader:
    return cast<HLSLShaderAttr>(this)->getSpelling();
  case attr::Hot:
    return cast<HotAttr>(this)->getSpelling();
  case attr::IBAction:
    return cast<IBActionAttr>(this)->getSpelling();
  case attr::IBOutlet:
    return cast<IBOutletAttr>(this)->getSpelling();
  case attr::IBOutletCollection:
    return cast<IBOutletCollectionAttr>(this)->getSpelling();
  case attr::IFunc:
    return cast<IFuncAttr>(this)->getSpelling();
  case attr::InitPriority:
    return cast<InitPriorityAttr>(this)->getSpelling();
  case attr::InitSeg:
    return cast<InitSegAttr>(this)->getSpelling();
  case attr::IntelOclBicc:
    return cast<IntelOclBiccAttr>(this)->getSpelling();
  case attr::InternalLinkage:
    return cast<InternalLinkageAttr>(this)->getSpelling();
  case attr::LTOVisibilityPublic:
    return cast<LTOVisibilityPublicAttr>(this)->getSpelling();
  case attr::LayoutVersion:
    return cast<LayoutVersionAttr>(this)->getSpelling();
  case attr::Leaf:
    return cast<LeafAttr>(this)->getSpelling();
  case attr::LifetimeBound:
    return cast<LifetimeBoundAttr>(this)->getSpelling();
  case attr::Likely:
    return cast<LikelyAttr>(this)->getSpelling();
  case attr::LoaderUninitialized:
    return cast<LoaderUninitializedAttr>(this)->getSpelling();
  case attr::LockReturned:
    return cast<LockReturnedAttr>(this)->getSpelling();
  case attr::LocksExcluded:
    return cast<LocksExcludedAttr>(this)->getSpelling();
  case attr::LoopHint:
    return cast<LoopHintAttr>(this)->getSpelling();
  case attr::M68kInterrupt:
    return cast<M68kInterruptAttr>(this)->getSpelling();
  case attr::MIGServerRoutine:
    return cast<MIGServerRoutineAttr>(this)->getSpelling();
  case attr::MSABI:
    return cast<MSABIAttr>(this)->getSpelling();
  case attr::MSAllocator:
    return cast<MSAllocatorAttr>(this)->getSpelling();
  case attr::MSInheritance:
    return cast<MSInheritanceAttr>(this)->getSpelling();
  case attr::MSNoVTable:
    return cast<MSNoVTableAttr>(this)->getSpelling();
  case attr::MSP430Interrupt:
    return cast<MSP430InterruptAttr>(this)->getSpelling();
  case attr::MSStruct:
    return cast<MSStructAttr>(this)->getSpelling();
  case attr::MSVtorDisp:
    return cast<MSVtorDispAttr>(this)->getSpelling();
  case attr::MaxFieldAlignment:
    return cast<MaxFieldAlignmentAttr>(this)->getSpelling();
  case attr::MayAlias:
    return cast<MayAliasAttr>(this)->getSpelling();
  case attr::MaybeUndef:
    return cast<MaybeUndefAttr>(this)->getSpelling();
  case attr::MicroMips:
    return cast<MicroMipsAttr>(this)->getSpelling();
  case attr::MinSize:
    return cast<MinSizeAttr>(this)->getSpelling();
  case attr::MinVectorWidth:
    return cast<MinVectorWidthAttr>(this)->getSpelling();
  case attr::Mips16:
    return cast<Mips16Attr>(this)->getSpelling();
  case attr::MipsInterrupt:
    return cast<MipsInterruptAttr>(this)->getSpelling();
  case attr::MipsLongCall:
    return cast<MipsLongCallAttr>(this)->getSpelling();
  case attr::MipsShortCall:
    return cast<MipsShortCallAttr>(this)->getSpelling();
  case attr::Mode:
    return cast<ModeAttr>(this)->getSpelling();
  case attr::MustTail:
    return cast<MustTailAttr>(this)->getSpelling();
  case attr::NSConsumed:
    return cast<NSConsumedAttr>(this)->getSpelling();
  case attr::NSConsumesSelf:
    return cast<NSConsumesSelfAttr>(this)->getSpelling();
  case attr::NSErrorDomain:
    return cast<NSErrorDomainAttr>(this)->getSpelling();
  case attr::NSReturnsAutoreleased:
    return cast<NSReturnsAutoreleasedAttr>(this)->getSpelling();
  case attr::NSReturnsNotRetained:
    return cast<NSReturnsNotRetainedAttr>(this)->getSpelling();
  case attr::NSReturnsRetained:
    return cast<NSReturnsRetainedAttr>(this)->getSpelling();
  case attr::Naked:
    return cast<NakedAttr>(this)->getSpelling();
  case attr::NoAlias:
    return cast<NoAliasAttr>(this)->getSpelling();
  case attr::NoBuiltin:
    return cast<NoBuiltinAttr>(this)->getSpelling();
  case attr::NoCommon:
    return cast<NoCommonAttr>(this)->getSpelling();
  case attr::NoDebug:
    return cast<NoDebugAttr>(this)->getSpelling();
  case attr::NoDeref:
    return cast<NoDerefAttr>(this)->getSpelling();
  case attr::NoDestroy:
    return cast<NoDestroyAttr>(this)->getSpelling();
  case attr::NoDuplicate:
    return cast<NoDuplicateAttr>(this)->getSpelling();
  case attr::NoEscape:
    return cast<NoEscapeAttr>(this)->getSpelling();
  case attr::NoInline:
    return cast<NoInlineAttr>(this)->getSpelling();
  case attr::NoInstrumentFunction:
    return cast<NoInstrumentFunctionAttr>(this)->getSpelling();
  case attr::NoMerge:
    return cast<NoMergeAttr>(this)->getSpelling();
  case attr::NoMicroMips:
    return cast<NoMicroMipsAttr>(this)->getSpelling();
  case attr::NoMips16:
    return cast<NoMips16Attr>(this)->getSpelling();
  case attr::NoProfileFunction:
    return cast<NoProfileFunctionAttr>(this)->getSpelling();
  case attr::NoRandomizeLayout:
    return cast<NoRandomizeLayoutAttr>(this)->getSpelling();
  case attr::NoReturn:
    return cast<NoReturnAttr>(this)->getSpelling();
  case attr::NoSanitize:
    return cast<NoSanitizeAttr>(this)->getSpelling();
  case attr::NoSpeculativeLoadHardening:
    return cast<NoSpeculativeLoadHardeningAttr>(this)->getSpelling();
  case attr::NoSplitStack:
    return cast<NoSplitStackAttr>(this)->getSpelling();
  case attr::NoStackProtector:
    return cast<NoStackProtectorAttr>(this)->getSpelling();
  case attr::NoThreadSafetyAnalysis:
    return cast<NoThreadSafetyAnalysisAttr>(this)->getSpelling();
  case attr::NoThrow:
    return cast<NoThrowAttr>(this)->getSpelling();
  case attr::NoUniqueAddress:
    return cast<NoUniqueAddressAttr>(this)->getSpelling();
  case attr::NoUwtable:
    return cast<NoUwtableAttr>(this)->getSpelling();
  case attr::NonNull:
    return cast<NonNullAttr>(this)->getSpelling();
  case attr::NotTailCalled:
    return cast<NotTailCalledAttr>(this)->getSpelling();
  case attr::OMPAllocateDecl:
    return cast<OMPAllocateDeclAttr>(this)->getSpelling();
  case attr::OMPCaptureKind:
    return cast<OMPCaptureKindAttr>(this)->getSpelling();
  case attr::OMPCaptureNoInit:
    return cast<OMPCaptureNoInitAttr>(this)->getSpelling();
  case attr::OMPDeclareSimdDecl:
    return cast<OMPDeclareSimdDeclAttr>(this)->getSpelling();
  case attr::OMPDeclareTargetDecl:
    return cast<OMPDeclareTargetDeclAttr>(this)->getSpelling();
  case attr::OMPDeclareVariant:
    return cast<OMPDeclareVariantAttr>(this)->getSpelling();
  case attr::OMPReferencedVar:
    return cast<OMPReferencedVarAttr>(this)->getSpelling();
  case attr::OMPThreadPrivateDecl:
    return cast<OMPThreadPrivateDeclAttr>(this)->getSpelling();
  case attr::OSConsumed:
    return cast<OSConsumedAttr>(this)->getSpelling();
  case attr::OSConsumesThis:
    return cast<OSConsumesThisAttr>(this)->getSpelling();
  case attr::OSReturnsNotRetained:
    return cast<OSReturnsNotRetainedAttr>(this)->getSpelling();
  case attr::OSReturnsRetained:
    return cast<OSReturnsRetainedAttr>(this)->getSpelling();
  case attr::OSReturnsRetainedOnNonZero:
    return cast<OSReturnsRetainedOnNonZeroAttr>(this)->getSpelling();
  case attr::OSReturnsRetainedOnZero:
    return cast<OSReturnsRetainedOnZeroAttr>(this)->getSpelling();
  case attr::ObjCBoxable:
    return cast<ObjCBoxableAttr>(this)->getSpelling();
  case attr::ObjCBridge:
    return cast<ObjCBridgeAttr>(this)->getSpelling();
  case attr::ObjCBridgeMutable:
    return cast<ObjCBridgeMutableAttr>(this)->getSpelling();
  case attr::ObjCBridgeRelated:
    return cast<ObjCBridgeRelatedAttr>(this)->getSpelling();
  case attr::ObjCClassStub:
    return cast<ObjCClassStubAttr>(this)->getSpelling();
  case attr::ObjCDesignatedInitializer:
    return cast<ObjCDesignatedInitializerAttr>(this)->getSpelling();
  case attr::ObjCDirect:
    return cast<ObjCDirectAttr>(this)->getSpelling();
  case attr::ObjCDirectMembers:
    return cast<ObjCDirectMembersAttr>(this)->getSpelling();
  case attr::ObjCException:
    return cast<ObjCExceptionAttr>(this)->getSpelling();
  case attr::ObjCExplicitProtocolImpl:
    return cast<ObjCExplicitProtocolImplAttr>(this)->getSpelling();
  case attr::ObjCExternallyRetained:
    return cast<ObjCExternallyRetainedAttr>(this)->getSpelling();
  case attr::ObjCGC:
    return cast<ObjCGCAttr>(this)->getSpelling();
  case attr::ObjCIndependentClass:
    return cast<ObjCIndependentClassAttr>(this)->getSpelling();
  case attr::ObjCInertUnsafeUnretained:
    return cast<ObjCInertUnsafeUnretainedAttr>(this)->getSpelling();
  case attr::ObjCKindOf:
    return cast<ObjCKindOfAttr>(this)->getSpelling();
  case attr::ObjCMethodFamily:
    return cast<ObjCMethodFamilyAttr>(this)->getSpelling();
  case attr::ObjCNSObject:
    return cast<ObjCNSObjectAttr>(this)->getSpelling();
  case attr::ObjCNonLazyClass:
    return cast<ObjCNonLazyClassAttr>(this)->getSpelling();
  case attr::ObjCNonRuntimeProtocol:
    return cast<ObjCNonRuntimeProtocolAttr>(this)->getSpelling();
  case attr::ObjCOwnership:
    return cast<ObjCOwnershipAttr>(this)->getSpelling();
  case attr::ObjCPreciseLifetime:
    return cast<ObjCPreciseLifetimeAttr>(this)->getSpelling();
  case attr::ObjCRequiresPropertyDefs:
    return cast<ObjCRequiresPropertyDefsAttr>(this)->getSpelling();
  case attr::ObjCRequiresSuper:
    return cast<ObjCRequiresSuperAttr>(this)->getSpelling();
  case attr::ObjCReturnsInnerPointer:
    return cast<ObjCReturnsInnerPointerAttr>(this)->getSpelling();
  case attr::ObjCRootClass:
    return cast<ObjCRootClassAttr>(this)->getSpelling();
  case attr::ObjCRuntimeName:
    return cast<ObjCRuntimeNameAttr>(this)->getSpelling();
  case attr::ObjCRuntimeVisible:
    return cast<ObjCRuntimeVisibleAttr>(this)->getSpelling();
  case attr::ObjCSubclassingRestricted:
    return cast<ObjCSubclassingRestrictedAttr>(this)->getSpelling();
  case attr::OpenCLAccess:
    return cast<OpenCLAccessAttr>(this)->getSpelling();
  case attr::OpenCLConstantAddressSpace:
    return cast<OpenCLConstantAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLGenericAddressSpace:
    return cast<OpenCLGenericAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLGlobalAddressSpace:
    return cast<OpenCLGlobalAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLGlobalDeviceAddressSpace:
    return cast<OpenCLGlobalDeviceAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLGlobalHostAddressSpace:
    return cast<OpenCLGlobalHostAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLIntelReqdSubGroupSize:
    return cast<OpenCLIntelReqdSubGroupSizeAttr>(this)->getSpelling();
  case attr::OpenCLKernel:
    return cast<OpenCLKernelAttr>(this)->getSpelling();
  case attr::OpenCLLocalAddressSpace:
    return cast<OpenCLLocalAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLPrivateAddressSpace:
    return cast<OpenCLPrivateAddressSpaceAttr>(this)->getSpelling();
  case attr::OpenCLUnrollHint:
    return cast<OpenCLUnrollHintAttr>(this)->getSpelling();
  case attr::OptimizeNone:
    return cast<OptimizeNoneAttr>(this)->getSpelling();
  case attr::Overloadable:
    return cast<OverloadableAttr>(this)->getSpelling();
  case attr::Override:
    return cast<OverrideAttr>(this)->getSpelling();
  case attr::Owner:
    return cast<OwnerAttr>(this)->getSpelling();
  case attr::Ownership:
    return cast<OwnershipAttr>(this)->getSpelling();
  case attr::Packed:
    return cast<PackedAttr>(this)->getSpelling();
  case attr::ParamTypestate:
    return cast<ParamTypestateAttr>(this)->getSpelling();
  case attr::Pascal:
    return cast<PascalAttr>(this)->getSpelling();
  case attr::PassObjectSize:
    return cast<PassObjectSizeAttr>(this)->getSpelling();
  case attr::PatchableFunctionEntry:
    return cast<PatchableFunctionEntryAttr>(this)->getSpelling();
  case attr::Pcs:
    return cast<PcsAttr>(this)->getSpelling();
  case attr::Pointer:
    return cast<PointerAttr>(this)->getSpelling();
  case attr::PragmaClangBSSSection:
    return cast<PragmaClangBSSSectionAttr>(this)->getSpelling();
  case attr::PragmaClangDataSection:
    return cast<PragmaClangDataSectionAttr>(this)->getSpelling();
  case attr::PragmaClangRelroSection:
    return cast<PragmaClangRelroSectionAttr>(this)->getSpelling();
  case attr::PragmaClangRodataSection:
    return cast<PragmaClangRodataSectionAttr>(this)->getSpelling();
  case attr::PragmaClangTextSection:
    return cast<PragmaClangTextSectionAttr>(this)->getSpelling();
  case attr::PreferredName:
    return cast<PreferredNameAttr>(this)->getSpelling();
  case attr::PreserveAll:
    return cast<PreserveAllAttr>(this)->getSpelling();
  case attr::PreserveMost:
    return cast<PreserveMostAttr>(this)->getSpelling();
  case attr::PtGuardedBy:
    return cast<PtGuardedByAttr>(this)->getSpelling();
  case attr::PtGuardedVar:
    return cast<PtGuardedVarAttr>(this)->getSpelling();
  case attr::Ptr32:
    return cast<Ptr32Attr>(this)->getSpelling();
  case attr::Ptr64:
    return cast<Ptr64Attr>(this)->getSpelling();
  case attr::Pure:
    return cast<PureAttr>(this)->getSpelling();
  case attr::RISCVInterrupt:
    return cast<RISCVInterruptAttr>(this)->getSpelling();
  case attr::RandomizeLayout:
    return cast<RandomizeLayoutAttr>(this)->getSpelling();
  case attr::RegCall:
    return cast<RegCallAttr>(this)->getSpelling();
  case attr::Reinitializes:
    return cast<ReinitializesAttr>(this)->getSpelling();
  case attr::ReleaseCapability:
    return cast<ReleaseCapabilityAttr>(this)->getSpelling();
  case attr::ReleaseHandle:
    return cast<ReleaseHandleAttr>(this)->getSpelling();
  case attr::RenderScriptKernel:
    return cast<RenderScriptKernelAttr>(this)->getSpelling();
  case attr::ReqdWorkGroupSize:
    return cast<ReqdWorkGroupSizeAttr>(this)->getSpelling();
  case attr::RequiresCapability:
    return cast<RequiresCapabilityAttr>(this)->getSpelling();
  case attr::Restrict:
    return cast<RestrictAttr>(this)->getSpelling();
  case attr::Retain:
    return cast<RetainAttr>(this)->getSpelling();
  case attr::ReturnTypestate:
    return cast<ReturnTypestateAttr>(this)->getSpelling();
  case attr::ReturnsNonNull:
    return cast<ReturnsNonNullAttr>(this)->getSpelling();
  case attr::ReturnsTwice:
    return cast<ReturnsTwiceAttr>(this)->getSpelling();
  case attr::SPtr:
    return cast<SPtrAttr>(this)->getSpelling();
  case attr::SYCLKernel:
    return cast<SYCLKernelAttr>(this)->getSpelling();
  case attr::SYCLSpecialClass:
    return cast<SYCLSpecialClassAttr>(this)->getSpelling();
  case attr::ScopedLockable:
    return cast<ScopedLockableAttr>(this)->getSpelling();
  case attr::Section:
    return cast<SectionAttr>(this)->getSpelling();
  case attr::SelectAny:
    return cast<SelectAnyAttr>(this)->getSpelling();
  case attr::Sentinel:
    return cast<SentinelAttr>(this)->getSpelling();
  case attr::SetTypestate:
    return cast<SetTypestateAttr>(this)->getSpelling();
  case attr::SharedTrylockFunction:
    return cast<SharedTrylockFunctionAttr>(this)->getSpelling();
  case attr::SpeculativeLoadHardening:
    return cast<SpeculativeLoadHardeningAttr>(this)->getSpelling();
  case attr::StandaloneDebug:
    return cast<StandaloneDebugAttr>(this)->getSpelling();
  case attr::StdCall:
    return cast<StdCallAttr>(this)->getSpelling();
  case attr::StrictFP:
    return cast<StrictFPAttr>(this)->getSpelling();
  case attr::StrictGuardStackCheck:
    return cast<StrictGuardStackCheckAttr>(this)->getSpelling();
  case attr::Suppress:
    return cast<SuppressAttr>(this)->getSpelling();
  case attr::SwiftAsync:
    return cast<SwiftAsyncAttr>(this)->getSpelling();
  case attr::SwiftAsyncCall:
    return cast<SwiftAsyncCallAttr>(this)->getSpelling();
  case attr::SwiftAsyncContext:
    return cast<SwiftAsyncContextAttr>(this)->getSpelling();
  case attr::SwiftAsyncError:
    return cast<SwiftAsyncErrorAttr>(this)->getSpelling();
  case attr::SwiftAsyncName:
    return cast<SwiftAsyncNameAttr>(this)->getSpelling();
  case attr::SwiftAttr:
    return cast<SwiftAttrAttr>(this)->getSpelling();
  case attr::SwiftBridge:
    return cast<SwiftBridgeAttr>(this)->getSpelling();
  case attr::SwiftBridgedTypedef:
    return cast<SwiftBridgedTypedefAttr>(this)->getSpelling();
  case attr::SwiftCall:
    return cast<SwiftCallAttr>(this)->getSpelling();
  case attr::SwiftContext:
    return cast<SwiftContextAttr>(this)->getSpelling();
  case attr::SwiftError:
    return cast<SwiftErrorAttr>(this)->getSpelling();
  case attr::SwiftErrorResult:
    return cast<SwiftErrorResultAttr>(this)->getSpelling();
  case attr::SwiftIndirectResult:
    return cast<SwiftIndirectResultAttr>(this)->getSpelling();
  case attr::SwiftName:
    return cast<SwiftNameAttr>(this)->getSpelling();
  case attr::SwiftNewType:
    return cast<SwiftNewTypeAttr>(this)->getSpelling();
  case attr::SwiftObjCMembers:
    return cast<SwiftObjCMembersAttr>(this)->getSpelling();
  case attr::SwiftPrivate:
    return cast<SwiftPrivateAttr>(this)->getSpelling();
  case attr::SysVABI:
    return cast<SysVABIAttr>(this)->getSpelling();
  case attr::TLSModel:
    return cast<TLSModelAttr>(this)->getSpelling();
  case attr::Target:
    return cast<TargetAttr>(this)->getSpelling();
  case attr::TargetClones:
    return cast<TargetClonesAttr>(this)->getSpelling();
  case attr::TestTypestate:
    return cast<TestTypestateAttr>(this)->getSpelling();
  case attr::ThisCall:
    return cast<ThisCallAttr>(this)->getSpelling();
  case attr::Thread:
    return cast<ThreadAttr>(this)->getSpelling();
  case attr::TransparentUnion:
    return cast<TransparentUnionAttr>(this)->getSpelling();
  case attr::TrivialABI:
    return cast<TrivialABIAttr>(this)->getSpelling();
  case attr::TryAcquireCapability:
    return cast<TryAcquireCapabilityAttr>(this)->getSpelling();
  case attr::TypeNonNull:
    return cast<TypeNonNullAttr>(this)->getSpelling();
  case attr::TypeNullUnspecified:
    return cast<TypeNullUnspecifiedAttr>(this)->getSpelling();
  case attr::TypeNullable:
    return cast<TypeNullableAttr>(this)->getSpelling();
  case attr::TypeNullableResult:
    return cast<TypeNullableResultAttr>(this)->getSpelling();
  case attr::TypeTagForDatatype:
    return cast<TypeTagForDatatypeAttr>(this)->getSpelling();
  case attr::TypeVisibility:
    return cast<TypeVisibilityAttr>(this)->getSpelling();
  case attr::UPtr:
    return cast<UPtrAttr>(this)->getSpelling();
  case attr::Unavailable:
    return cast<UnavailableAttr>(this)->getSpelling();
  case attr::Uninitialized:
    return cast<UninitializedAttr>(this)->getSpelling();
  case attr::Unlikely:
    return cast<UnlikelyAttr>(this)->getSpelling();
  case attr::Unused:
    return cast<UnusedAttr>(this)->getSpelling();
  case attr::UseHandle:
    return cast<UseHandleAttr>(this)->getSpelling();
  case attr::Used:
    return cast<UsedAttr>(this)->getSpelling();
  case attr::UsingIfExists:
    return cast<UsingIfExistsAttr>(this)->getSpelling();
  case attr::Uuid:
    return cast<UuidAttr>(this)->getSpelling();
  case attr::VecReturn:
    return cast<VecReturnAttr>(this)->getSpelling();
  case attr::VecTypeHint:
    return cast<VecTypeHintAttr>(this)->getSpelling();
  case attr::VectorCall:
    return cast<VectorCallAttr>(this)->getSpelling();
  case attr::Visibility:
    return cast<VisibilityAttr>(this)->getSpelling();
  case attr::WarnUnused:
    return cast<WarnUnusedAttr>(this)->getSpelling();
  case attr::WarnUnusedResult:
    return cast<WarnUnusedResultAttr>(this)->getSpelling();
  case attr::Weak:
    return cast<WeakAttr>(this)->getSpelling();
  case attr::WeakImport:
    return cast<WeakImportAttr>(this)->getSpelling();
  case attr::WeakRef:
    return cast<WeakRefAttr>(this)->getSpelling();
  case attr::WebAssemblyExportName:
    return cast<WebAssemblyExportNameAttr>(this)->getSpelling();
  case attr::WebAssemblyImportModule:
    return cast<WebAssemblyImportModuleAttr>(this)->getSpelling();
  case attr::WebAssemblyImportName:
    return cast<WebAssemblyImportNameAttr>(this)->getSpelling();
  case attr::WorkGroupSizeHint:
    return cast<WorkGroupSizeHintAttr>(this)->getSpelling();
  case attr::X86ForceAlignArgPointer:
    return cast<X86ForceAlignArgPointerAttr>(this)->getSpelling();
  case attr::XRayInstrument:
    return cast<XRayInstrumentAttr>(this)->getSpelling();
  case attr::XRayLogArgs:
    return cast<XRayLogArgsAttr>(this)->getSpelling();
  case attr::ZeroCallUsedRegs:
    return cast<ZeroCallUsedRegsAttr>(this)->getSpelling();
  }
  llvm_unreachable("Unexpected attribute kind!");
}

Attr *Attr::clone(ASTContext &C) const {
  switch (getKind()) {
  case attr::AArch64SVEPcs:
    return cast<AArch64SVEPcsAttr>(this)->clone(C);
  case attr::AArch64VectorPcs:
    return cast<AArch64VectorPcsAttr>(this)->clone(C);
  case attr::AMDGPUFlatWorkGroupSize:
    return cast<AMDGPUFlatWorkGroupSizeAttr>(this)->clone(C);
  case attr::AMDGPUKernelCall:
    return cast<AMDGPUKernelCallAttr>(this)->clone(C);
  case attr::AMDGPUNumSGPR:
    return cast<AMDGPUNumSGPRAttr>(this)->clone(C);
  case attr::AMDGPUNumVGPR:
    return cast<AMDGPUNumVGPRAttr>(this)->clone(C);
  case attr::AMDGPUWavesPerEU:
    return cast<AMDGPUWavesPerEUAttr>(this)->clone(C);
  case attr::ARMInterrupt:
    return cast<ARMInterruptAttr>(this)->clone(C);
  case attr::AVRInterrupt:
    return cast<AVRInterruptAttr>(this)->clone(C);
  case attr::AVRSignal:
    return cast<AVRSignalAttr>(this)->clone(C);
  case attr::AbiTag:
    return cast<AbiTagAttr>(this)->clone(C);
  case attr::AcquireCapability:
    return cast<AcquireCapabilityAttr>(this)->clone(C);
  case attr::AcquireHandle:
    return cast<AcquireHandleAttr>(this)->clone(C);
  case attr::AcquiredAfter:
    return cast<AcquiredAfterAttr>(this)->clone(C);
  case attr::AcquiredBefore:
    return cast<AcquiredBeforeAttr>(this)->clone(C);
  case attr::AddressSpace:
    return cast<AddressSpaceAttr>(this)->clone(C);
  case attr::Alias:
    return cast<AliasAttr>(this)->clone(C);
  case attr::AlignMac68k:
    return cast<AlignMac68kAttr>(this)->clone(C);
  case attr::AlignNatural:
    return cast<AlignNaturalAttr>(this)->clone(C);
  case attr::AlignValue:
    return cast<AlignValueAttr>(this)->clone(C);
  case attr::Aligned:
    return cast<AlignedAttr>(this)->clone(C);
  case attr::AllocAlign:
    return cast<AllocAlignAttr>(this)->clone(C);
  case attr::AllocSize:
    return cast<AllocSizeAttr>(this)->clone(C);
  case attr::AlwaysDestroy:
    return cast<AlwaysDestroyAttr>(this)->clone(C);
  case attr::AlwaysInline:
    return cast<AlwaysInlineAttr>(this)->clone(C);
  case attr::AnalyzerNoReturn:
    return cast<AnalyzerNoReturnAttr>(this)->clone(C);
  case attr::Annotate:
    return cast<AnnotateAttr>(this)->clone(C);
  case attr::AnnotateType:
    return cast<AnnotateTypeAttr>(this)->clone(C);
  case attr::AnyX86Interrupt:
    return cast<AnyX86InterruptAttr>(this)->clone(C);
  case attr::AnyX86NoCallerSavedRegisters:
    return cast<AnyX86NoCallerSavedRegistersAttr>(this)->clone(C);
  case attr::AnyX86NoCfCheck:
    return cast<AnyX86NoCfCheckAttr>(this)->clone(C);
  case attr::ArcWeakrefUnavailable:
    return cast<ArcWeakrefUnavailableAttr>(this)->clone(C);
  case attr::ArgumentWithTypeTag:
    return cast<ArgumentWithTypeTagAttr>(this)->clone(C);
  case attr::ArmBuiltinAlias:
    return cast<ArmBuiltinAliasAttr>(this)->clone(C);
  case attr::ArmMveStrictPolymorphism:
    return cast<ArmMveStrictPolymorphismAttr>(this)->clone(C);
  case attr::Artificial:
    return cast<ArtificialAttr>(this)->clone(C);
  case attr::AsmLabel:
    return cast<AsmLabelAttr>(this)->clone(C);
  case attr::AssertCapability:
    return cast<AssertCapabilityAttr>(this)->clone(C);
  case attr::AssertExclusiveLock:
    return cast<AssertExclusiveLockAttr>(this)->clone(C);
  case attr::AssertSharedLock:
    return cast<AssertSharedLockAttr>(this)->clone(C);
  case attr::AssumeAligned:
    return cast<AssumeAlignedAttr>(this)->clone(C);
  case attr::Assumption:
    return cast<AssumptionAttr>(this)->clone(C);
  case attr::Availability:
    return cast<AvailabilityAttr>(this)->clone(C);
  case attr::BPFPreserveAccessIndex:
    return cast<BPFPreserveAccessIndexAttr>(this)->clone(C);
  case attr::BTFDeclTag:
    return cast<BTFDeclTagAttr>(this)->clone(C);
  case attr::BTFTypeTag:
    return cast<BTFTypeTagAttr>(this)->clone(C);
  case attr::Blocks:
    return cast<BlocksAttr>(this)->clone(C);
  case attr::Builtin:
    return cast<BuiltinAttr>(this)->clone(C);
  case attr::BuiltinAlias:
    return cast<BuiltinAliasAttr>(this)->clone(C);
  case attr::C11NoReturn:
    return cast<C11NoReturnAttr>(this)->clone(C);
  case attr::CDecl:
    return cast<CDeclAttr>(this)->clone(C);
  case attr::CFAuditedTransfer:
    return cast<CFAuditedTransferAttr>(this)->clone(C);
  case attr::CFConsumed:
    return cast<CFConsumedAttr>(this)->clone(C);
  case attr::CFGuard:
    return cast<CFGuardAttr>(this)->clone(C);
  case attr::CFICanonicalJumpTable:
    return cast<CFICanonicalJumpTableAttr>(this)->clone(C);
  case attr::CFReturnsNotRetained:
    return cast<CFReturnsNotRetainedAttr>(this)->clone(C);
  case attr::CFReturnsRetained:
    return cast<CFReturnsRetainedAttr>(this)->clone(C);
  case attr::CFUnknownTransfer:
    return cast<CFUnknownTransferAttr>(this)->clone(C);
  case attr::CPUDispatch:
    return cast<CPUDispatchAttr>(this)->clone(C);
  case attr::CPUSpecific:
    return cast<CPUSpecificAttr>(this)->clone(C);
  case attr::CUDAConstant:
    return cast<CUDAConstantAttr>(this)->clone(C);
  case attr::CUDADevice:
    return cast<CUDADeviceAttr>(this)->clone(C);
  case attr::CUDADeviceBuiltinSurfaceType:
    return cast<CUDADeviceBuiltinSurfaceTypeAttr>(this)->clone(C);
  case attr::CUDADeviceBuiltinTextureType:
    return cast<CUDADeviceBuiltinTextureTypeAttr>(this)->clone(C);
  case attr::CUDAGlobal:
    return cast<CUDAGlobalAttr>(this)->clone(C);
  case attr::CUDAHost:
    return cast<CUDAHostAttr>(this)->clone(C);
  case attr::CUDAInvalidTarget:
    return cast<CUDAInvalidTargetAttr>(this)->clone(C);
  case attr::CUDALaunchBounds:
    return cast<CUDALaunchBoundsAttr>(this)->clone(C);
  case attr::CUDAShared:
    return cast<CUDASharedAttr>(this)->clone(C);
  case attr::CXX11NoReturn:
    return cast<CXX11NoReturnAttr>(this)->clone(C);
  case attr::CallableWhen:
    return cast<CallableWhenAttr>(this)->clone(C);
  case attr::Callback:
    return cast<CallbackAttr>(this)->clone(C);
  case attr::CalledOnce:
    return cast<CalledOnceAttr>(this)->clone(C);
  case attr::Capability:
    return cast<CapabilityAttr>(this)->clone(C);
  case attr::CapturedRecord:
    return cast<CapturedRecordAttr>(this)->clone(C);
  case attr::CarriesDependency:
    return cast<CarriesDependencyAttr>(this)->clone(C);
  case attr::Cleanup:
    return cast<CleanupAttr>(this)->clone(C);
  case attr::CmseNSCall:
    return cast<CmseNSCallAttr>(this)->clone(C);
  case attr::CmseNSEntry:
    return cast<CmseNSEntryAttr>(this)->clone(C);
  case attr::CodeSeg:
    return cast<CodeSegAttr>(this)->clone(C);
  case attr::Cold:
    return cast<ColdAttr>(this)->clone(C);
  case attr::Common:
    return cast<CommonAttr>(this)->clone(C);
  case attr::Const:
    return cast<ConstAttr>(this)->clone(C);
  case attr::ConstInit:
    return cast<ConstInitAttr>(this)->clone(C);
  case attr::Constructor:
    return cast<ConstructorAttr>(this)->clone(C);
  case attr::Consumable:
    return cast<ConsumableAttr>(this)->clone(C);
  case attr::ConsumableAutoCast:
    return cast<ConsumableAutoCastAttr>(this)->clone(C);
  case attr::ConsumableSetOnRead:
    return cast<ConsumableSetOnReadAttr>(this)->clone(C);
  case attr::Convergent:
    return cast<ConvergentAttr>(this)->clone(C);
  case attr::DLLExport:
    return cast<DLLExportAttr>(this)->clone(C);
  case attr::DLLExportStaticLocal:
    return cast<DLLExportStaticLocalAttr>(this)->clone(C);
  case attr::DLLImport:
    return cast<DLLImportAttr>(this)->clone(C);
  case attr::DLLImportStaticLocal:
    return cast<DLLImportStaticLocalAttr>(this)->clone(C);
  case attr::Deprecated:
    return cast<DeprecatedAttr>(this)->clone(C);
  case attr::Destructor:
    return cast<DestructorAttr>(this)->clone(C);
  case attr::DiagnoseAsBuiltin:
    return cast<DiagnoseAsBuiltinAttr>(this)->clone(C);
  case attr::DiagnoseIf:
    return cast<DiagnoseIfAttr>(this)->clone(C);
  case attr::DisableSanitizerInstrumentation:
    return cast<DisableSanitizerInstrumentationAttr>(this)->clone(C);
  case attr::DisableTailCalls:
    return cast<DisableTailCallsAttr>(this)->clone(C);
  case attr::EmptyBases:
    return cast<EmptyBasesAttr>(this)->clone(C);
  case attr::EnableIf:
    return cast<EnableIfAttr>(this)->clone(C);
  case attr::EnforceTCB:
    return cast<EnforceTCBAttr>(this)->clone(C);
  case attr::EnforceTCBLeaf:
    return cast<EnforceTCBLeafAttr>(this)->clone(C);
  case attr::EnumExtensibility:
    return cast<EnumExtensibilityAttr>(this)->clone(C);
  case attr::Error:
    return cast<ErrorAttr>(this)->clone(C);
  case attr::ExcludeFromExplicitInstantiation:
    return cast<ExcludeFromExplicitInstantiationAttr>(this)->clone(C);
  case attr::ExclusiveTrylockFunction:
    return cast<ExclusiveTrylockFunctionAttr>(this)->clone(C);
  case attr::ExternalSourceSymbol:
    return cast<ExternalSourceSymbolAttr>(this)->clone(C);
  case attr::FallThrough:
    return cast<FallThroughAttr>(this)->clone(C);
  case attr::FastCall:
    return cast<FastCallAttr>(this)->clone(C);
  case attr::Final:
    return cast<FinalAttr>(this)->clone(C);
  case attr::FlagEnum:
    return cast<FlagEnumAttr>(this)->clone(C);
  case attr::Flatten:
    return cast<FlattenAttr>(this)->clone(C);
  case attr::Format:
    return cast<FormatAttr>(this)->clone(C);
  case attr::FormatArg:
    return cast<FormatArgAttr>(this)->clone(C);
  case attr::FunctionReturnThunks:
    return cast<FunctionReturnThunksAttr>(this)->clone(C);
  case attr::GNUInline:
    return cast<GNUInlineAttr>(this)->clone(C);
  case attr::GuardedBy:
    return cast<GuardedByAttr>(this)->clone(C);
  case attr::GuardedVar:
    return cast<GuardedVarAttr>(this)->clone(C);
  case attr::HIPManaged:
    return cast<HIPManagedAttr>(this)->clone(C);
  case attr::HLSLNumThreads:
    return cast<HLSLNumThreadsAttr>(this)->clone(C);
  case attr::HLSLResource:
    return cast<HLSLResourceAttr>(this)->clone(C);
  case attr::HLSLResourceBinding:
    return cast<HLSLResourceBindingAttr>(this)->clone(C);
  case attr::HLSLSV_GroupIndex:
    return cast<HLSLSV_GroupIndexAttr>(this)->clone(C);
  case attr::HLSLShader:
    return cast<HLSLShaderAttr>(this)->clone(C);
  case attr::Hot:
    return cast<HotAttr>(this)->clone(C);
  case attr::IBAction:
    return cast<IBActionAttr>(this)->clone(C);
  case attr::IBOutlet:
    return cast<IBOutletAttr>(this)->clone(C);
  case attr::IBOutletCollection:
    return cast<IBOutletCollectionAttr>(this)->clone(C);
  case attr::IFunc:
    return cast<IFuncAttr>(this)->clone(C);
  case attr::InitPriority:
    return cast<InitPriorityAttr>(this)->clone(C);
  case attr::InitSeg:
    return cast<InitSegAttr>(this)->clone(C);
  case attr::IntelOclBicc:
    return cast<IntelOclBiccAttr>(this)->clone(C);
  case attr::InternalLinkage:
    return cast<InternalLinkageAttr>(this)->clone(C);
  case attr::LTOVisibilityPublic:
    return cast<LTOVisibilityPublicAttr>(this)->clone(C);
  case attr::LayoutVersion:
    return cast<LayoutVersionAttr>(this)->clone(C);
  case attr::Leaf:
    return cast<LeafAttr>(this)->clone(C);
  case attr::LifetimeBound:
    return cast<LifetimeBoundAttr>(this)->clone(C);
  case attr::Likely:
    return cast<LikelyAttr>(this)->clone(C);
  case attr::LoaderUninitialized:
    return cast<LoaderUninitializedAttr>(this)->clone(C);
  case attr::LockReturned:
    return cast<LockReturnedAttr>(this)->clone(C);
  case attr::LocksExcluded:
    return cast<LocksExcludedAttr>(this)->clone(C);
  case attr::LoopHint:
    return cast<LoopHintAttr>(this)->clone(C);
  case attr::M68kInterrupt:
    return cast<M68kInterruptAttr>(this)->clone(C);
  case attr::MIGServerRoutine:
    return cast<MIGServerRoutineAttr>(this)->clone(C);
  case attr::MSABI:
    return cast<MSABIAttr>(this)->clone(C);
  case attr::MSAllocator:
    return cast<MSAllocatorAttr>(this)->clone(C);
  case attr::MSInheritance:
    return cast<MSInheritanceAttr>(this)->clone(C);
  case attr::MSNoVTable:
    return cast<MSNoVTableAttr>(this)->clone(C);
  case attr::MSP430Interrupt:
    return cast<MSP430InterruptAttr>(this)->clone(C);
  case attr::MSStruct:
    return cast<MSStructAttr>(this)->clone(C);
  case attr::MSVtorDisp:
    return cast<MSVtorDispAttr>(this)->clone(C);
  case attr::MaxFieldAlignment:
    return cast<MaxFieldAlignmentAttr>(this)->clone(C);
  case attr::MayAlias:
    return cast<MayAliasAttr>(this)->clone(C);
  case attr::MaybeUndef:
    return cast<MaybeUndefAttr>(this)->clone(C);
  case attr::MicroMips:
    return cast<MicroMipsAttr>(this)->clone(C);
  case attr::MinSize:
    return cast<MinSizeAttr>(this)->clone(C);
  case attr::MinVectorWidth:
    return cast<MinVectorWidthAttr>(this)->clone(C);
  case attr::Mips16:
    return cast<Mips16Attr>(this)->clone(C);
  case attr::MipsInterrupt:
    return cast<MipsInterruptAttr>(this)->clone(C);
  case attr::MipsLongCall:
    return cast<MipsLongCallAttr>(this)->clone(C);
  case attr::MipsShortCall:
    return cast<MipsShortCallAttr>(this)->clone(C);
  case attr::Mode:
    return cast<ModeAttr>(this)->clone(C);
  case attr::MustTail:
    return cast<MustTailAttr>(this)->clone(C);
  case attr::NSConsumed:
    return cast<NSConsumedAttr>(this)->clone(C);
  case attr::NSConsumesSelf:
    return cast<NSConsumesSelfAttr>(this)->clone(C);
  case attr::NSErrorDomain:
    return cast<NSErrorDomainAttr>(this)->clone(C);
  case attr::NSReturnsAutoreleased:
    return cast<NSReturnsAutoreleasedAttr>(this)->clone(C);
  case attr::NSReturnsNotRetained:
    return cast<NSReturnsNotRetainedAttr>(this)->clone(C);
  case attr::NSReturnsRetained:
    return cast<NSReturnsRetainedAttr>(this)->clone(C);
  case attr::Naked:
    return cast<NakedAttr>(this)->clone(C);
  case attr::NoAlias:
    return cast<NoAliasAttr>(this)->clone(C);
  case attr::NoBuiltin:
    return cast<NoBuiltinAttr>(this)->clone(C);
  case attr::NoCommon:
    return cast<NoCommonAttr>(this)->clone(C);
  case attr::NoDebug:
    return cast<NoDebugAttr>(this)->clone(C);
  case attr::NoDeref:
    return cast<NoDerefAttr>(this)->clone(C);
  case attr::NoDestroy:
    return cast<NoDestroyAttr>(this)->clone(C);
  case attr::NoDuplicate:
    return cast<NoDuplicateAttr>(this)->clone(C);
  case attr::NoEscape:
    return cast<NoEscapeAttr>(this)->clone(C);
  case attr::NoInline:
    return cast<NoInlineAttr>(this)->clone(C);
  case attr::NoInstrumentFunction:
    return cast<NoInstrumentFunctionAttr>(this)->clone(C);
  case attr::NoMerge:
    return cast<NoMergeAttr>(this)->clone(C);
  case attr::NoMicroMips:
    return cast<NoMicroMipsAttr>(this)->clone(C);
  case attr::NoMips16:
    return cast<NoMips16Attr>(this)->clone(C);
  case attr::NoProfileFunction:
    return cast<NoProfileFunctionAttr>(this)->clone(C);
  case attr::NoRandomizeLayout:
    return cast<NoRandomizeLayoutAttr>(this)->clone(C);
  case attr::NoReturn:
    return cast<NoReturnAttr>(this)->clone(C);
  case attr::NoSanitize:
    return cast<NoSanitizeAttr>(this)->clone(C);
  case attr::NoSpeculativeLoadHardening:
    return cast<NoSpeculativeLoadHardeningAttr>(this)->clone(C);
  case attr::NoSplitStack:
    return cast<NoSplitStackAttr>(this)->clone(C);
  case attr::NoStackProtector:
    return cast<NoStackProtectorAttr>(this)->clone(C);
  case attr::NoThreadSafetyAnalysis:
    return cast<NoThreadSafetyAnalysisAttr>(this)->clone(C);
  case attr::NoThrow:
    return cast<NoThrowAttr>(this)->clone(C);
  case attr::NoUniqueAddress:
    return cast<NoUniqueAddressAttr>(this)->clone(C);
  case attr::NoUwtable:
    return cast<NoUwtableAttr>(this)->clone(C);
  case attr::NonNull:
    return cast<NonNullAttr>(this)->clone(C);
  case attr::NotTailCalled:
    return cast<NotTailCalledAttr>(this)->clone(C);
  case attr::OMPAllocateDecl:
    return cast<OMPAllocateDeclAttr>(this)->clone(C);
  case attr::OMPCaptureKind:
    return cast<OMPCaptureKindAttr>(this)->clone(C);
  case attr::OMPCaptureNoInit:
    return cast<OMPCaptureNoInitAttr>(this)->clone(C);
  case attr::OMPDeclareSimdDecl:
    return cast<OMPDeclareSimdDeclAttr>(this)->clone(C);
  case attr::OMPDeclareTargetDecl:
    return cast<OMPDeclareTargetDeclAttr>(this)->clone(C);
  case attr::OMPDeclareVariant:
    return cast<OMPDeclareVariantAttr>(this)->clone(C);
  case attr::OMPReferencedVar:
    return cast<OMPReferencedVarAttr>(this)->clone(C);
  case attr::OMPThreadPrivateDecl:
    return cast<OMPThreadPrivateDeclAttr>(this)->clone(C);
  case attr::OSConsumed:
    return cast<OSConsumedAttr>(this)->clone(C);
  case attr::OSConsumesThis:
    return cast<OSConsumesThisAttr>(this)->clone(C);
  case attr::OSReturnsNotRetained:
    return cast<OSReturnsNotRetainedAttr>(this)->clone(C);
  case attr::OSReturnsRetained:
    return cast<OSReturnsRetainedAttr>(this)->clone(C);
  case attr::OSReturnsRetainedOnNonZero:
    return cast<OSReturnsRetainedOnNonZeroAttr>(this)->clone(C);
  case attr::OSReturnsRetainedOnZero:
    return cast<OSReturnsRetainedOnZeroAttr>(this)->clone(C);
  case attr::ObjCBoxable:
    return cast<ObjCBoxableAttr>(this)->clone(C);
  case attr::ObjCBridge:
    return cast<ObjCBridgeAttr>(this)->clone(C);
  case attr::ObjCBridgeMutable:
    return cast<ObjCBridgeMutableAttr>(this)->clone(C);
  case attr::ObjCBridgeRelated:
    return cast<ObjCBridgeRelatedAttr>(this)->clone(C);
  case attr::ObjCClassStub:
    return cast<ObjCClassStubAttr>(this)->clone(C);
  case attr::ObjCDesignatedInitializer:
    return cast<ObjCDesignatedInitializerAttr>(this)->clone(C);
  case attr::ObjCDirect:
    return cast<ObjCDirectAttr>(this)->clone(C);
  case attr::ObjCDirectMembers:
    return cast<ObjCDirectMembersAttr>(this)->clone(C);
  case attr::ObjCException:
    return cast<ObjCExceptionAttr>(this)->clone(C);
  case attr::ObjCExplicitProtocolImpl:
    return cast<ObjCExplicitProtocolImplAttr>(this)->clone(C);
  case attr::ObjCExternallyRetained:
    return cast<ObjCExternallyRetainedAttr>(this)->clone(C);
  case attr::ObjCGC:
    return cast<ObjCGCAttr>(this)->clone(C);
  case attr::ObjCIndependentClass:
    return cast<ObjCIndependentClassAttr>(this)->clone(C);
  case attr::ObjCInertUnsafeUnretained:
    return cast<ObjCInertUnsafeUnretainedAttr>(this)->clone(C);
  case attr::ObjCKindOf:
    return cast<ObjCKindOfAttr>(this)->clone(C);
  case attr::ObjCMethodFamily:
    return cast<ObjCMethodFamilyAttr>(this)->clone(C);
  case attr::ObjCNSObject:
    return cast<ObjCNSObjectAttr>(this)->clone(C);
  case attr::ObjCNonLazyClass:
    return cast<ObjCNonLazyClassAttr>(this)->clone(C);
  case attr::ObjCNonRuntimeProtocol:
    return cast<ObjCNonRuntimeProtocolAttr>(this)->clone(C);
  case attr::ObjCOwnership:
    return cast<ObjCOwnershipAttr>(this)->clone(C);
  case attr::ObjCPreciseLifetime:
    return cast<ObjCPreciseLifetimeAttr>(this)->clone(C);
  case attr::ObjCRequiresPropertyDefs:
    return cast<ObjCRequiresPropertyDefsAttr>(this)->clone(C);
  case attr::ObjCRequiresSuper:
    return cast<ObjCRequiresSuperAttr>(this)->clone(C);
  case attr::ObjCReturnsInnerPointer:
    return cast<ObjCReturnsInnerPointerAttr>(this)->clone(C);
  case attr::ObjCRootClass:
    return cast<ObjCRootClassAttr>(this)->clone(C);
  case attr::ObjCRuntimeName:
    return cast<ObjCRuntimeNameAttr>(this)->clone(C);
  case attr::ObjCRuntimeVisible:
    return cast<ObjCRuntimeVisibleAttr>(this)->clone(C);
  case attr::ObjCSubclassingRestricted:
    return cast<ObjCSubclassingRestrictedAttr>(this)->clone(C);
  case attr::OpenCLAccess:
    return cast<OpenCLAccessAttr>(this)->clone(C);
  case attr::OpenCLConstantAddressSpace:
    return cast<OpenCLConstantAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLGenericAddressSpace:
    return cast<OpenCLGenericAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLGlobalAddressSpace:
    return cast<OpenCLGlobalAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLGlobalDeviceAddressSpace:
    return cast<OpenCLGlobalDeviceAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLGlobalHostAddressSpace:
    return cast<OpenCLGlobalHostAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLIntelReqdSubGroupSize:
    return cast<OpenCLIntelReqdSubGroupSizeAttr>(this)->clone(C);
  case attr::OpenCLKernel:
    return cast<OpenCLKernelAttr>(this)->clone(C);
  case attr::OpenCLLocalAddressSpace:
    return cast<OpenCLLocalAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLPrivateAddressSpace:
    return cast<OpenCLPrivateAddressSpaceAttr>(this)->clone(C);
  case attr::OpenCLUnrollHint:
    return cast<OpenCLUnrollHintAttr>(this)->clone(C);
  case attr::OptimizeNone:
    return cast<OptimizeNoneAttr>(this)->clone(C);
  case attr::Overloadable:
    return cast<OverloadableAttr>(this)->clone(C);
  case attr::Override:
    return cast<OverrideAttr>(this)->clone(C);
  case attr::Owner:
    return cast<OwnerAttr>(this)->clone(C);
  case attr::Ownership:
    return cast<OwnershipAttr>(this)->clone(C);
  case attr::Packed:
    return cast<PackedAttr>(this)->clone(C);
  case attr::ParamTypestate:
    return cast<ParamTypestateAttr>(this)->clone(C);
  case attr::Pascal:
    return cast<PascalAttr>(this)->clone(C);
  case attr::PassObjectSize:
    return cast<PassObjectSizeAttr>(this)->clone(C);
  case attr::PatchableFunctionEntry:
    return cast<PatchableFunctionEntryAttr>(this)->clone(C);
  case attr::Pcs:
    return cast<PcsAttr>(this)->clone(C);
  case attr::Pointer:
    return cast<PointerAttr>(this)->clone(C);
  case attr::PragmaClangBSSSection:
    return cast<PragmaClangBSSSectionAttr>(this)->clone(C);
  case attr::PragmaClangDataSection:
    return cast<PragmaClangDataSectionAttr>(this)->clone(C);
  case attr::PragmaClangRelroSection:
    return cast<PragmaClangRelroSectionAttr>(this)->clone(C);
  case attr::PragmaClangRodataSection:
    return cast<PragmaClangRodataSectionAttr>(this)->clone(C);
  case attr::PragmaClangTextSection:
    return cast<PragmaClangTextSectionAttr>(this)->clone(C);
  case attr::PreferredName:
    return cast<PreferredNameAttr>(this)->clone(C);
  case attr::PreserveAll:
    return cast<PreserveAllAttr>(this)->clone(C);
  case attr::PreserveMost:
    return cast<PreserveMostAttr>(this)->clone(C);
  case attr::PtGuardedBy:
    return cast<PtGuardedByAttr>(this)->clone(C);
  case attr::PtGuardedVar:
    return cast<PtGuardedVarAttr>(this)->clone(C);
  case attr::Ptr32:
    return cast<Ptr32Attr>(this)->clone(C);
  case attr::Ptr64:
    return cast<Ptr64Attr>(this)->clone(C);
  case attr::Pure:
    return cast<PureAttr>(this)->clone(C);
  case attr::RISCVInterrupt:
    return cast<RISCVInterruptAttr>(this)->clone(C);
  case attr::RandomizeLayout:
    return cast<RandomizeLayoutAttr>(this)->clone(C);
  case attr::RegCall:
    return cast<RegCallAttr>(this)->clone(C);
  case attr::Reinitializes:
    return cast<ReinitializesAttr>(this)->clone(C);
  case attr::ReleaseCapability:
    return cast<ReleaseCapabilityAttr>(this)->clone(C);
  case attr::ReleaseHandle:
    return cast<ReleaseHandleAttr>(this)->clone(C);
  case attr::RenderScriptKernel:
    return cast<RenderScriptKernelAttr>(this)->clone(C);
  case attr::ReqdWorkGroupSize:
    return cast<ReqdWorkGroupSizeAttr>(this)->clone(C);
  case attr::RequiresCapability:
    return cast<RequiresCapabilityAttr>(this)->clone(C);
  case attr::Restrict:
    return cast<RestrictAttr>(this)->clone(C);
  case attr::Retain:
    return cast<RetainAttr>(this)->clone(C);
  case attr::ReturnTypestate:
    return cast<ReturnTypestateAttr>(this)->clone(C);
  case attr::ReturnsNonNull:
    return cast<ReturnsNonNullAttr>(this)->clone(C);
  case attr::ReturnsTwice:
    return cast<ReturnsTwiceAttr>(this)->clone(C);
  case attr::SPtr:
    return cast<SPtrAttr>(this)->clone(C);
  case attr::SYCLKernel:
    return cast<SYCLKernelAttr>(this)->clone(C);
  case attr::SYCLSpecialClass:
    return cast<SYCLSpecialClassAttr>(this)->clone(C);
  case attr::ScopedLockable:
    return cast<ScopedLockableAttr>(this)->clone(C);
  case attr::Section:
    return cast<SectionAttr>(this)->clone(C);
  case attr::SelectAny:
    return cast<SelectAnyAttr>(this)->clone(C);
  case attr::Sentinel:
    return cast<SentinelAttr>(this)->clone(C);
  case attr::SetTypestate:
    return cast<SetTypestateAttr>(this)->clone(C);
  case attr::SharedTrylockFunction:
    return cast<SharedTrylockFunctionAttr>(this)->clone(C);
  case attr::SpeculativeLoadHardening:
    return cast<SpeculativeLoadHardeningAttr>(this)->clone(C);
  case attr::StandaloneDebug:
    return cast<StandaloneDebugAttr>(this)->clone(C);
  case attr::StdCall:
    return cast<StdCallAttr>(this)->clone(C);
  case attr::StrictFP:
    return cast<StrictFPAttr>(this)->clone(C);
  case attr::StrictGuardStackCheck:
    return cast<StrictGuardStackCheckAttr>(this)->clone(C);
  case attr::Suppress:
    return cast<SuppressAttr>(this)->clone(C);
  case attr::SwiftAsync:
    return cast<SwiftAsyncAttr>(this)->clone(C);
  case attr::SwiftAsyncCall:
    return cast<SwiftAsyncCallAttr>(this)->clone(C);
  case attr::SwiftAsyncContext:
    return cast<SwiftAsyncContextAttr>(this)->clone(C);
  case attr::SwiftAsyncError:
    return cast<SwiftAsyncErrorAttr>(this)->clone(C);
  case attr::SwiftAsyncName:
    return cast<SwiftAsyncNameAttr>(this)->clone(C);
  case attr::SwiftAttr:
    return cast<SwiftAttrAttr>(this)->clone(C);
  case attr::SwiftBridge:
    return cast<SwiftBridgeAttr>(this)->clone(C);
  case attr::SwiftBridgedTypedef:
    return cast<SwiftBridgedTypedefAttr>(this)->clone(C);
  case attr::SwiftCall:
    return cast<SwiftCallAttr>(this)->clone(C);
  case attr::SwiftContext:
    return cast<SwiftContextAttr>(this)->clone(C);
  case attr::SwiftError:
    return cast<SwiftErrorAttr>(this)->clone(C);
  case attr::SwiftErrorResult:
    return cast<SwiftErrorResultAttr>(this)->clone(C);
  case attr::SwiftIndirectResult:
    return cast<SwiftIndirectResultAttr>(this)->clone(C);
  case attr::SwiftName:
    return cast<SwiftNameAttr>(this)->clone(C);
  case attr::SwiftNewType:
    return cast<SwiftNewTypeAttr>(this)->clone(C);
  case attr::SwiftObjCMembers:
    return cast<SwiftObjCMembersAttr>(this)->clone(C);
  case attr::SwiftPrivate:
    return cast<SwiftPrivateAttr>(this)->clone(C);
  case attr::SysVABI:
    return cast<SysVABIAttr>(this)->clone(C);
  case attr::TLSModel:
    return cast<TLSModelAttr>(this)->clone(C);
  case attr::Target:
    return cast<TargetAttr>(this)->clone(C);
  case attr::TargetClones:
    return cast<TargetClonesAttr>(this)->clone(C);
  case attr::TestTypestate:
    return cast<TestTypestateAttr>(this)->clone(C);
  case attr::ThisCall:
    return cast<ThisCallAttr>(this)->clone(C);
  case attr::Thread:
    return cast<ThreadAttr>(this)->clone(C);
  case attr::TransparentUnion:
    return cast<TransparentUnionAttr>(this)->clone(C);
  case attr::TrivialABI:
    return cast<TrivialABIAttr>(this)->clone(C);
  case attr::TryAcquireCapability:
    return cast<TryAcquireCapabilityAttr>(this)->clone(C);
  case attr::TypeNonNull:
    return cast<TypeNonNullAttr>(this)->clone(C);
  case attr::TypeNullUnspecified:
    return cast<TypeNullUnspecifiedAttr>(this)->clone(C);
  case attr::TypeNullable:
    return cast<TypeNullableAttr>(this)->clone(C);
  case attr::TypeNullableResult:
    return cast<TypeNullableResultAttr>(this)->clone(C);
  case attr::TypeTagForDatatype:
    return cast<TypeTagForDatatypeAttr>(this)->clone(C);
  case attr::TypeVisibility:
    return cast<TypeVisibilityAttr>(this)->clone(C);
  case attr::UPtr:
    return cast<UPtrAttr>(this)->clone(C);
  case attr::Unavailable:
    return cast<UnavailableAttr>(this)->clone(C);
  case attr::Uninitialized:
    return cast<UninitializedAttr>(this)->clone(C);
  case attr::Unlikely:
    return cast<UnlikelyAttr>(this)->clone(C);
  case attr::Unused:
    return cast<UnusedAttr>(this)->clone(C);
  case attr::UseHandle:
    return cast<UseHandleAttr>(this)->clone(C);
  case attr::Used:
    return cast<UsedAttr>(this)->clone(C);
  case attr::UsingIfExists:
    return cast<UsingIfExistsAttr>(this)->clone(C);
  case attr::Uuid:
    return cast<UuidAttr>(this)->clone(C);
  case attr::VecReturn:
    return cast<VecReturnAttr>(this)->clone(C);
  case attr::VecTypeHint:
    return cast<VecTypeHintAttr>(this)->clone(C);
  case attr::VectorCall:
    return cast<VectorCallAttr>(this)->clone(C);
  case attr::Visibility:
    return cast<VisibilityAttr>(this)->clone(C);
  case attr::WarnUnused:
    return cast<WarnUnusedAttr>(this)->clone(C);
  case attr::WarnUnusedResult:
    return cast<WarnUnusedResultAttr>(this)->clone(C);
  case attr::Weak:
    return cast<WeakAttr>(this)->clone(C);
  case attr::WeakImport:
    return cast<WeakImportAttr>(this)->clone(C);
  case attr::WeakRef:
    return cast<WeakRefAttr>(this)->clone(C);
  case attr::WebAssemblyExportName:
    return cast<WebAssemblyExportNameAttr>(this)->clone(C);
  case attr::WebAssemblyImportModule:
    return cast<WebAssemblyImportModuleAttr>(this)->clone(C);
  case attr::WebAssemblyImportName:
    return cast<WebAssemblyImportNameAttr>(this)->clone(C);
  case attr::WorkGroupSizeHint:
    return cast<WorkGroupSizeHintAttr>(this)->clone(C);
  case attr::X86ForceAlignArgPointer:
    return cast<X86ForceAlignArgPointerAttr>(this)->clone(C);
  case attr::XRayInstrument:
    return cast<XRayInstrumentAttr>(this)->clone(C);
  case attr::XRayLogArgs:
    return cast<XRayLogArgsAttr>(this)->clone(C);
  case attr::ZeroCallUsedRegs:
    return cast<ZeroCallUsedRegsAttr>(this)->clone(C);
  }
  llvm_unreachable("Unexpected attribute kind!");
}

void Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  switch (getKind()) {
  case attr::AArch64SVEPcs:
    return cast<AArch64SVEPcsAttr>(this)->printPretty(OS, Policy);
  case attr::AArch64VectorPcs:
    return cast<AArch64VectorPcsAttr>(this)->printPretty(OS, Policy);
  case attr::AMDGPUFlatWorkGroupSize:
    return cast<AMDGPUFlatWorkGroupSizeAttr>(this)->printPretty(OS, Policy);
  case attr::AMDGPUKernelCall:
    return cast<AMDGPUKernelCallAttr>(this)->printPretty(OS, Policy);
  case attr::AMDGPUNumSGPR:
    return cast<AMDGPUNumSGPRAttr>(this)->printPretty(OS, Policy);
  case attr::AMDGPUNumVGPR:
    return cast<AMDGPUNumVGPRAttr>(this)->printPretty(OS, Policy);
  case attr::AMDGPUWavesPerEU:
    return cast<AMDGPUWavesPerEUAttr>(this)->printPretty(OS, Policy);
  case attr::ARMInterrupt:
    return cast<ARMInterruptAttr>(this)->printPretty(OS, Policy);
  case attr::AVRInterrupt:
    return cast<AVRInterruptAttr>(this)->printPretty(OS, Policy);
  case attr::AVRSignal:
    return cast<AVRSignalAttr>(this)->printPretty(OS, Policy);
  case attr::AbiTag:
    return cast<AbiTagAttr>(this)->printPretty(OS, Policy);
  case attr::AcquireCapability:
    return cast<AcquireCapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::AcquireHandle:
    return cast<AcquireHandleAttr>(this)->printPretty(OS, Policy);
  case attr::AcquiredAfter:
    return cast<AcquiredAfterAttr>(this)->printPretty(OS, Policy);
  case attr::AcquiredBefore:
    return cast<AcquiredBeforeAttr>(this)->printPretty(OS, Policy);
  case attr::AddressSpace:
    return cast<AddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::Alias:
    return cast<AliasAttr>(this)->printPretty(OS, Policy);
  case attr::AlignMac68k:
    return cast<AlignMac68kAttr>(this)->printPretty(OS, Policy);
  case attr::AlignNatural:
    return cast<AlignNaturalAttr>(this)->printPretty(OS, Policy);
  case attr::AlignValue:
    return cast<AlignValueAttr>(this)->printPretty(OS, Policy);
  case attr::Aligned:
    return cast<AlignedAttr>(this)->printPretty(OS, Policy);
  case attr::AllocAlign:
    return cast<AllocAlignAttr>(this)->printPretty(OS, Policy);
  case attr::AllocSize:
    return cast<AllocSizeAttr>(this)->printPretty(OS, Policy);
  case attr::AlwaysDestroy:
    return cast<AlwaysDestroyAttr>(this)->printPretty(OS, Policy);
  case attr::AlwaysInline:
    return cast<AlwaysInlineAttr>(this)->printPretty(OS, Policy);
  case attr::AnalyzerNoReturn:
    return cast<AnalyzerNoReturnAttr>(this)->printPretty(OS, Policy);
  case attr::Annotate:
    return cast<AnnotateAttr>(this)->printPretty(OS, Policy);
  case attr::AnnotateType:
    return cast<AnnotateTypeAttr>(this)->printPretty(OS, Policy);
  case attr::AnyX86Interrupt:
    return cast<AnyX86InterruptAttr>(this)->printPretty(OS, Policy);
  case attr::AnyX86NoCallerSavedRegisters:
    return cast<AnyX86NoCallerSavedRegistersAttr>(this)->printPretty(OS, Policy);
  case attr::AnyX86NoCfCheck:
    return cast<AnyX86NoCfCheckAttr>(this)->printPretty(OS, Policy);
  case attr::ArcWeakrefUnavailable:
    return cast<ArcWeakrefUnavailableAttr>(this)->printPretty(OS, Policy);
  case attr::ArgumentWithTypeTag:
    return cast<ArgumentWithTypeTagAttr>(this)->printPretty(OS, Policy);
  case attr::ArmBuiltinAlias:
    return cast<ArmBuiltinAliasAttr>(this)->printPretty(OS, Policy);
  case attr::ArmMveStrictPolymorphism:
    return cast<ArmMveStrictPolymorphismAttr>(this)->printPretty(OS, Policy);
  case attr::Artificial:
    return cast<ArtificialAttr>(this)->printPretty(OS, Policy);
  case attr::AsmLabel:
    return cast<AsmLabelAttr>(this)->printPretty(OS, Policy);
  case attr::AssertCapability:
    return cast<AssertCapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::AssertExclusiveLock:
    return cast<AssertExclusiveLockAttr>(this)->printPretty(OS, Policy);
  case attr::AssertSharedLock:
    return cast<AssertSharedLockAttr>(this)->printPretty(OS, Policy);
  case attr::AssumeAligned:
    return cast<AssumeAlignedAttr>(this)->printPretty(OS, Policy);
  case attr::Assumption:
    return cast<AssumptionAttr>(this)->printPretty(OS, Policy);
  case attr::Availability:
    return cast<AvailabilityAttr>(this)->printPretty(OS, Policy);
  case attr::BPFPreserveAccessIndex:
    return cast<BPFPreserveAccessIndexAttr>(this)->printPretty(OS, Policy);
  case attr::BTFDeclTag:
    return cast<BTFDeclTagAttr>(this)->printPretty(OS, Policy);
  case attr::BTFTypeTag:
    return cast<BTFTypeTagAttr>(this)->printPretty(OS, Policy);
  case attr::Blocks:
    return cast<BlocksAttr>(this)->printPretty(OS, Policy);
  case attr::Builtin:
    return cast<BuiltinAttr>(this)->printPretty(OS, Policy);
  case attr::BuiltinAlias:
    return cast<BuiltinAliasAttr>(this)->printPretty(OS, Policy);
  case attr::C11NoReturn:
    return cast<C11NoReturnAttr>(this)->printPretty(OS, Policy);
  case attr::CDecl:
    return cast<CDeclAttr>(this)->printPretty(OS, Policy);
  case attr::CFAuditedTransfer:
    return cast<CFAuditedTransferAttr>(this)->printPretty(OS, Policy);
  case attr::CFConsumed:
    return cast<CFConsumedAttr>(this)->printPretty(OS, Policy);
  case attr::CFGuard:
    return cast<CFGuardAttr>(this)->printPretty(OS, Policy);
  case attr::CFICanonicalJumpTable:
    return cast<CFICanonicalJumpTableAttr>(this)->printPretty(OS, Policy);
  case attr::CFReturnsNotRetained:
    return cast<CFReturnsNotRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::CFReturnsRetained:
    return cast<CFReturnsRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::CFUnknownTransfer:
    return cast<CFUnknownTransferAttr>(this)->printPretty(OS, Policy);
  case attr::CPUDispatch:
    return cast<CPUDispatchAttr>(this)->printPretty(OS, Policy);
  case attr::CPUSpecific:
    return cast<CPUSpecificAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAConstant:
    return cast<CUDAConstantAttr>(this)->printPretty(OS, Policy);
  case attr::CUDADevice:
    return cast<CUDADeviceAttr>(this)->printPretty(OS, Policy);
  case attr::CUDADeviceBuiltinSurfaceType:
    return cast<CUDADeviceBuiltinSurfaceTypeAttr>(this)->printPretty(OS, Policy);
  case attr::CUDADeviceBuiltinTextureType:
    return cast<CUDADeviceBuiltinTextureTypeAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAGlobal:
    return cast<CUDAGlobalAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAHost:
    return cast<CUDAHostAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAInvalidTarget:
    return cast<CUDAInvalidTargetAttr>(this)->printPretty(OS, Policy);
  case attr::CUDALaunchBounds:
    return cast<CUDALaunchBoundsAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAShared:
    return cast<CUDASharedAttr>(this)->printPretty(OS, Policy);
  case attr::CXX11NoReturn:
    return cast<CXX11NoReturnAttr>(this)->printPretty(OS, Policy);
  case attr::CallableWhen:
    return cast<CallableWhenAttr>(this)->printPretty(OS, Policy);
  case attr::Callback:
    return cast<CallbackAttr>(this)->printPretty(OS, Policy);
  case attr::CalledOnce:
    return cast<CalledOnceAttr>(this)->printPretty(OS, Policy);
  case attr::Capability:
    return cast<CapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::CapturedRecord:
    return cast<CapturedRecordAttr>(this)->printPretty(OS, Policy);
  case attr::CarriesDependency:
    return cast<CarriesDependencyAttr>(this)->printPretty(OS, Policy);
  case attr::Cleanup:
    return cast<CleanupAttr>(this)->printPretty(OS, Policy);
  case attr::CmseNSCall:
    return cast<CmseNSCallAttr>(this)->printPretty(OS, Policy);
  case attr::CmseNSEntry:
    return cast<CmseNSEntryAttr>(this)->printPretty(OS, Policy);
  case attr::CodeSeg:
    return cast<CodeSegAttr>(this)->printPretty(OS, Policy);
  case attr::Cold:
    return cast<ColdAttr>(this)->printPretty(OS, Policy);
  case attr::Common:
    return cast<CommonAttr>(this)->printPretty(OS, Policy);
  case attr::Const:
    return cast<ConstAttr>(this)->printPretty(OS, Policy);
  case attr::ConstInit:
    return cast<ConstInitAttr>(this)->printPretty(OS, Policy);
  case attr::Constructor:
    return cast<ConstructorAttr>(this)->printPretty(OS, Policy);
  case attr::Consumable:
    return cast<ConsumableAttr>(this)->printPretty(OS, Policy);
  case attr::ConsumableAutoCast:
    return cast<ConsumableAutoCastAttr>(this)->printPretty(OS, Policy);
  case attr::ConsumableSetOnRead:
    return cast<ConsumableSetOnReadAttr>(this)->printPretty(OS, Policy);
  case attr::Convergent:
    return cast<ConvergentAttr>(this)->printPretty(OS, Policy);
  case attr::DLLExport:
    return cast<DLLExportAttr>(this)->printPretty(OS, Policy);
  case attr::DLLExportStaticLocal:
    return cast<DLLExportStaticLocalAttr>(this)->printPretty(OS, Policy);
  case attr::DLLImport:
    return cast<DLLImportAttr>(this)->printPretty(OS, Policy);
  case attr::DLLImportStaticLocal:
    return cast<DLLImportStaticLocalAttr>(this)->printPretty(OS, Policy);
  case attr::Deprecated:
    return cast<DeprecatedAttr>(this)->printPretty(OS, Policy);
  case attr::Destructor:
    return cast<DestructorAttr>(this)->printPretty(OS, Policy);
  case attr::DiagnoseAsBuiltin:
    return cast<DiagnoseAsBuiltinAttr>(this)->printPretty(OS, Policy);
  case attr::DiagnoseIf:
    return cast<DiagnoseIfAttr>(this)->printPretty(OS, Policy);
  case attr::DisableSanitizerInstrumentation:
    return cast<DisableSanitizerInstrumentationAttr>(this)->printPretty(OS, Policy);
  case attr::DisableTailCalls:
    return cast<DisableTailCallsAttr>(this)->printPretty(OS, Policy);
  case attr::EmptyBases:
    return cast<EmptyBasesAttr>(this)->printPretty(OS, Policy);
  case attr::EnableIf:
    return cast<EnableIfAttr>(this)->printPretty(OS, Policy);
  case attr::EnforceTCB:
    return cast<EnforceTCBAttr>(this)->printPretty(OS, Policy);
  case attr::EnforceTCBLeaf:
    return cast<EnforceTCBLeafAttr>(this)->printPretty(OS, Policy);
  case attr::EnumExtensibility:
    return cast<EnumExtensibilityAttr>(this)->printPretty(OS, Policy);
  case attr::Error:
    return cast<ErrorAttr>(this)->printPretty(OS, Policy);
  case attr::ExcludeFromExplicitInstantiation:
    return cast<ExcludeFromExplicitInstantiationAttr>(this)->printPretty(OS, Policy);
  case attr::ExclusiveTrylockFunction:
    return cast<ExclusiveTrylockFunctionAttr>(this)->printPretty(OS, Policy);
  case attr::ExternalSourceSymbol:
    return cast<ExternalSourceSymbolAttr>(this)->printPretty(OS, Policy);
  case attr::FallThrough:
    return cast<FallThroughAttr>(this)->printPretty(OS, Policy);
  case attr::FastCall:
    return cast<FastCallAttr>(this)->printPretty(OS, Policy);
  case attr::Final:
    return cast<FinalAttr>(this)->printPretty(OS, Policy);
  case attr::FlagEnum:
    return cast<FlagEnumAttr>(this)->printPretty(OS, Policy);
  case attr::Flatten:
    return cast<FlattenAttr>(this)->printPretty(OS, Policy);
  case attr::Format:
    return cast<FormatAttr>(this)->printPretty(OS, Policy);
  case attr::FormatArg:
    return cast<FormatArgAttr>(this)->printPretty(OS, Policy);
  case attr::FunctionReturnThunks:
    return cast<FunctionReturnThunksAttr>(this)->printPretty(OS, Policy);
  case attr::GNUInline:
    return cast<GNUInlineAttr>(this)->printPretty(OS, Policy);
  case attr::GuardedBy:
    return cast<GuardedByAttr>(this)->printPretty(OS, Policy);
  case attr::GuardedVar:
    return cast<GuardedVarAttr>(this)->printPretty(OS, Policy);
  case attr::HIPManaged:
    return cast<HIPManagedAttr>(this)->printPretty(OS, Policy);
  case attr::HLSLNumThreads:
    return cast<HLSLNumThreadsAttr>(this)->printPretty(OS, Policy);
  case attr::HLSLResource:
    return cast<HLSLResourceAttr>(this)->printPretty(OS, Policy);
  case attr::HLSLResourceBinding:
    return cast<HLSLResourceBindingAttr>(this)->printPretty(OS, Policy);
  case attr::HLSLSV_GroupIndex:
    return cast<HLSLSV_GroupIndexAttr>(this)->printPretty(OS, Policy);
  case attr::HLSLShader:
    return cast<HLSLShaderAttr>(this)->printPretty(OS, Policy);
  case attr::Hot:
    return cast<HotAttr>(this)->printPretty(OS, Policy);
  case attr::IBAction:
    return cast<IBActionAttr>(this)->printPretty(OS, Policy);
  case attr::IBOutlet:
    return cast<IBOutletAttr>(this)->printPretty(OS, Policy);
  case attr::IBOutletCollection:
    return cast<IBOutletCollectionAttr>(this)->printPretty(OS, Policy);
  case attr::IFunc:
    return cast<IFuncAttr>(this)->printPretty(OS, Policy);
  case attr::InitPriority:
    return cast<InitPriorityAttr>(this)->printPretty(OS, Policy);
  case attr::InitSeg:
    return cast<InitSegAttr>(this)->printPretty(OS, Policy);
  case attr::IntelOclBicc:
    return cast<IntelOclBiccAttr>(this)->printPretty(OS, Policy);
  case attr::InternalLinkage:
    return cast<InternalLinkageAttr>(this)->printPretty(OS, Policy);
  case attr::LTOVisibilityPublic:
    return cast<LTOVisibilityPublicAttr>(this)->printPretty(OS, Policy);
  case attr::LayoutVersion:
    return cast<LayoutVersionAttr>(this)->printPretty(OS, Policy);
  case attr::Leaf:
    return cast<LeafAttr>(this)->printPretty(OS, Policy);
  case attr::LifetimeBound:
    return cast<LifetimeBoundAttr>(this)->printPretty(OS, Policy);
  case attr::Likely:
    return cast<LikelyAttr>(this)->printPretty(OS, Policy);
  case attr::LoaderUninitialized:
    return cast<LoaderUninitializedAttr>(this)->printPretty(OS, Policy);
  case attr::LockReturned:
    return cast<LockReturnedAttr>(this)->printPretty(OS, Policy);
  case attr::LocksExcluded:
    return cast<LocksExcludedAttr>(this)->printPretty(OS, Policy);
  case attr::LoopHint:
    return cast<LoopHintAttr>(this)->printPretty(OS, Policy);
  case attr::M68kInterrupt:
    return cast<M68kInterruptAttr>(this)->printPretty(OS, Policy);
  case attr::MIGServerRoutine:
    return cast<MIGServerRoutineAttr>(this)->printPretty(OS, Policy);
  case attr::MSABI:
    return cast<MSABIAttr>(this)->printPretty(OS, Policy);
  case attr::MSAllocator:
    return cast<MSAllocatorAttr>(this)->printPretty(OS, Policy);
  case attr::MSInheritance:
    return cast<MSInheritanceAttr>(this)->printPretty(OS, Policy);
  case attr::MSNoVTable:
    return cast<MSNoVTableAttr>(this)->printPretty(OS, Policy);
  case attr::MSP430Interrupt:
    return cast<MSP430InterruptAttr>(this)->printPretty(OS, Policy);
  case attr::MSStruct:
    return cast<MSStructAttr>(this)->printPretty(OS, Policy);
  case attr::MSVtorDisp:
    return cast<MSVtorDispAttr>(this)->printPretty(OS, Policy);
  case attr::MaxFieldAlignment:
    return cast<MaxFieldAlignmentAttr>(this)->printPretty(OS, Policy);
  case attr::MayAlias:
    return cast<MayAliasAttr>(this)->printPretty(OS, Policy);
  case attr::MaybeUndef:
    return cast<MaybeUndefAttr>(this)->printPretty(OS, Policy);
  case attr::MicroMips:
    return cast<MicroMipsAttr>(this)->printPretty(OS, Policy);
  case attr::MinSize:
    return cast<MinSizeAttr>(this)->printPretty(OS, Policy);
  case attr::MinVectorWidth:
    return cast<MinVectorWidthAttr>(this)->printPretty(OS, Policy);
  case attr::Mips16:
    return cast<Mips16Attr>(this)->printPretty(OS, Policy);
  case attr::MipsInterrupt:
    return cast<MipsInterruptAttr>(this)->printPretty(OS, Policy);
  case attr::MipsLongCall:
    return cast<MipsLongCallAttr>(this)->printPretty(OS, Policy);
  case attr::MipsShortCall:
    return cast<MipsShortCallAttr>(this)->printPretty(OS, Policy);
  case attr::Mode:
    return cast<ModeAttr>(this)->printPretty(OS, Policy);
  case attr::MustTail:
    return cast<MustTailAttr>(this)->printPretty(OS, Policy);
  case attr::NSConsumed:
    return cast<NSConsumedAttr>(this)->printPretty(OS, Policy);
  case attr::NSConsumesSelf:
    return cast<NSConsumesSelfAttr>(this)->printPretty(OS, Policy);
  case attr::NSErrorDomain:
    return cast<NSErrorDomainAttr>(this)->printPretty(OS, Policy);
  case attr::NSReturnsAutoreleased:
    return cast<NSReturnsAutoreleasedAttr>(this)->printPretty(OS, Policy);
  case attr::NSReturnsNotRetained:
    return cast<NSReturnsNotRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::NSReturnsRetained:
    return cast<NSReturnsRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::Naked:
    return cast<NakedAttr>(this)->printPretty(OS, Policy);
  case attr::NoAlias:
    return cast<NoAliasAttr>(this)->printPretty(OS, Policy);
  case attr::NoBuiltin:
    return cast<NoBuiltinAttr>(this)->printPretty(OS, Policy);
  case attr::NoCommon:
    return cast<NoCommonAttr>(this)->printPretty(OS, Policy);
  case attr::NoDebug:
    return cast<NoDebugAttr>(this)->printPretty(OS, Policy);
  case attr::NoDeref:
    return cast<NoDerefAttr>(this)->printPretty(OS, Policy);
  case attr::NoDestroy:
    return cast<NoDestroyAttr>(this)->printPretty(OS, Policy);
  case attr::NoDuplicate:
    return cast<NoDuplicateAttr>(this)->printPretty(OS, Policy);
  case attr::NoEscape:
    return cast<NoEscapeAttr>(this)->printPretty(OS, Policy);
  case attr::NoInline:
    return cast<NoInlineAttr>(this)->printPretty(OS, Policy);
  case attr::NoInstrumentFunction:
    return cast<NoInstrumentFunctionAttr>(this)->printPretty(OS, Policy);
  case attr::NoMerge:
    return cast<NoMergeAttr>(this)->printPretty(OS, Policy);
  case attr::NoMicroMips:
    return cast<NoMicroMipsAttr>(this)->printPretty(OS, Policy);
  case attr::NoMips16:
    return cast<NoMips16Attr>(this)->printPretty(OS, Policy);
  case attr::NoProfileFunction:
    return cast<NoProfileFunctionAttr>(this)->printPretty(OS, Policy);
  case attr::NoRandomizeLayout:
    return cast<NoRandomizeLayoutAttr>(this)->printPretty(OS, Policy);
  case attr::NoReturn:
    return cast<NoReturnAttr>(this)->printPretty(OS, Policy);
  case attr::NoSanitize:
    return cast<NoSanitizeAttr>(this)->printPretty(OS, Policy);
  case attr::NoSpeculativeLoadHardening:
    return cast<NoSpeculativeLoadHardeningAttr>(this)->printPretty(OS, Policy);
  case attr::NoSplitStack:
    return cast<NoSplitStackAttr>(this)->printPretty(OS, Policy);
  case attr::NoStackProtector:
    return cast<NoStackProtectorAttr>(this)->printPretty(OS, Policy);
  case attr::NoThreadSafetyAnalysis:
    return cast<NoThreadSafetyAnalysisAttr>(this)->printPretty(OS, Policy);
  case attr::NoThrow:
    return cast<NoThrowAttr>(this)->printPretty(OS, Policy);
  case attr::NoUniqueAddress:
    return cast<NoUniqueAddressAttr>(this)->printPretty(OS, Policy);
  case attr::NoUwtable:
    return cast<NoUwtableAttr>(this)->printPretty(OS, Policy);
  case attr::NonNull:
    return cast<NonNullAttr>(this)->printPretty(OS, Policy);
  case attr::NotTailCalled:
    return cast<NotTailCalledAttr>(this)->printPretty(OS, Policy);
  case attr::OMPAllocateDecl:
    return cast<OMPAllocateDeclAttr>(this)->printPretty(OS, Policy);
  case attr::OMPCaptureKind:
    return cast<OMPCaptureKindAttr>(this)->printPretty(OS, Policy);
  case attr::OMPCaptureNoInit:
    return cast<OMPCaptureNoInitAttr>(this)->printPretty(OS, Policy);
  case attr::OMPDeclareSimdDecl:
    return cast<OMPDeclareSimdDeclAttr>(this)->printPretty(OS, Policy);
  case attr::OMPDeclareTargetDecl:
    return cast<OMPDeclareTargetDeclAttr>(this)->printPretty(OS, Policy);
  case attr::OMPDeclareVariant:
    return cast<OMPDeclareVariantAttr>(this)->printPretty(OS, Policy);
  case attr::OMPReferencedVar:
    return cast<OMPReferencedVarAttr>(this)->printPretty(OS, Policy);
  case attr::OMPThreadPrivateDecl:
    return cast<OMPThreadPrivateDeclAttr>(this)->printPretty(OS, Policy);
  case attr::OSConsumed:
    return cast<OSConsumedAttr>(this)->printPretty(OS, Policy);
  case attr::OSConsumesThis:
    return cast<OSConsumesThisAttr>(this)->printPretty(OS, Policy);
  case attr::OSReturnsNotRetained:
    return cast<OSReturnsNotRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::OSReturnsRetained:
    return cast<OSReturnsRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::OSReturnsRetainedOnNonZero:
    return cast<OSReturnsRetainedOnNonZeroAttr>(this)->printPretty(OS, Policy);
  case attr::OSReturnsRetainedOnZero:
    return cast<OSReturnsRetainedOnZeroAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCBoxable:
    return cast<ObjCBoxableAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCBridge:
    return cast<ObjCBridgeAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCBridgeMutable:
    return cast<ObjCBridgeMutableAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCBridgeRelated:
    return cast<ObjCBridgeRelatedAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCClassStub:
    return cast<ObjCClassStubAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCDesignatedInitializer:
    return cast<ObjCDesignatedInitializerAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCDirect:
    return cast<ObjCDirectAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCDirectMembers:
    return cast<ObjCDirectMembersAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCException:
    return cast<ObjCExceptionAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCExplicitProtocolImpl:
    return cast<ObjCExplicitProtocolImplAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCExternallyRetained:
    return cast<ObjCExternallyRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCGC:
    return cast<ObjCGCAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCIndependentClass:
    return cast<ObjCIndependentClassAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCInertUnsafeUnretained:
    return cast<ObjCInertUnsafeUnretainedAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCKindOf:
    return cast<ObjCKindOfAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCMethodFamily:
    return cast<ObjCMethodFamilyAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCNSObject:
    return cast<ObjCNSObjectAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCNonLazyClass:
    return cast<ObjCNonLazyClassAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCNonRuntimeProtocol:
    return cast<ObjCNonRuntimeProtocolAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCOwnership:
    return cast<ObjCOwnershipAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCPreciseLifetime:
    return cast<ObjCPreciseLifetimeAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCRequiresPropertyDefs:
    return cast<ObjCRequiresPropertyDefsAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCRequiresSuper:
    return cast<ObjCRequiresSuperAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCReturnsInnerPointer:
    return cast<ObjCReturnsInnerPointerAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCRootClass:
    return cast<ObjCRootClassAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCRuntimeName:
    return cast<ObjCRuntimeNameAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCRuntimeVisible:
    return cast<ObjCRuntimeVisibleAttr>(this)->printPretty(OS, Policy);
  case attr::ObjCSubclassingRestricted:
    return cast<ObjCSubclassingRestrictedAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLAccess:
    return cast<OpenCLAccessAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLConstantAddressSpace:
    return cast<OpenCLConstantAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLGenericAddressSpace:
    return cast<OpenCLGenericAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLGlobalAddressSpace:
    return cast<OpenCLGlobalAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLGlobalDeviceAddressSpace:
    return cast<OpenCLGlobalDeviceAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLGlobalHostAddressSpace:
    return cast<OpenCLGlobalHostAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLIntelReqdSubGroupSize:
    return cast<OpenCLIntelReqdSubGroupSizeAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLKernel:
    return cast<OpenCLKernelAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLLocalAddressSpace:
    return cast<OpenCLLocalAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLPrivateAddressSpace:
    return cast<OpenCLPrivateAddressSpaceAttr>(this)->printPretty(OS, Policy);
  case attr::OpenCLUnrollHint:
    return cast<OpenCLUnrollHintAttr>(this)->printPretty(OS, Policy);
  case attr::OptimizeNone:
    return cast<OptimizeNoneAttr>(this)->printPretty(OS, Policy);
  case attr::Overloadable:
    return cast<OverloadableAttr>(this)->printPretty(OS, Policy);
  case attr::Override:
    return cast<OverrideAttr>(this)->printPretty(OS, Policy);
  case attr::Owner:
    return cast<OwnerAttr>(this)->printPretty(OS, Policy);
  case attr::Ownership:
    return cast<OwnershipAttr>(this)->printPretty(OS, Policy);
  case attr::Packed:
    return cast<PackedAttr>(this)->printPretty(OS, Policy);
  case attr::ParamTypestate:
    return cast<ParamTypestateAttr>(this)->printPretty(OS, Policy);
  case attr::Pascal:
    return cast<PascalAttr>(this)->printPretty(OS, Policy);
  case attr::PassObjectSize:
    return cast<PassObjectSizeAttr>(this)->printPretty(OS, Policy);
  case attr::PatchableFunctionEntry:
    return cast<PatchableFunctionEntryAttr>(this)->printPretty(OS, Policy);
  case attr::Pcs:
    return cast<PcsAttr>(this)->printPretty(OS, Policy);
  case attr::Pointer:
    return cast<PointerAttr>(this)->printPretty(OS, Policy);
  case attr::PragmaClangBSSSection:
    return cast<PragmaClangBSSSectionAttr>(this)->printPretty(OS, Policy);
  case attr::PragmaClangDataSection:
    return cast<PragmaClangDataSectionAttr>(this)->printPretty(OS, Policy);
  case attr::PragmaClangRelroSection:
    return cast<PragmaClangRelroSectionAttr>(this)->printPretty(OS, Policy);
  case attr::PragmaClangRodataSection:
    return cast<PragmaClangRodataSectionAttr>(this)->printPretty(OS, Policy);
  case attr::PragmaClangTextSection:
    return cast<PragmaClangTextSectionAttr>(this)->printPretty(OS, Policy);
  case attr::PreferredName:
    return cast<PreferredNameAttr>(this)->printPretty(OS, Policy);
  case attr::PreserveAll:
    return cast<PreserveAllAttr>(this)->printPretty(OS, Policy);
  case attr::PreserveMost:
    return cast<PreserveMostAttr>(this)->printPretty(OS, Policy);
  case attr::PtGuardedBy:
    return cast<PtGuardedByAttr>(this)->printPretty(OS, Policy);
  case attr::PtGuardedVar:
    return cast<PtGuardedVarAttr>(this)->printPretty(OS, Policy);
  case attr::Ptr32:
    return cast<Ptr32Attr>(this)->printPretty(OS, Policy);
  case attr::Ptr64:
    return cast<Ptr64Attr>(this)->printPretty(OS, Policy);
  case attr::Pure:
    return cast<PureAttr>(this)->printPretty(OS, Policy);
  case attr::RISCVInterrupt:
    return cast<RISCVInterruptAttr>(this)->printPretty(OS, Policy);
  case attr::RandomizeLayout:
    return cast<RandomizeLayoutAttr>(this)->printPretty(OS, Policy);
  case attr::RegCall:
    return cast<RegCallAttr>(this)->printPretty(OS, Policy);
  case attr::Reinitializes:
    return cast<ReinitializesAttr>(this)->printPretty(OS, Policy);
  case attr::ReleaseCapability:
    return cast<ReleaseCapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::ReleaseHandle:
    return cast<ReleaseHandleAttr>(this)->printPretty(OS, Policy);
  case attr::RenderScriptKernel:
    return cast<RenderScriptKernelAttr>(this)->printPretty(OS, Policy);
  case attr::ReqdWorkGroupSize:
    return cast<ReqdWorkGroupSizeAttr>(this)->printPretty(OS, Policy);
  case attr::RequiresCapability:
    return cast<RequiresCapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::Restrict:
    return cast<RestrictAttr>(this)->printPretty(OS, Policy);
  case attr::Retain:
    return cast<RetainAttr>(this)->printPretty(OS, Policy);
  case attr::ReturnTypestate:
    return cast<ReturnTypestateAttr>(this)->printPretty(OS, Policy);
  case attr::ReturnsNonNull:
    return cast<ReturnsNonNullAttr>(this)->printPretty(OS, Policy);
  case attr::ReturnsTwice:
    return cast<ReturnsTwiceAttr>(this)->printPretty(OS, Policy);
  case attr::SPtr:
    return cast<SPtrAttr>(this)->printPretty(OS, Policy);
  case attr::SYCLKernel:
    return cast<SYCLKernelAttr>(this)->printPretty(OS, Policy);
  case attr::SYCLSpecialClass:
    return cast<SYCLSpecialClassAttr>(this)->printPretty(OS, Policy);
  case attr::ScopedLockable:
    return cast<ScopedLockableAttr>(this)->printPretty(OS, Policy);
  case attr::Section:
    return cast<SectionAttr>(this)->printPretty(OS, Policy);
  case attr::SelectAny:
    return cast<SelectAnyAttr>(this)->printPretty(OS, Policy);
  case attr::Sentinel:
    return cast<SentinelAttr>(this)->printPretty(OS, Policy);
  case attr::SetTypestate:
    return cast<SetTypestateAttr>(this)->printPretty(OS, Policy);
  case attr::SharedTrylockFunction:
    return cast<SharedTrylockFunctionAttr>(this)->printPretty(OS, Policy);
  case attr::SpeculativeLoadHardening:
    return cast<SpeculativeLoadHardeningAttr>(this)->printPretty(OS, Policy);
  case attr::StandaloneDebug:
    return cast<StandaloneDebugAttr>(this)->printPretty(OS, Policy);
  case attr::StdCall:
    return cast<StdCallAttr>(this)->printPretty(OS, Policy);
  case attr::StrictFP:
    return cast<StrictFPAttr>(this)->printPretty(OS, Policy);
  case attr::StrictGuardStackCheck:
    return cast<StrictGuardStackCheckAttr>(this)->printPretty(OS, Policy);
  case attr::Suppress:
    return cast<SuppressAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsync:
    return cast<SwiftAsyncAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncCall:
    return cast<SwiftAsyncCallAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncContext:
    return cast<SwiftAsyncContextAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncError:
    return cast<SwiftAsyncErrorAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncName:
    return cast<SwiftAsyncNameAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAttr:
    return cast<SwiftAttrAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftBridge:
    return cast<SwiftBridgeAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftBridgedTypedef:
    return cast<SwiftBridgedTypedefAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftCall:
    return cast<SwiftCallAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftContext:
    return cast<SwiftContextAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftError:
    return cast<SwiftErrorAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftErrorResult:
    return cast<SwiftErrorResultAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftIndirectResult:
    return cast<SwiftIndirectResultAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftName:
    return cast<SwiftNameAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftNewType:
    return cast<SwiftNewTypeAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftObjCMembers:
    return cast<SwiftObjCMembersAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftPrivate:
    return cast<SwiftPrivateAttr>(this)->printPretty(OS, Policy);
  case attr::SysVABI:
    return cast<SysVABIAttr>(this)->printPretty(OS, Policy);
  case attr::TLSModel:
    return cast<TLSModelAttr>(this)->printPretty(OS, Policy);
  case attr::Target:
    return cast<TargetAttr>(this)->printPretty(OS, Policy);
  case attr::TargetClones:
    return cast<TargetClonesAttr>(this)->printPretty(OS, Policy);
  case attr::TestTypestate:
    return cast<TestTypestateAttr>(this)->printPretty(OS, Policy);
  case attr::ThisCall:
    return cast<ThisCallAttr>(this)->printPretty(OS, Policy);
  case attr::Thread:
    return cast<ThreadAttr>(this)->printPretty(OS, Policy);
  case attr::TransparentUnion:
    return cast<TransparentUnionAttr>(this)->printPretty(OS, Policy);
  case attr::TrivialABI:
    return cast<TrivialABIAttr>(this)->printPretty(OS, Policy);
  case attr::TryAcquireCapability:
    return cast<TryAcquireCapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNonNull:
    return cast<TypeNonNullAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNullUnspecified:
    return cast<TypeNullUnspecifiedAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNullable:
    return cast<TypeNullableAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNullableResult:
    return cast<TypeNullableResultAttr>(this)->printPretty(OS, Policy);
  case attr::TypeTagForDatatype:
    return cast<TypeTagForDatatypeAttr>(this)->printPretty(OS, Policy);
  case attr::TypeVisibility:
    return cast<TypeVisibilityAttr>(this)->printPretty(OS, Policy);
  case attr::UPtr:
    return cast<UPtrAttr>(this)->printPretty(OS, Policy);
  case attr::Unavailable:
    return cast<UnavailableAttr>(this)->printPretty(OS, Policy);
  case attr::Uninitialized:
    return cast<UninitializedAttr>(this)->printPretty(OS, Policy);
  case attr::Unlikely:
    return cast<UnlikelyAttr>(this)->printPretty(OS, Policy);
  case attr::Unused:
    return cast<UnusedAttr>(this)->printPretty(OS, Policy);
  case attr::UseHandle:
    return cast<UseHandleAttr>(this)->printPretty(OS, Policy);
  case attr::Used:
    return cast<UsedAttr>(this)->printPretty(OS, Policy);
  case attr::UsingIfExists:
    return cast<UsingIfExistsAttr>(this)->printPretty(OS, Policy);
  case attr::Uuid:
    return cast<UuidAttr>(this)->printPretty(OS, Policy);
  case attr::VecReturn:
    return cast<VecReturnAttr>(this)->printPretty(OS, Policy);
  case attr::VecTypeHint:
    return cast<VecTypeHintAttr>(this)->printPretty(OS, Policy);
  case attr::VectorCall:
    return cast<VectorCallAttr>(this)->printPretty(OS, Policy);
  case attr::Visibility:
    return cast<VisibilityAttr>(this)->printPretty(OS, Policy);
  case attr::WarnUnused:
    return cast<WarnUnusedAttr>(this)->printPretty(OS, Policy);
  case attr::WarnUnusedResult:
    return cast<WarnUnusedResultAttr>(this)->printPretty(OS, Policy);
  case attr::Weak:
    return cast<WeakAttr>(this)->printPretty(OS, Policy);
  case attr::WeakImport:
    return cast<WeakImportAttr>(this)->printPretty(OS, Policy);
  case attr::WeakRef:
    return cast<WeakRefAttr>(this)->printPretty(OS, Policy);
  case attr::WebAssemblyExportName:
    return cast<WebAssemblyExportNameAttr>(this)->printPretty(OS, Policy);
  case attr::WebAssemblyImportModule:
    return cast<WebAssemblyImportModuleAttr>(this)->printPretty(OS, Policy);
  case attr::WebAssemblyImportName:
    return cast<WebAssemblyImportNameAttr>(this)->printPretty(OS, Policy);
  case attr::WorkGroupSizeHint:
    return cast<WorkGroupSizeHintAttr>(this)->printPretty(OS, Policy);
  case attr::X86ForceAlignArgPointer:
    return cast<X86ForceAlignArgPointerAttr>(this)->printPretty(OS, Policy);
  case attr::XRayInstrument:
    return cast<XRayInstrumentAttr>(this)->printPretty(OS, Policy);
  case attr::XRayLogArgs:
    return cast<XRayLogArgsAttr>(this)->printPretty(OS, Policy);
  case attr::ZeroCallUsedRegs:
    return cast<ZeroCallUsedRegsAttr>(this)->printPretty(OS, Policy);
  }
  llvm_unreachable("Unexpected attribute kind!");
}

