/*===- 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;
  }
}
}

const char *CFGuardAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    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";
  }
}


// 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
             )
  : InheritableAttr(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("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::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";
  }
}


// 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);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

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

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

NoStackProtectorAttr::NoStackProtectorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoStackProtector, false, false)
  {
}

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

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


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


// 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, InteropType *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, InteropType *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, InteropType *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, InteropType *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
              , InteropType *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) InteropType[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
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareVariant, false, true)
              , variantFuncRef(VariantFuncRef)
              , traitInfos(TraitInfos)
              , adjustArgsNothing_Size(0), adjustArgsNothing_(nullptr)
              , adjustArgsNeedDevicePtr_Size(0), adjustArgsNeedDevicePtr_(nullptr)
              , appendArgs_Size(0), appendArgs_(nullptr)
  {
}











bool OMPDeclareVariantAttr::ConvertStrToInteropType(StringRef Val, InteropType &Out) {
  Optional<InteropType> R = llvm::StringSwitch<Optional<InteropType>>(Val)
    .Case("target", OMPDeclareVariantAttr::Target)
    .Case("targetsync", OMPDeclareVariantAttr::TargetSync)
    .Case("target,targetsync", OMPDeclareVariantAttr::Target_TargetSync)
    .Default(Optional<InteropType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPDeclareVariantAttr::ConvertInteropTypeToStr(InteropType Val) {
  switch(Val) {
  case OMPDeclareVariantAttr::Target: return "target";
  case OMPDeclareVariantAttr::TargetSync: return "targetsync";
  case OMPDeclareVariantAttr::Target_TargetSync: return "target,targetsync";
  }
  llvm_unreachable("No enumerator with that value");
}
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)";
}


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

