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

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


// 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
             )
  : InheritableAttr(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 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 << " __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 "__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(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])
  {
    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)
  {
    if (!Annotation.empty())
      std::memcpy(annotation, Annotation.data(), annotationLength);
}





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


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


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


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

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

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

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

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

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


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


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


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


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


// 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
             )
  : InheritableAttr(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 << " __attribute__((noinline";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::noinline";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::noinline";
    OS << "]]";
    break;
  }
  case 3 : {
    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";
  }
}


// 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, true)
  {
}

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


// 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, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPAllocateDeclAttr(Ctx, CommonInfo, AllocatorType, Allocator);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

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

OMPAllocateDeclAttr *OMPAllocateDeclAttr::CreateImplicit(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, AllocatorType, Allocator, I);
}

OMPAllocateDeclAttr *OMPAllocateDeclAttr::Create(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, AllocatorType, Allocator, I);
}

OMPAllocateDeclAttr::OMPAllocateDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , AllocatorTypeTy AllocatorType
              , Expr * Allocator
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPAllocateDecl, false, false)
              , allocatorType(AllocatorType)
              , allocator(Allocator)
  {
}



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);
  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, unsigned Level, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareTargetDeclAttr(Ctx, CommonInfo, MapType, DevType, Level);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::Create(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, unsigned Level, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareTargetDeclAttr(Ctx, CommonInfo, MapType, DevType, Level);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::CreateImplicit(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, unsigned Level, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, MapType, DevType, Level, I);
}

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::Create(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, unsigned Level, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, MapType, DevType, Level, I);
}

OMPDeclareTargetDeclAttr::OMPDeclareTargetDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , MapTypeTy MapType
              , DevTypeTy DevType
              , unsigned Level
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareTargetDecl, false, false)
              , mapType(MapType)
              , devType(DevType)
              , 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, 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, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareVariantAttr(Ctx, CommonInfo, VariantFuncRef, TraitInfos);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

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

OMPDeclareVariantAttr *OMPDeclareVariantAttr::CreateImplicit(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, VariantFuncRef, TraitInfos, I);
}

OMPDeclareVariantAttr *OMPDeclareVariantAttr::Create(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, VariantFuncRef, TraitInfos, I);
}

OMPDeclareVariantAttr::OMPDeclareVariantAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * VariantFuncRef
              , OMPTraitInfo * TraitInfos
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareVariant, false, true)
              , variantFuncRef(VariantFuncRef)
              , traitInfos(TraitInfos)
  {
}





OMPDeclareVariantAttr *OMPDeclareVariantAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPDeclareVariantAttr(C, *this, variantFuncRef, traitInfos);
  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";
  }
}


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


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


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


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


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

const char *Attr::getSpelling() const {
  switch (getKind()) {
  case attr::AArch64VectorPcs:
    return cast<AArch64VectorPcsAttr>(this)->getSpelling();
  case attr::AMDGPUFlatWorkGroupSize:
    return cast<AMDGPUFlatWorkGroupSizeAttr>(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::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::Blocks:
    return cast<BlocksAttr>(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::DiagnoseIf:
    return cast<DiagnoseIfAttr>(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::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::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::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::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::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::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::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::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::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();
  }
  llvm_unreachable("Unexpected attribute kind!");
}

Attr *Attr::clone(ASTContext &C) const {
  switch (getKind()) {
  case attr::AArch64VectorPcs:
    return cast<AArch64VectorPcsAttr>(this)->clone(C);
  case attr::AMDGPUFlatWorkGroupSize:
    return cast<AMDGPUFlatWorkGroupSizeAttr>(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::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::Blocks:
    return cast<BlocksAttr>(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::DiagnoseIf:
    return cast<DiagnoseIfAttr>(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::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::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::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::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::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::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::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::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::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);
  }
  llvm_unreachable("Unexpected attribute kind!");
}

void Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  switch (getKind()) {
  case attr::AArch64VectorPcs:
    return cast<AArch64VectorPcsAttr>(this)->printPretty(OS, Policy);
  case attr::AMDGPUFlatWorkGroupSize:
    return cast<AMDGPUFlatWorkGroupSizeAttr>(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::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::Blocks:
    return cast<BlocksAttr>(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::DiagnoseIf:
    return cast<DiagnoseIfAttr>(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::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::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::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::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::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::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::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::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::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);
  }
  llvm_unreachable("Unexpected attribute kind!");
}

