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


// BTFDeclTagAttr implementation

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

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

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

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

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



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

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

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


// BTFTypeTagAttr implementation

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

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

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

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

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



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

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

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


// BlocksAttr implementation

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

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

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

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

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



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

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

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

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


// BuiltinAttr implementation

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

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

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

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

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



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

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

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


// BuiltinAliasAttr implementation

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

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

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

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

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

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


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

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

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


// C11NoReturnAttr implementation

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

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

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

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

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

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

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

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


// CDeclAttr implementation

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

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

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

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

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

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

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

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


// CFAuditedTransferAttr implementation

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

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

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

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

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

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

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

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


// CFConsumedAttr implementation

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

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

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

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

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

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

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

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


// CFGuardAttr implementation

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

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

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

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

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



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

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

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

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


// CFICanonicalJumpTableAttr implementation

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

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

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

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

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

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

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

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


// CFReturnsNotRetainedAttr implementation

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

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

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

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

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

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

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

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


// CFReturnsRetainedAttr implementation

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

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

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

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

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

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

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

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


// CFUnknownTransferAttr implementation

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

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

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

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

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

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

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

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


// CPUDispatchAttr implementation

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

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

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

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

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

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



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

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

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


// CPUSpecificAttr implementation

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

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

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

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

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

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



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

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

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


// CUDAConstantAttr implementation

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

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

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

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

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

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

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

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


// CUDADeviceAttr implementation

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

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

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

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

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

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

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

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


// CUDADeviceBuiltinSurfaceTypeAttr implementation

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

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

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

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

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

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

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

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


// CUDADeviceBuiltinTextureTypeAttr implementation

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

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

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

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

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

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

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

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


// CUDAGlobalAttr implementation

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

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

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

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

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

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

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

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


// CUDAHostAttr implementation

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

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

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

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

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

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

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

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


// CUDAInvalidTargetAttr implementation

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

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

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

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

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

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

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

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


// CUDALaunchBoundsAttr implementation

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

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

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

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

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

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





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

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

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


// CUDASharedAttr implementation

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

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

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

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

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

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

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

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


// CXX11NoReturnAttr implementation

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

CXX11NoReturnAttr *CXX11NoReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) CXX11NoReturnAttr(Ctx, CommonInfo);
  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";
  }
}


// DisableSanitizerInstrumentationAttr implementation

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

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

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

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

DisableSanitizerInstrumentationAttr::DisableSanitizerInstrumentationAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DisableSanitizerInstrumentation, false, false)
  {
}

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

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

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


// DisableTailCallsAttr implementation

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

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

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

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

DisableTailCallsAttr::DisableTailCallsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::DisableTailCalls, false, false)
  {
}

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

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

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


// EmptyBasesAttr implementation

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

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

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

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

EmptyBasesAttr::EmptyBasesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EmptyBases, false, false)
  {
}

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

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

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


// EnableIfAttr implementation

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

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

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

EnableIfAttr *EnableIfAttr::Create(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Cond, Message, I);
}

EnableIfAttr::EnableIfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Cond
              , llvm::StringRef Message
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnableIf, false, false)
              , cond(Cond)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}





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

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

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


// EnforceTCBAttr implementation

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

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

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

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

EnforceTCBAttr::EnforceTCBAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef TCBName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnforceTCB, false, true)
              , tCBNameLength(TCBName.size()),tCBName(new (Ctx, 1) char[tCBNameLength])
  {
    if (!TCBName.empty())
      std::memcpy(tCBName, TCBName.data(), tCBNameLength);
}



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

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

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


// EnforceTCBLeafAttr implementation

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

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

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

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

EnforceTCBLeafAttr::EnforceTCBLeafAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef TCBName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnforceTCBLeaf, false, true)
              , tCBNameLength(TCBName.size()),tCBName(new (Ctx, 1) char[tCBNameLength])
  {
    if (!TCBName.empty())
      std::memcpy(tCBName, TCBName.data(), tCBNameLength);
}



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

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

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


// EnumExtensibilityAttr implementation

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

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

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

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

EnumExtensibilityAttr::EnumExtensibilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Kind Extensibility
             )
  : InheritableAttr(Ctx, CommonInfo, attr::EnumExtensibility, false, false)
              , extensibility(Extensibility)
  {
}



bool EnumExtensibilityAttr::ConvertStrToKind(StringRef Val, Kind &Out) {
  Optional<Kind> R = llvm::StringSwitch<Optional<Kind>>(Val)
    .Case("closed", EnumExtensibilityAttr::Closed)
    .Case("open", EnumExtensibilityAttr::Open)
    .Default(Optional<Kind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *EnumExtensibilityAttr::ConvertKindToStr(Kind Val) {
  switch(Val) {
  case EnumExtensibilityAttr::Closed: return "closed";
  case EnumExtensibilityAttr::Open: return "open";
  }
  llvm_unreachable("No enumerator with that value");
}
EnumExtensibilityAttr *EnumExtensibilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) EnumExtensibilityAttr(C, *this, extensibility);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

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


// ErrorAttr implementation

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

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

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

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

ErrorAttr::ErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef UserDiagnostic
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Error, false, false)
              , userDiagnosticLength(UserDiagnostic.size()),userDiagnostic(new (Ctx, 1) char[userDiagnosticLength])
  {
    if (!UserDiagnostic.empty())
      std::memcpy(userDiagnostic, UserDiagnostic.data(), userDiagnosticLength);
}

ErrorAttr::Spelling ErrorAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_error;
    case 1: return CXX11_gnu_error;
    case 2: return C2x_gnu_error;
    case 3: return GNU_warning;
    case 4: return CXX11_gnu_warning;
    case 5: return C2x_gnu_warning;
  }
}


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

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

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


// ExcludeFromExplicitInstantiationAttr implementation

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

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

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

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

ExcludeFromExplicitInstantiationAttr::ExcludeFromExplicitInstantiationAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExcludeFromExplicitInstantiation, false, false)
  {
}

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

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

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


// ExclusiveTrylockFunctionAttr implementation

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

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

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

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

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

ExclusiveTrylockFunctionAttr::ExclusiveTrylockFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExclusiveTrylockFunction, true, true)
              , successValue(SuccessValue)
              , args_Size(0), args_(nullptr)
  {
}





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

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

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


// ExternalSourceSymbolAttr implementation

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

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

ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Language, DefinedIn, GeneratedDeclaration, I);
}

ExternalSourceSymbolAttr *ExternalSourceSymbolAttr::Create(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Language, DefinedIn, GeneratedDeclaration, I);
}

ExternalSourceSymbolAttr::ExternalSourceSymbolAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Language
              , llvm::StringRef DefinedIn
              , bool GeneratedDeclaration
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExternalSourceSymbol, false, false)
              , languageLength(Language.size()),language(new (Ctx, 1) char[languageLength])
              , definedInLength(DefinedIn.size()),definedIn(new (Ctx, 1) char[definedInLength])
              , generatedDeclaration(GeneratedDeclaration)
  {
    if (!Language.empty())
      std::memcpy(language, Language.data(), languageLength);
    if (!DefinedIn.empty())
      std::memcpy(definedIn, DefinedIn.data(), definedInLength);
}

ExternalSourceSymbolAttr::ExternalSourceSymbolAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ExternalSourceSymbol, false, false)
              , languageLength(0),language(nullptr)
              , definedInLength(0),definedIn(nullptr)
              , generatedDeclaration()
  {
}







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

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

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


// FallThroughAttr implementation

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

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

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

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

FallThroughAttr::FallThroughAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::FallThrough, false)
  {
}

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

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

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


// FastCallAttr implementation

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

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

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

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

FastCallAttr::FastCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FastCall, false, false)
  {
}

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

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

const char *FastCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "fastcall";
  case 1:
    return "fastcall";
  case 2:
    return "fastcall";
  case 3:
    return "__fastcall";
  case 4:
    return "_fastcall";
  }
}


// FinalAttr implementation

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

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

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

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

FinalAttr::FinalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Final, false, false)
  {
}

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

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

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


// FlagEnumAttr implementation

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

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

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

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

FlagEnumAttr::FlagEnumAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FlagEnum, false, false)
  {
}

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

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

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


// FlattenAttr implementation

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

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

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

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

FlattenAttr::FlattenAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Flatten, false, false)
  {
}

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

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

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


// FormatAttr implementation

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

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

FormatAttr *FormatAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Type, FormatIdx, FirstArg, I);
}

FormatAttr *FormatAttr::Create(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Type, FormatIdx, FirstArg, I);
}

FormatAttr::FormatAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Type
              , int FormatIdx
              , int FirstArg
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Format, false, false)
              , type(Type)
              , formatIdx(FormatIdx)
              , firstArg(FirstArg)
  {
}







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

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

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


// FormatArgAttr implementation

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

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

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

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

FormatArgAttr::FormatArgAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx FormatIdx
             )
  : InheritableAttr(Ctx, CommonInfo, attr::FormatArg, false, false)
              , formatIdx(FormatIdx)
  {
}



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

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

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


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


// NoProfileFunctionAttr implementation

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

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

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

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

NoProfileFunctionAttr::NoProfileFunctionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoProfileFunction, false, false)
  {
}

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

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

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


// NoReturnAttr implementation

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

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

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

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

NoReturnAttr::NoReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoReturn, false, false)
  {
}

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

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

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


// NoSanitizeAttr implementation

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

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

NoSanitizeAttr *NoSanitizeAttr::CreateImplicit(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Sanitizers, SanitizersSize, I);
}

NoSanitizeAttr *NoSanitizeAttr::Create(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Sanitizers, SanitizersSize, I);
}

NoSanitizeAttr::NoSanitizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *Sanitizers, unsigned SanitizersSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSanitize, false, false)
              , sanitizers_Size(SanitizersSize), sanitizers_(new (Ctx, 16) StringRef[sanitizers_Size])
  {
  for (size_t I = 0, E = sanitizers_Size; I != E;
       ++I) {
    StringRef Ref = Sanitizers[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      sanitizers_[I] = StringRef(Mem, Ref.size());
    }
  }
}

NoSanitizeAttr::NoSanitizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSanitize, false, false)
              , sanitizers_Size(0), sanitizers_(nullptr)
  {
}



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

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

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


// NoSpeculativeLoadHardeningAttr implementation

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

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

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

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

NoSpeculativeLoadHardeningAttr::NoSpeculativeLoadHardeningAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSpeculativeLoadHardening, false, false)
  {
}

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

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

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


// NoSplitStackAttr implementation

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

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

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

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

NoSplitStackAttr::NoSplitStackAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoSplitStack, false, false)
  {
}

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

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

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


// NoStackProtectorAttr implementation

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

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

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

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

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

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

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

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


// NoThreadSafetyAnalysisAttr implementation

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

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

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

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

NoThreadSafetyAnalysisAttr::NoThreadSafetyAnalysisAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoThreadSafetyAnalysis, false, false)
  {
}

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

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

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


// NoThrowAttr implementation

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

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

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

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

NoThrowAttr::NoThrowAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoThrow, false, false)
  {
}

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

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

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


// NoUniqueAddressAttr implementation

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

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

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

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

NoUniqueAddressAttr::NoUniqueAddressAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NoUniqueAddress, false, false)
  {
}

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

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

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


// NonNullAttr implementation

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

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

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

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

NonNullAttr::NonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ParamIdx *Args, unsigned ArgsSize
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::NonNull, false, true)
              , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

NonNullAttr::NonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::NonNull, false, true)
              , args_Size(0), args_(nullptr)
  {
}



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

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

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


// NotTailCalledAttr implementation

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

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

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

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

NotTailCalledAttr::NotTailCalledAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::NotTailCalled, false, false)
  {
}

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

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

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


// OMPAllocateDeclAttr implementation

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

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

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

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

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



bool OMPAllocateDeclAttr::ConvertStrToAllocatorTypeTy(StringRef Val, AllocatorTypeTy &Out) {
  Optional<AllocatorTypeTy> R = llvm::StringSwitch<Optional<AllocatorTypeTy>>(Val)
    .Case("omp_null_allocator", OMPAllocateDeclAttr::OMPNullMemAlloc)
    .Case("omp_default_mem_alloc", OMPAllocateDeclAttr::OMPDefaultMemAlloc)
    .Case("omp_large_cap_mem_alloc", OMPAllocateDeclAttr::OMPLargeCapMemAlloc)
    .Case("omp_const_mem_alloc", OMPAllocateDeclAttr::OMPConstMemAlloc)
    .Case("omp_high_bw_mem_alloc", OMPAllocateDeclAttr::OMPHighBWMemAlloc)
    .Case("omp_low_lat_mem_alloc", OMPAllocateDeclAttr::OMPLowLatMemAlloc)
    .Case("omp_cgroup_mem_alloc", OMPAllocateDeclAttr::OMPCGroupMemAlloc)
    .Case("omp_pteam_mem_alloc", OMPAllocateDeclAttr::OMPPTeamMemAlloc)
    .Case("omp_thread_mem_alloc", OMPAllocateDeclAttr::OMPThreadMemAlloc)
    .Case("", OMPAllocateDeclAttr::OMPUserDefinedMemAlloc)
    .Default(Optional<AllocatorTypeTy>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorTypeTy Val) {
  switch(Val) {
  case OMPAllocateDeclAttr::OMPNullMemAlloc: return "omp_null_allocator";
  case OMPAllocateDeclAttr::OMPDefaultMemAlloc: return "omp_default_mem_alloc";
  case OMPAllocateDeclAttr::OMPLargeCapMemAlloc: return "omp_large_cap_mem_alloc";
  case OMPAllocateDeclAttr::OMPConstMemAlloc: return "omp_const_mem_alloc";
  case OMPAllocateDeclAttr::OMPHighBWMemAlloc: return "omp_high_bw_mem_alloc";
  case OMPAllocateDeclAttr::OMPLowLatMemAlloc: return "omp_low_lat_mem_alloc";
  case OMPAllocateDeclAttr::OMPCGroupMemAlloc: return "omp_cgroup_mem_alloc";
  case OMPAllocateDeclAttr::OMPPTeamMemAlloc: return "omp_pteam_mem_alloc";
  case OMPAllocateDeclAttr::OMPThreadMemAlloc: return "omp_thread_mem_alloc";
  case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc: return "";
  }
  llvm_unreachable("No enumerator with that value");
}




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

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

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


// OMPCaptureKindAttr implementation

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

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

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

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

OMPCaptureKindAttr::OMPCaptureKindAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned CaptureKindVal
             )
  : Attr(Ctx, CommonInfo, attr::OMPCaptureKind, false)
              , captureKindVal(CaptureKindVal)
  {
}



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

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

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


// OMPCaptureNoInitAttr implementation

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

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

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

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

OMPCaptureNoInitAttr::OMPCaptureNoInitAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPCaptureNoInit, false, false)
  {
}

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

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

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


// OMPDeclareSimdDeclAttr implementation

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::CreateImplicit(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareSimdDeclAttr(Ctx, CommonInfo, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::Create(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareSimdDeclAttr(Ctx, CommonInfo, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::CreateImplicit(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize, I);
}

OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::Create(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize, I);
}

OMPDeclareSimdDeclAttr::OMPDeclareSimdDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , BranchStateTy BranchState
              , Expr * Simdlen
              , Expr * *Uniforms, unsigned UniformsSize
              , Expr * *Aligneds, unsigned AlignedsSize
              , Expr * *Alignments, unsigned AlignmentsSize
              , Expr * *Linears, unsigned LinearsSize
              , unsigned *Modifiers, unsigned ModifiersSize
              , Expr * *Steps, unsigned StepsSize
             )
  : Attr(Ctx, CommonInfo, attr::OMPDeclareSimdDecl, false)
              , branchState(BranchState)
              , simdlen(Simdlen)
              , uniforms_Size(UniformsSize), uniforms_(new (Ctx, 16) Expr *[uniforms_Size])
              , aligneds_Size(AlignedsSize), aligneds_(new (Ctx, 16) Expr *[aligneds_Size])
              , alignments_Size(AlignmentsSize), alignments_(new (Ctx, 16) Expr *[alignments_Size])
              , linears_Size(LinearsSize), linears_(new (Ctx, 16) Expr *[linears_Size])
              , modifiers_Size(ModifiersSize), modifiers_(new (Ctx, 16) unsigned[modifiers_Size])
              , steps_Size(StepsSize), steps_(new (Ctx, 16) Expr *[steps_Size])
  {
  std::copy(Uniforms, Uniforms + uniforms_Size, uniforms_);
  std::copy(Aligneds, Aligneds + aligneds_Size, aligneds_);
  std::copy(Alignments, Alignments + alignments_Size, alignments_);
  std::copy(Linears, Linears + linears_Size, linears_);
  std::copy(Modifiers, Modifiers + modifiers_Size, modifiers_);
  std::copy(Steps, Steps + steps_Size, steps_);
}

OMPDeclareSimdDeclAttr::OMPDeclareSimdDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , BranchStateTy BranchState
              , Expr * Simdlen
             )
  : Attr(Ctx, CommonInfo, attr::OMPDeclareSimdDecl, false)
              , branchState(BranchState)
              , simdlen(Simdlen)
              , uniforms_Size(0), uniforms_(nullptr)
              , aligneds_Size(0), aligneds_(nullptr)
              , alignments_Size(0), alignments_(nullptr)
              , linears_Size(0), linears_(nullptr)
              , modifiers_Size(0), modifiers_(nullptr)
              , steps_Size(0), steps_(nullptr)
  {
}



bool OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(StringRef Val, BranchStateTy &Out) {
  Optional<BranchStateTy> R = llvm::StringSwitch<Optional<BranchStateTy>>(Val)
    .Case("", OMPDeclareSimdDeclAttr::BS_Undefined)
    .Case("inbranch", OMPDeclareSimdDeclAttr::BS_Inbranch)
    .Case("notinbranch", OMPDeclareSimdDeclAttr::BS_Notinbranch)
    .Default(Optional<BranchStateTy>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BranchStateTy Val) {
  switch(Val) {
  case OMPDeclareSimdDeclAttr::BS_Undefined: return "";
  case OMPDeclareSimdDeclAttr::BS_Inbranch: return "inbranch";
  case OMPDeclareSimdDeclAttr::BS_Notinbranch: return "notinbranch";
  }
  llvm_unreachable("No enumerator with that value");
}














OMPDeclareSimdDeclAttr *OMPDeclareSimdDeclAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPDeclareSimdDeclAttr(C, *this, branchState, simdlen, uniforms_, uniforms_Size, aligneds_, aligneds_Size, alignments_, alignments_Size, linears_, linears_Size, modifiers_, modifiers_Size, steps_, steps_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPDeclareSimdDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma omp declare simd";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

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


// OMPDeclareTargetDeclAttr implementation

OMPDeclareTargetDeclAttr *OMPDeclareTargetDeclAttr::CreateImplicit(ASTContext &Ctx, MapTypeTy MapType, DevTypeTy DevType, 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, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, InteropType *AppendArgs, unsigned AppendArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OMPDeclareVariantAttr(Ctx, CommonInfo, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

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

OMPDeclareVariantAttr *OMPDeclareVariantAttr::CreateImplicit(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, InteropType *AppendArgs, unsigned AppendArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize, I);
}

OMPDeclareVariantAttr *OMPDeclareVariantAttr::Create(ASTContext &Ctx, Expr * VariantFuncRef, OMPTraitInfo * TraitInfos, Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize, Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize, InteropType *AppendArgs, unsigned AppendArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, VariantFuncRef, TraitInfos, AdjustArgsNothing, AdjustArgsNothingSize, AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtrSize, AppendArgs, AppendArgsSize, I);
}

OMPDeclareVariantAttr::OMPDeclareVariantAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * VariantFuncRef
              , OMPTraitInfo * TraitInfos
              , Expr * *AdjustArgsNothing, unsigned AdjustArgsNothingSize
              , Expr * *AdjustArgsNeedDevicePtr, unsigned AdjustArgsNeedDevicePtrSize
              , InteropType *AppendArgs, unsigned AppendArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareVariant, false, true)
              , variantFuncRef(VariantFuncRef)
              , traitInfos(TraitInfos)
              , adjustArgsNothing_Size(AdjustArgsNothingSize), adjustArgsNothing_(new (Ctx, 16) Expr *[adjustArgsNothing_Size])
              , adjustArgsNeedDevicePtr_Size(AdjustArgsNeedDevicePtrSize), adjustArgsNeedDevicePtr_(new (Ctx, 16) Expr *[adjustArgsNeedDevicePtr_Size])
              , appendArgs_Size(AppendArgsSize), appendArgs_(new (Ctx, 16) InteropType[appendArgs_Size])
  {
  std::copy(AdjustArgsNothing, AdjustArgsNothing + adjustArgsNothing_Size, adjustArgsNothing_);
  std::copy(AdjustArgsNeedDevicePtr, AdjustArgsNeedDevicePtr + adjustArgsNeedDevicePtr_Size, adjustArgsNeedDevicePtr_);
  std::copy(AppendArgs, AppendArgs + appendArgs_Size, appendArgs_);
}

OMPDeclareVariantAttr::OMPDeclareVariantAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * VariantFuncRef
              , OMPTraitInfo * TraitInfos
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPDeclareVariant, false, true)
              , variantFuncRef(VariantFuncRef)
              , traitInfos(TraitInfos)
              , adjustArgsNothing_Size(0), adjustArgsNothing_(nullptr)
              , adjustArgsNeedDevicePtr_Size(0), adjustArgsNeedDevicePtr_(nullptr)
              , appendArgs_Size(0), appendArgs_(nullptr)
  {
}











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

const char *OMPDeclareVariantAttr::ConvertInteropTypeToStr(InteropType Val) {
  switch(Val) {
  case OMPDeclareVariantAttr::Target: return "target";
  case OMPDeclareVariantAttr::TargetSync: return "targetsync";
  case OMPDeclareVariantAttr::Target_TargetSync: return "target,targetsync";
  }
  llvm_unreachable("No enumerator with that value");
}
OMPDeclareVariantAttr *OMPDeclareVariantAttr::clone(ASTContext &C) const {
  auto *A = new (C) OMPDeclareVariantAttr(C, *this, variantFuncRef, traitInfos, adjustArgsNothing_, adjustArgsNothing_Size, adjustArgsNeedDevicePtr_, adjustArgsNeedDevicePtr_Size, appendArgs_, appendArgs_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OMPDeclareVariantAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << "#pragma omp declare variant";
    printPrettyPragma(OS, Policy);
    OS << "\n";    break;
  }
}
}

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


// OMPReferencedVarAttr implementation

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

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

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

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

OMPReferencedVarAttr::OMPReferencedVarAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Ref
             )
  : Attr(Ctx, CommonInfo, attr::OMPReferencedVar, false)
              , ref(Ref)
  {
}



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

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

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


// OMPThreadPrivateDeclAttr implementation

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

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

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

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

OMPThreadPrivateDeclAttr::OMPThreadPrivateDeclAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OMPThreadPrivateDecl, false, false)
  {
}

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

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

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


// OSConsumedAttr implementation

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

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

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

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

OSConsumedAttr::OSConsumedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::OSConsumed, false, false)
  {
}

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

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

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


// OSConsumesThisAttr implementation

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

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

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

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

OSConsumesThisAttr::OSConsumesThisAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSConsumesThis, false, false)
  {
}

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

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

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


// OSReturnsNotRetainedAttr implementation

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

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

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

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

OSReturnsNotRetainedAttr::OSReturnsNotRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsNotRetained, false, false)
  {
}

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

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

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


// OSReturnsRetainedAttr implementation

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

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

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

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

OSReturnsRetainedAttr::OSReturnsRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsRetained, false, false)
  {
}

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

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

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


// OSReturnsRetainedOnNonZeroAttr implementation

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

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

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

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

OSReturnsRetainedOnNonZeroAttr::OSReturnsRetainedOnNonZeroAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsRetainedOnNonZero, false, false)
  {
}

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

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

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


// OSReturnsRetainedOnZeroAttr implementation

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

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

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

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

OSReturnsRetainedOnZeroAttr::OSReturnsRetainedOnZeroAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OSReturnsRetainedOnZero, false, false)
  {
}

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

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

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


// ObjCBoxableAttr implementation

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

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

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

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

ObjCBoxableAttr::ObjCBoxableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCBoxable, false)
  {
}

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

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

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


// ObjCBridgeAttr implementation

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

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

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

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

ObjCBridgeAttr::ObjCBridgeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * BridgedType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCBridge, false, false)
              , bridgedType(BridgedType)
  {
}



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

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

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


// ObjCBridgeMutableAttr implementation

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

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

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

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

ObjCBridgeMutableAttr::ObjCBridgeMutableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * BridgedType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCBridgeMutable, false, false)
              , bridgedType(BridgedType)
  {
}



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

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

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


// ObjCBridgeRelatedAttr implementation

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

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

ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, RelatedClass, ClassMethod, InstanceMethod, I);
}

ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::Create(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, RelatedClass, ClassMethod, InstanceMethod, I);
}

ObjCBridgeRelatedAttr::ObjCBridgeRelatedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * RelatedClass
              , IdentifierInfo * ClassMethod
              , IdentifierInfo * InstanceMethod
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCBridgeRelated, false, false)
              , relatedClass(RelatedClass)
              , classMethod(ClassMethod)
              , instanceMethod(InstanceMethod)
  {
}







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

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

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


// ObjCClassStubAttr implementation

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

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

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

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

ObjCClassStubAttr::ObjCClassStubAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCClassStub, false)
  {
}

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

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

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


// ObjCDesignatedInitializerAttr implementation

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

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

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

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

ObjCDesignatedInitializerAttr::ObjCDesignatedInitializerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCDesignatedInitializer, false)
  {
}

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

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

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


// ObjCDirectAttr implementation

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

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

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

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

ObjCDirectAttr::ObjCDirectAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCDirect, false)
  {
}

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

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

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


// ObjCDirectMembersAttr implementation

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

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

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

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

ObjCDirectMembersAttr::ObjCDirectMembersAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCDirectMembers, false)
  {
}

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

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

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


// ObjCExceptionAttr implementation

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

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

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

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

ObjCExceptionAttr::ObjCExceptionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCException, false, false)
  {
}

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

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

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


// ObjCExplicitProtocolImplAttr implementation

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

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

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

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

ObjCExplicitProtocolImplAttr::ObjCExplicitProtocolImplAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCExplicitProtocolImpl, false, false)
  {
}

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

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

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


// ObjCExternallyRetainedAttr implementation

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

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

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

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

ObjCExternallyRetainedAttr::ObjCExternallyRetainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCExternallyRetained, false, false)
  {
}

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

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

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


// ObjCGCAttr implementation

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

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

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

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

ObjCGCAttr::ObjCGCAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Kind
             )
  : TypeAttr(Ctx, CommonInfo, attr::ObjCGC, false)
              , kind(Kind)
  {
}



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

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

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


// ObjCIndependentClassAttr implementation

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

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

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

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

ObjCIndependentClassAttr::ObjCIndependentClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCIndependentClass, false, false)
  {
}

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

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

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


// ObjCInertUnsafeUnretainedAttr implementation

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

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

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

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

ObjCInertUnsafeUnretainedAttr::ObjCInertUnsafeUnretainedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::ObjCInertUnsafeUnretained, false)
  {
}

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

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

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


// ObjCKindOfAttr implementation

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

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

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

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

ObjCKindOfAttr::ObjCKindOfAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::ObjCKindOf, false)
  {
}

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

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

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


// ObjCMethodFamilyAttr implementation

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

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

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

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

ObjCMethodFamilyAttr::ObjCMethodFamilyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , FamilyKind Family
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCMethodFamily, false, false)
              , family(Family)
  {
}



bool ObjCMethodFamilyAttr::ConvertStrToFamilyKind(StringRef Val, FamilyKind &Out) {
  Optional<FamilyKind> R = llvm::StringSwitch<Optional<FamilyKind>>(Val)
    .Case("none", ObjCMethodFamilyAttr::OMF_None)
    .Case("alloc", ObjCMethodFamilyAttr::OMF_alloc)
    .Case("copy", ObjCMethodFamilyAttr::OMF_copy)
    .Case("init", ObjCMethodFamilyAttr::OMF_init)
    .Case("mutableCopy", ObjCMethodFamilyAttr::OMF_mutableCopy)
    .Case("new", ObjCMethodFamilyAttr::OMF_new)
    .Default(Optional<FamilyKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *ObjCMethodFamilyAttr::ConvertFamilyKindToStr(FamilyKind Val) {
  switch(Val) {
  case ObjCMethodFamilyAttr::OMF_None: return "none";
  case ObjCMethodFamilyAttr::OMF_alloc: return "alloc";
  case ObjCMethodFamilyAttr::OMF_copy: return "copy";
  case ObjCMethodFamilyAttr::OMF_init: return "init";
  case ObjCMethodFamilyAttr::OMF_mutableCopy: return "mutableCopy";
  case ObjCMethodFamilyAttr::OMF_new: return "new";
  }
  llvm_unreachable("No enumerator with that value");
}
ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::clone(ASTContext &C) const {
  auto *A = new (C) ObjCMethodFamilyAttr(C, *this, family);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

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


// ObjCNSObjectAttr implementation

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

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

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

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

ObjCNSObjectAttr::ObjCNSObjectAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCNSObject, false, false)
  {
}

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

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

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


// ObjCNonLazyClassAttr implementation

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

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

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

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

ObjCNonLazyClassAttr::ObjCNonLazyClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCNonLazyClass, false)
  {
}

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

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

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


// ObjCNonRuntimeProtocolAttr implementation

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

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

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

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

ObjCNonRuntimeProtocolAttr::ObjCNonRuntimeProtocolAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCNonRuntimeProtocol, false)
  {
}

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

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

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


// ObjCOwnershipAttr implementation

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

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

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

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

ObjCOwnershipAttr::ObjCOwnershipAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Kind
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCOwnership, false, false)
              , kind(Kind)
  {
}



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

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

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


// ObjCPreciseLifetimeAttr implementation

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

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

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

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

ObjCPreciseLifetimeAttr::ObjCPreciseLifetimeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCPreciseLifetime, false, false)
  {
}

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

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

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


// ObjCRequiresPropertyDefsAttr implementation

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

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

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

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

ObjCRequiresPropertyDefsAttr::ObjCRequiresPropertyDefsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCRequiresPropertyDefs, false, false)
  {
}

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

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

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


// ObjCRequiresSuperAttr implementation

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

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

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

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

ObjCRequiresSuperAttr::ObjCRequiresSuperAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCRequiresSuper, false, false)
  {
}

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

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

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


// ObjCReturnsInnerPointerAttr implementation

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

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

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

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

ObjCReturnsInnerPointerAttr::ObjCReturnsInnerPointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCReturnsInnerPointer, false, false)
  {
}

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

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

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


// ObjCRootClassAttr implementation

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

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

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

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

ObjCRootClassAttr::ObjCRootClassAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCRootClass, false, false)
  {
}

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

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

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


// ObjCRuntimeNameAttr implementation

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

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

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

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

ObjCRuntimeNameAttr::ObjCRuntimeNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef MetadataName
             )
  : Attr(Ctx, CommonInfo, attr::ObjCRuntimeName, false)
              , metadataNameLength(MetadataName.size()),metadataName(new (Ctx, 1) char[metadataNameLength])
  {
    if (!MetadataName.empty())
      std::memcpy(metadataName, MetadataName.data(), metadataNameLength);
}



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

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

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


// ObjCRuntimeVisibleAttr implementation

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

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

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

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

ObjCRuntimeVisibleAttr::ObjCRuntimeVisibleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::ObjCRuntimeVisible, false)
  {
}

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

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

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


// ObjCSubclassingRestrictedAttr implementation

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

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

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

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

ObjCSubclassingRestrictedAttr::ObjCSubclassingRestrictedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ObjCSubclassingRestricted, false, false)
  {
}

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

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

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


// OpenCLAccessAttr implementation

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

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

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

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

OpenCLAccessAttr::OpenCLAccessAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::OpenCLAccess, false)
  {
}

OpenCLAccessAttr::Spelling OpenCLAccessAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_read_only;
    case 1: return Keyword_read_only;
    case 2: return Keyword_write_only;
    case 3: return Keyword_write_only;
    case 4: return Keyword_read_write;
    case 5: return Keyword_read_write;
  }
}
OpenCLAccessAttr *OpenCLAccessAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLAccessAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void OpenCLAccessAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __read_only";
    OS << "";
    break;
  }
  case 1 : {
    OS << " read_only";
    OS << "";
    break;
  }
  case 2 : {
    OS << " __write_only";
    OS << "";
    break;
  }
  case 3 : {
    OS << " write_only";
    OS << "";
    break;
  }
  case 4 : {
    OS << " __read_write";
    OS << "";
    break;
  }
  case 5 : {
    OS << " read_write";
    OS << "";
    break;
  }
}
}

const char *OpenCLAccessAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__read_only";
  case 1:
    return "read_only";
  case 2:
    return "__write_only";
  case 3:
    return "write_only";
  case 4:
    return "__read_write";
  case 5:
    return "read_write";
  }
}


// OpenCLConstantAddressSpaceAttr implementation

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

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

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

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

OpenCLConstantAddressSpaceAttr::OpenCLConstantAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLConstantAddressSpace, false)
  {
}

OpenCLConstantAddressSpaceAttr::Spelling OpenCLConstantAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_constant;
    case 1: return Keyword_constant;
    case 2: return GNU_opencl_constant;
    case 3: return CXX11_clang_opencl_constant;
    case 4: return C2x_clang_opencl_constant;
  }
}
OpenCLConstantAddressSpaceAttr *OpenCLConstantAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLConstantAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

const char *OpenCLConstantAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__constant";
  case 1:
    return "constant";
  case 2:
    return "opencl_constant";
  case 3:
    return "opencl_constant";
  case 4:
    return "opencl_constant";
  }
}


// OpenCLGenericAddressSpaceAttr implementation

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

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

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

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

OpenCLGenericAddressSpaceAttr::OpenCLGenericAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGenericAddressSpace, false)
  {
}

OpenCLGenericAddressSpaceAttr::Spelling OpenCLGenericAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_generic;
    case 1: return Keyword_generic;
    case 2: return GNU_opencl_generic;
    case 3: return CXX11_clang_opencl_generic;
    case 4: return C2x_clang_opencl_generic;
  }
}
OpenCLGenericAddressSpaceAttr *OpenCLGenericAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLGenericAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

const char *OpenCLGenericAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__generic";
  case 1:
    return "generic";
  case 2:
    return "opencl_generic";
  case 3:
    return "opencl_generic";
  case 4:
    return "opencl_generic";
  }
}


// OpenCLGlobalAddressSpaceAttr implementation

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

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

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

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

OpenCLGlobalAddressSpaceAttr::OpenCLGlobalAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGlobalAddressSpace, false)
  {
}

OpenCLGlobalAddressSpaceAttr::Spelling OpenCLGlobalAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_global;
    case 1: return Keyword_global;
    case 2: return GNU_opencl_global;
    case 3: return CXX11_clang_opencl_global;
    case 4: return C2x_clang_opencl_global;
  }
}
OpenCLGlobalAddressSpaceAttr *OpenCLGlobalAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLGlobalAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

const char *OpenCLGlobalAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__global";
  case 1:
    return "global";
  case 2:
    return "opencl_global";
  case 3:
    return "opencl_global";
  case 4:
    return "opencl_global";
  }
}


// OpenCLGlobalDeviceAddressSpaceAttr implementation

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

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

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

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

OpenCLGlobalDeviceAddressSpaceAttr::OpenCLGlobalDeviceAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGlobalDeviceAddressSpace, false)
  {
}

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

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

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


// OpenCLGlobalHostAddressSpaceAttr implementation

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

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

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

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

OpenCLGlobalHostAddressSpaceAttr::OpenCLGlobalHostAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLGlobalHostAddressSpace, false)
  {
}

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

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

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


// OpenCLIntelReqdSubGroupSizeAttr implementation

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

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

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

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

OpenCLIntelReqdSubGroupSizeAttr::OpenCLIntelReqdSubGroupSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned SubGroupSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OpenCLIntelReqdSubGroupSize, false, false)
              , subGroupSize(SubGroupSize)
  {
}



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

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

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


// OpenCLKernelAttr implementation

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

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

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

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

OpenCLKernelAttr::OpenCLKernelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OpenCLKernel, false, false)
  {
}

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

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

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


// OpenCLLocalAddressSpaceAttr implementation

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

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

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

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

OpenCLLocalAddressSpaceAttr::OpenCLLocalAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLLocalAddressSpace, false)
  {
}

OpenCLLocalAddressSpaceAttr::Spelling OpenCLLocalAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_local;
    case 1: return Keyword_local;
    case 2: return GNU_opencl_local;
    case 3: return CXX11_clang_opencl_local;
    case 4: return C2x_clang_opencl_local;
  }
}
OpenCLLocalAddressSpaceAttr *OpenCLLocalAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLLocalAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

const char *OpenCLLocalAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__local";
  case 1:
    return "local";
  case 2:
    return "opencl_local";
  case 3:
    return "opencl_local";
  case 4:
    return "opencl_local";
  }
}


// OpenCLPrivateAddressSpaceAttr implementation

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

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

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

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

OpenCLPrivateAddressSpaceAttr::OpenCLPrivateAddressSpaceAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::OpenCLPrivateAddressSpace, false)
  {
}

OpenCLPrivateAddressSpaceAttr::Spelling OpenCLPrivateAddressSpaceAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return Keyword_private;
    case 1: return Keyword_private;
    case 2: return GNU_opencl_private;
    case 3: return CXX11_clang_opencl_private;
    case 4: return C2x_clang_opencl_private;
  }
}
OpenCLPrivateAddressSpaceAttr *OpenCLPrivateAddressSpaceAttr::clone(ASTContext &C) const {
  auto *A = new (C) OpenCLPrivateAddressSpaceAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

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

const char *OpenCLPrivateAddressSpaceAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__private";
  case 1:
    return "private";
  case 2:
    return "opencl_private";
  case 3:
    return "opencl_private";
  case 4:
    return "opencl_private";
  }
}


// OpenCLUnrollHintAttr implementation

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

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

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

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

OpenCLUnrollHintAttr::OpenCLUnrollHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned UnrollHint
             )
  : StmtAttr(Ctx, CommonInfo, attr::OpenCLUnrollHint, false)
              , unrollHint(UnrollHint)
  {
}

OpenCLUnrollHintAttr::OpenCLUnrollHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::OpenCLUnrollHint, false)
              , unrollHint()
  {
}



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

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

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


// OptimizeNoneAttr implementation

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

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

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

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

OptimizeNoneAttr::OptimizeNoneAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::OptimizeNone, false, false)
  {
}

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

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

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


// OverloadableAttr implementation

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

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

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

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

OverloadableAttr::OverloadableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::Overloadable, false)
  {
}

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

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

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


// OverrideAttr implementation

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

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

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

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

OverrideAttr::OverrideAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Override, false, false)
  {
}

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

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

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


// OwnerAttr implementation

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

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

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

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

OwnerAttr::OwnerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * DerefType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Owner, false, false)
              , derefType(DerefType)
  {
}

OwnerAttr::OwnerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Owner, false, false)
              , derefType()
  {
}



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

void OwnerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[gsl::Owner";
    if (!getDerefTypeLoc())
      ++TrailingOmittedArgs;
    if (!(!getDerefTypeLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getDerefType().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

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


// OwnershipAttr implementation

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

OwnershipAttr *OwnershipAttr::Create(ASTContext &Ctx, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) OwnershipAttr(Ctx, CommonInfo, Module, Args, ArgsSize);
  return A;
}

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

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

OwnershipAttr::OwnershipAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Module
              , ParamIdx *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Ownership, false, false)
              , module(Module)
              , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

OwnershipAttr::OwnershipAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * Module
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Ownership, false, false)
              , module(Module)
              , args_Size(0), args_(nullptr)
  {
}

OwnershipAttr::Spelling OwnershipAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_ownership_holds;
    case 1: return CXX11_clang_ownership_holds;
    case 2: return C2x_clang_ownership_holds;
    case 3: return GNU_ownership_returns;
    case 4: return CXX11_clang_ownership_returns;
    case 5: return C2x_clang_ownership_returns;
    case 6: return GNU_ownership_takes;
    case 7: return CXX11_clang_ownership_takes;
    case 8: return C2x_clang_ownership_takes;
  }
}




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

void OwnershipAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((ownership_holds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::ownership_holds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::ownership_holds";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((ownership_returns";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::ownership_returns";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::ownership_returns";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 6 : {
    OS << " __attribute__((ownership_takes";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 7 : {
    OS << " [[clang::ownership_takes";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 8 : {
    OS << " [[clang::ownership_takes";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getModule() ? getModule()->getName() : "") << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val.getSourceIndex();
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *OwnershipAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "ownership_holds";
  case 1:
    return "ownership_holds";
  case 2:
    return "ownership_holds";
  case 3:
    return "ownership_returns";
  case 4:
    return "ownership_returns";
  case 5:
    return "ownership_returns";
  case 6:
    return "ownership_takes";
  case 7:
    return "ownership_takes";
  case 8:
    return "ownership_takes";
  }
}


// PackedAttr implementation

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

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

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

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

PackedAttr::PackedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Packed, false, false)
  {
}

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

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

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


// ParamTypestateAttr implementation

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

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

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

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

ParamTypestateAttr::ParamTypestateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState ParamState
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ParamTypestate, false, false)
              , paramState(ParamState)
  {
}



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

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

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

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


// PascalAttr implementation

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

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

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

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

PascalAttr::PascalAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pascal, false, false)
  {
}

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

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

const char *PascalAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pascal";
  case 1:
    return "pascal";
  case 2:
    return "pascal";
  case 3:
    return "__pascal";
  case 4:
    return "_pascal";
  }
}


// PassObjectSizeAttr implementation

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

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

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

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

PassObjectSizeAttr::PassObjectSizeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , int Type
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::PassObjectSize, false, false)
              , type(Type)
  {
}

PassObjectSizeAttr::Spelling PassObjectSizeAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_pass_object_size;
    case 1: return CXX11_clang_pass_object_size;
    case 2: return C2x_clang_pass_object_size;
    case 3: return GNU_pass_dynamic_object_size;
    case 4: return CXX11_clang_pass_dynamic_object_size;
    case 5: return C2x_clang_pass_dynamic_object_size;
  }
}


PassObjectSizeAttr *PassObjectSizeAttr::clone(ASTContext &C) const {
  auto *A = new (C) PassObjectSizeAttr(C, *this, type);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PassObjectSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pass_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::pass_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::pass_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((pass_dynamic_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::pass_dynamic_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::pass_dynamic_object_size";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getType() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PassObjectSizeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pass_object_size";
  case 1:
    return "pass_object_size";
  case 2:
    return "pass_object_size";
  case 3:
    return "pass_dynamic_object_size";
  case 4:
    return "pass_dynamic_object_size";
  case 5:
    return "pass_dynamic_object_size";
  }
}


// PatchableFunctionEntryAttr implementation

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::CreateImplicit(ASTContext &Ctx, unsigned Count, int Offset, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PatchableFunctionEntryAttr(Ctx, CommonInfo, Count, Offset);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::Create(ASTContext &Ctx, unsigned Count, int Offset, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PatchableFunctionEntryAttr(Ctx, CommonInfo, Count, Offset);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::CreateImplicit(ASTContext &Ctx, unsigned Count, int Offset, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Count, Offset, I);
}

PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::Create(ASTContext &Ctx, unsigned Count, int Offset, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Count, Offset, I);
}

PatchableFunctionEntryAttr::PatchableFunctionEntryAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Count
              , int Offset
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PatchableFunctionEntry, false, false)
              , count(Count)
              , offset(Offset)
  {
}

PatchableFunctionEntryAttr::PatchableFunctionEntryAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned Count
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PatchableFunctionEntry, false, false)
              , count(Count)
              , offset()
  {
}





PatchableFunctionEntryAttr *PatchableFunctionEntryAttr::clone(ASTContext &C) const {
  auto *A = new (C) PatchableFunctionEntryAttr(C, *this, count, offset);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PatchableFunctionEntryAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((patchable_function_entry";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCount() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::patchable_function_entry";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCount() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::patchable_function_entry";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getCount() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getOffset() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PatchableFunctionEntryAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "patchable_function_entry";
  case 1:
    return "patchable_function_entry";
  case 2:
    return "patchable_function_entry";
  }
}


// PcsAttr implementation

PcsAttr *PcsAttr::CreateImplicit(ASTContext &Ctx, PCSType PCS, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PcsAttr(Ctx, CommonInfo, PCS);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PcsAttr *PcsAttr::Create(ASTContext &Ctx, PCSType PCS, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PcsAttr(Ctx, CommonInfo, PCS);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PcsAttr *PcsAttr::CreateImplicit(ASTContext &Ctx, PCSType PCS, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, PCS, I);
}

PcsAttr *PcsAttr::Create(ASTContext &Ctx, PCSType PCS, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, PCS, I);
}

PcsAttr::PcsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , PCSType PCS
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pcs, false, false)
              , pCS(PCS)
  {
}



bool PcsAttr::ConvertStrToPCSType(StringRef Val, PCSType &Out) {
  Optional<PCSType> R = llvm::StringSwitch<Optional<PCSType>>(Val)
    .Case("aapcs", PcsAttr::AAPCS)
    .Case("aapcs-vfp", PcsAttr::AAPCS_VFP)
    .Default(Optional<PCSType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *PcsAttr::ConvertPCSTypeToStr(PCSType Val) {
  switch(Val) {
  case PcsAttr::AAPCS: return "aapcs";
  case PcsAttr::AAPCS_VFP: return "aapcs-vfp";
  }
  llvm_unreachable("No enumerator with that value");
}
PcsAttr *PcsAttr::clone(ASTContext &C) const {
  auto *A = new (C) PcsAttr(C, *this, pCS);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PcsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pcs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << PcsAttr::ConvertPCSTypeToStr(getPCS()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::pcs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << PcsAttr::ConvertPCSTypeToStr(getPCS()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::pcs";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << PcsAttr::ConvertPCSTypeToStr(getPCS()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PcsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pcs";
  case 1:
    return "pcs";
  case 2:
    return "pcs";
  }
}


// PointerAttr implementation

PointerAttr *PointerAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * DerefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PointerAttr(Ctx, CommonInfo, DerefType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PointerAttr *PointerAttr::Create(ASTContext &Ctx, TypeSourceInfo * DerefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PointerAttr(Ctx, CommonInfo, DerefType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PointerAttr *PointerAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * DerefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, DerefType, I);
}

PointerAttr *PointerAttr::Create(ASTContext &Ctx, TypeSourceInfo * DerefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, DerefType, I);
}

PointerAttr::PointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * DerefType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pointer, false, false)
              , derefType(DerefType)
  {
}

PointerAttr::PointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pointer, false, false)
              , derefType()
  {
}



PointerAttr *PointerAttr::clone(ASTContext &C) const {
  auto *A = new (C) PointerAttr(C, *this, derefType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[gsl::Pointer";
    if (!getDerefTypeLoc())
      ++TrailingOmittedArgs;
    if (!(!getDerefTypeLoc())) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getDerefType().getAsString() << "";
    }
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PointerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "Pointer";
  }
}


// PragmaClangBSSSectionAttr implementation

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangBSSSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangBSSSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangBSSSectionAttr::PragmaClangBSSSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangBSSSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangBSSSectionAttr *PragmaClangBSSSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangBSSSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangBSSSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangBSSSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangDataSectionAttr implementation

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangDataSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangDataSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangDataSectionAttr::PragmaClangDataSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangDataSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangDataSectionAttr *PragmaClangDataSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangDataSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangDataSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangDataSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangRelroSectionAttr implementation

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRelroSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRelroSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangRelroSectionAttr::PragmaClangRelroSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangRelroSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangRelroSectionAttr *PragmaClangRelroSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangRelroSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangRelroSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangRelroSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangRodataSectionAttr implementation

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRodataSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangRodataSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangRodataSectionAttr::PragmaClangRodataSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangRodataSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangRodataSectionAttr *PragmaClangRodataSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangRodataSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangRodataSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangRodataSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PragmaClangTextSectionAttr implementation

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangTextSectionAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PragmaClangTextSectionAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

PragmaClangTextSectionAttr::PragmaClangTextSectionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PragmaClangTextSection, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



PragmaClangTextSectionAttr *PragmaClangTextSectionAttr::clone(ASTContext &C) const {
  auto *A = new (C) PragmaClangTextSectionAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PragmaClangTextSectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
}

const char *PragmaClangTextSectionAttr::getSpelling() const {
  return "(No spelling)";
}


// PreferredNameAttr implementation

PreferredNameAttr *PreferredNameAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypedefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreferredNameAttr(Ctx, CommonInfo, TypedefType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreferredNameAttr *PreferredNameAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypedefType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreferredNameAttr(Ctx, CommonInfo, TypedefType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreferredNameAttr *PreferredNameAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypedefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TypedefType, I);
}

PreferredNameAttr *PreferredNameAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypedefType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TypedefType, I);
}

PreferredNameAttr::PreferredNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * TypedefType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PreferredName, false, true)
              , typedefType(TypedefType)
  {
}



PreferredNameAttr *PreferredNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) PreferredNameAttr(C, *this, typedefType);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PreferredNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preferred_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypedefType().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preferred_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypedefType().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *PreferredNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preferred_name";
  case 1:
    return "preferred_name";
  }
}


// PreserveAllAttr implementation

PreserveAllAttr *PreserveAllAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveAllAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveAllAttr *PreserveAllAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveAllAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveAllAttr *PreserveAllAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PreserveAllAttr *PreserveAllAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PreserveAllAttr::PreserveAllAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PreserveAll, false, false)
  {
}

PreserveAllAttr *PreserveAllAttr::clone(ASTContext &C) const {
  auto *A = new (C) PreserveAllAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PreserveAllAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preserve_all";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preserve_all";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::preserve_all";
    OS << "]]";
    break;
  }
}
}

const char *PreserveAllAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preserve_all";
  case 1:
    return "preserve_all";
  case 2:
    return "preserve_all";
  }
}


// PreserveMostAttr implementation

PreserveMostAttr *PreserveMostAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveMostAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveMostAttr *PreserveMostAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PreserveMostAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PreserveMostAttr *PreserveMostAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PreserveMostAttr *PreserveMostAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PreserveMostAttr::PreserveMostAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PreserveMost, false, false)
  {
}

PreserveMostAttr *PreserveMostAttr::clone(ASTContext &C) const {
  auto *A = new (C) PreserveMostAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PreserveMostAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((preserve_most";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::preserve_most";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::preserve_most";
    OS << "]]";
    break;
  }
}
}

const char *PreserveMostAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "preserve_most";
  case 1:
    return "preserve_most";
  case 2:
    return "preserve_most";
  }
}


// PtGuardedByAttr implementation

PtGuardedByAttr *PtGuardedByAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedByAttr(Ctx, CommonInfo, Arg);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedByAttr *PtGuardedByAttr::Create(ASTContext &Ctx, Expr * Arg, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedByAttr(Ctx, CommonInfo, Arg);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedByAttr *PtGuardedByAttr::CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Arg, I);
}

PtGuardedByAttr *PtGuardedByAttr::Create(ASTContext &Ctx, Expr * Arg, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Arg, I);
}

PtGuardedByAttr::PtGuardedByAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * Arg
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PtGuardedBy, true, true)
              , arg(Arg)
  {
}



PtGuardedByAttr *PtGuardedByAttr::clone(ASTContext &C) const {
  auto *A = new (C) PtGuardedByAttr(C, *this, arg);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PtGuardedByAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pt_guarded_by";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArg() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *PtGuardedByAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pt_guarded_by";
  }
}


// PtGuardedVarAttr implementation

PtGuardedVarAttr *PtGuardedVarAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedVarAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedVarAttr *PtGuardedVarAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PtGuardedVarAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PtGuardedVarAttr *PtGuardedVarAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PtGuardedVarAttr *PtGuardedVarAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PtGuardedVarAttr::PtGuardedVarAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::PtGuardedVar, false, false)
  {
}

PtGuardedVarAttr *PtGuardedVarAttr::clone(ASTContext &C) const {
  auto *A = new (C) PtGuardedVarAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PtGuardedVarAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pt_guarded_var";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::pt_guarded_var";
    OS << "]]";
    break;
  }
}
}

const char *PtGuardedVarAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pt_guarded_var";
  case 1:
    return "pt_guarded_var";
  }
}


// Ptr32Attr implementation

Ptr32Attr *Ptr32Attr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr32Attr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr32Attr *Ptr32Attr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr32Attr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr32Attr *Ptr32Attr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

Ptr32Attr *Ptr32Attr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

Ptr32Attr::Ptr32Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::Ptr32, false)
  {
}

Ptr32Attr *Ptr32Attr::clone(ASTContext &C) const {
  auto *A = new (C) Ptr32Attr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void Ptr32Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __ptr32";
    OS << "";
    break;
  }
}
}

const char *Ptr32Attr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__ptr32";
  }
}


// Ptr64Attr implementation

Ptr64Attr *Ptr64Attr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr64Attr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr64Attr *Ptr64Attr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) Ptr64Attr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

Ptr64Attr *Ptr64Attr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

Ptr64Attr *Ptr64Attr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

Ptr64Attr::Ptr64Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::Ptr64, false)
  {
}

Ptr64Attr *Ptr64Attr::clone(ASTContext &C) const {
  auto *A = new (C) Ptr64Attr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void Ptr64Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __ptr64";
    OS << "";
    break;
  }
}
}

const char *Ptr64Attr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__ptr64";
  }
}


// PureAttr implementation

PureAttr *PureAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PureAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PureAttr *PureAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) PureAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

PureAttr *PureAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

PureAttr *PureAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

PureAttr::PureAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Pure, false, false)
  {
}

PureAttr *PureAttr::clone(ASTContext &C) const {
  auto *A = new (C) PureAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void PureAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((pure";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::pure";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::pure";
    OS << "]]";
    break;
  }
}
}

const char *PureAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "pure";
  case 1:
    return "pure";
  case 2:
    return "pure";
  }
}


// RISCVInterruptAttr implementation

RISCVInterruptAttr *RISCVInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RISCVInterruptAttr(Ctx, CommonInfo, Interrupt);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RISCVInterruptAttr *RISCVInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) RISCVInterruptAttr(Ctx, CommonInfo, Interrupt);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

RISCVInterruptAttr *RISCVInterruptAttr::CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Interrupt, I);
}

RISCVInterruptAttr *RISCVInterruptAttr::Create(ASTContext &Ctx, InterruptType Interrupt, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Interrupt, I);
}

RISCVInterruptAttr::RISCVInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , InterruptType Interrupt
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RISCVInterrupt, false, false)
              , interrupt(Interrupt)
  {
}

RISCVInterruptAttr::RISCVInterruptAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::RISCVInterrupt, false, false)
              , interrupt(InterruptType(0))
  {
}



bool RISCVInterruptAttr::ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
  Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
    .Case("user", RISCVInterruptAttr::user)
    .Case("supervisor", RISCVInterruptAttr::supervisor)
    .Case("machine", RISCVInterruptAttr::machine)
    .Default(Optional<InterruptType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *RISCVInterruptAttr::ConvertInterruptTypeToStr(InterruptType Val) {
  switch(Val) {
  case RISCVInterruptAttr::user: return "user";
  case RISCVInterruptAttr::supervisor: return "supervisor";
  case RISCVInterruptAttr::machine: return "machine";
  }
  llvm_unreachable("No enumerator with that value");
}
RISCVInterruptAttr *RISCVInterruptAttr::clone(ASTContext &C) const {
  auto *A = new (C) RISCVInterruptAttr(C, *this, interrupt);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void RISCVInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << RISCVInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << RISCVInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::interrupt";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << RISCVInterruptAttr::ConvertInterruptTypeToStr(getInterrupt()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *RISCVInterruptAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "interrupt";
  case 1:
    return "interrupt";
  case 2:
    return "interrupt";
  }
}


// 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";
  }
}


// SwiftAsyncCallAttr implementation

SwiftAsyncCallAttr *SwiftAsyncCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftAsyncCallAttr::SwiftAsyncCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncCall, false, false)
  {
}

SwiftAsyncCallAttr *SwiftAsyncCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swiftasynccall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swiftasynccall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swiftasynccall";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swiftasynccall";
  case 1:
    return "swiftasynccall";
  case 2:
    return "swiftasynccall";
  }
}


// SwiftAsyncContextAttr implementation

SwiftAsyncContextAttr *SwiftAsyncContextAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncContextAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncContextAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftAsyncContextAttr::SwiftAsyncContextAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftAsyncContext, false, false)
  {
}

SwiftAsyncContextAttr *SwiftAsyncContextAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncContextAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncContextAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async_context";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_async_context";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_async_context";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncContextAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async_context";
  case 1:
    return "swift_async_context";
  case 2:
    return "swift_async_context";
  }
}


// SwiftAsyncErrorAttr implementation

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncErrorAttr(Ctx, CommonInfo, Convention, HandlerParamIdx);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncErrorAttr(Ctx, CommonInfo, Convention, HandlerParamIdx);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Convention, HandlerParamIdx, I);
}

SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, unsigned HandlerParamIdx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Convention, HandlerParamIdx, I);
}

SwiftAsyncErrorAttr::SwiftAsyncErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConventionKind Convention
              , unsigned HandlerParamIdx
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncError, false, false)
              , convention(Convention)
              , handlerParamIdx(HandlerParamIdx)
  {
}

SwiftAsyncErrorAttr::SwiftAsyncErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConventionKind Convention
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncError, false, false)
              , convention(Convention)
              , handlerParamIdx()
  {
}



bool SwiftAsyncErrorAttr::ConvertStrToConventionKind(StringRef Val, ConventionKind &Out) {
  Optional<ConventionKind> R = llvm::StringSwitch<Optional<ConventionKind>>(Val)
    .Case("none", SwiftAsyncErrorAttr::None)
    .Case("nonnull_error", SwiftAsyncErrorAttr::NonNullError)
    .Case("zero_argument", SwiftAsyncErrorAttr::ZeroArgument)
    .Case("nonzero_argument", SwiftAsyncErrorAttr::NonZeroArgument)
    .Default(Optional<ConventionKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftAsyncErrorAttr::ConvertConventionKindToStr(ConventionKind Val) {
  switch(Val) {
  case SwiftAsyncErrorAttr::None: return "none";
  case SwiftAsyncErrorAttr::NonNullError: return "nonnull_error";
  case SwiftAsyncErrorAttr::ZeroArgument: return "zero_argument";
  case SwiftAsyncErrorAttr::NonZeroArgument: return "nonzero_argument";
  }
  llvm_unreachable("No enumerator with that value");
}


SwiftAsyncErrorAttr *SwiftAsyncErrorAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncErrorAttr(C, *this, convention, handlerParamIdx);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncErrorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getHandlerParamIdx() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_async_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getHandlerParamIdx() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_async_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftAsyncErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getHandlerParamIdx() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *SwiftAsyncErrorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async_error";
  case 1:
    return "swift_async_error";
  case 2:
    return "swift_async_error";
  }
}


// SwiftAsyncNameAttr implementation

SwiftAsyncNameAttr *SwiftAsyncNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncNameAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncNameAttr *SwiftAsyncNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAsyncNameAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAsyncNameAttr *SwiftAsyncNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

SwiftAsyncNameAttr *SwiftAsyncNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

SwiftAsyncNameAttr::SwiftAsyncNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAsyncName, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



SwiftAsyncNameAttr *SwiftAsyncNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAsyncNameAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAsyncNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_async_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftAsyncNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_async_name";
  }
}


// SwiftAttrAttr implementation

SwiftAttrAttr *SwiftAttrAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Attribute, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAttrAttr(Ctx, CommonInfo, Attribute);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAttrAttr *SwiftAttrAttr::Create(ASTContext &Ctx, llvm::StringRef Attribute, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftAttrAttr(Ctx, CommonInfo, Attribute);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftAttrAttr *SwiftAttrAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Attribute, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Attribute, I);
}

SwiftAttrAttr *SwiftAttrAttr::Create(ASTContext &Ctx, llvm::StringRef Attribute, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Attribute, I);
}

SwiftAttrAttr::SwiftAttrAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Attribute
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftAttr, false, false)
              , attributeLength(Attribute.size()),attribute(new (Ctx, 1) char[attributeLength])
  {
    if (!Attribute.empty())
      std::memcpy(attribute, Attribute.data(), attributeLength);
}



SwiftAttrAttr *SwiftAttrAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftAttrAttr(C, *this, getAttribute());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftAttrAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_attr";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAttribute() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftAttrAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_attr";
  }
}


// SwiftBridgeAttr implementation

SwiftBridgeAttr *SwiftBridgeAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef SwiftType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgeAttr(Ctx, CommonInfo, SwiftType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgeAttr *SwiftBridgeAttr::Create(ASTContext &Ctx, llvm::StringRef SwiftType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgeAttr(Ctx, CommonInfo, SwiftType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgeAttr *SwiftBridgeAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef SwiftType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, SwiftType, I);
}

SwiftBridgeAttr *SwiftBridgeAttr::Create(ASTContext &Ctx, llvm::StringRef SwiftType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, SwiftType, I);
}

SwiftBridgeAttr::SwiftBridgeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef SwiftType
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftBridge, false, false)
              , swiftTypeLength(SwiftType.size()),swiftType(new (Ctx, 1) char[swiftTypeLength])
  {
    if (!SwiftType.empty())
      std::memcpy(swiftType, SwiftType.data(), swiftTypeLength);
}



SwiftBridgeAttr *SwiftBridgeAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftBridgeAttr(C, *this, getSwiftType());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftBridgeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_bridge";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getSwiftType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftBridgeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_bridge";
  }
}


// SwiftBridgedTypedefAttr implementation

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgedTypedefAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftBridgedTypedefAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftBridgedTypedefAttr::SwiftBridgedTypedefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftBridgedTypedef, false, false)
  {
}

SwiftBridgedTypedefAttr *SwiftBridgedTypedefAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftBridgedTypedefAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftBridgedTypedefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_bridged_typedef";
    OS << "))";
    break;
  }
}
}

const char *SwiftBridgedTypedefAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_bridged_typedef";
  }
}


// SwiftCallAttr implementation

SwiftCallAttr *SwiftCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftCallAttr *SwiftCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftCallAttr *SwiftCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftCallAttr *SwiftCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftCallAttr::SwiftCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftCall, false, false)
  {
}

SwiftCallAttr *SwiftCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swiftcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swiftcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swiftcall";
    OS << "]]";
    break;
  }
}
}

const char *SwiftCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swiftcall";
  case 1:
    return "swiftcall";
  case 2:
    return "swiftcall";
  }
}


// SwiftContextAttr implementation

SwiftContextAttr *SwiftContextAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftContextAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftContextAttr *SwiftContextAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftContextAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftContextAttr *SwiftContextAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftContextAttr *SwiftContextAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftContextAttr::SwiftContextAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftContext, false, false)
  {
}

SwiftContextAttr *SwiftContextAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftContextAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftContextAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_context";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_context";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_context";
    OS << "]]";
    break;
  }
}
}

const char *SwiftContextAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_context";
  case 1:
    return "swift_context";
  case 2:
    return "swift_context";
  }
}


// SwiftErrorAttr implementation

SwiftErrorAttr *SwiftErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorAttr(Ctx, CommonInfo, Convention);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorAttr *SwiftErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorAttr(Ctx, CommonInfo, Convention);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorAttr *SwiftErrorAttr::CreateImplicit(ASTContext &Ctx, ConventionKind Convention, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Convention, I);
}

SwiftErrorAttr *SwiftErrorAttr::Create(ASTContext &Ctx, ConventionKind Convention, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Convention, I);
}

SwiftErrorAttr::SwiftErrorAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConventionKind Convention
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftError, false, false)
              , convention(Convention)
  {
}



bool SwiftErrorAttr::ConvertStrToConventionKind(StringRef Val, ConventionKind &Out) {
  Optional<ConventionKind> R = llvm::StringSwitch<Optional<ConventionKind>>(Val)
    .Case("none", SwiftErrorAttr::None)
    .Case("nonnull_error", SwiftErrorAttr::NonNullError)
    .Case("null_result", SwiftErrorAttr::NullResult)
    .Case("zero_result", SwiftErrorAttr::ZeroResult)
    .Case("nonzero_result", SwiftErrorAttr::NonZeroResult)
    .Default(Optional<ConventionKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftErrorAttr::ConvertConventionKindToStr(ConventionKind Val) {
  switch(Val) {
  case SwiftErrorAttr::None: return "none";
  case SwiftErrorAttr::NonNullError: return "nonnull_error";
  case SwiftErrorAttr::NullResult: return "null_result";
  case SwiftErrorAttr::ZeroResult: return "zero_result";
  case SwiftErrorAttr::NonZeroResult: return "nonzero_result";
  }
  llvm_unreachable("No enumerator with that value");
}
SwiftErrorAttr *SwiftErrorAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftErrorAttr(C, *this, convention);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftErrorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_error";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftErrorAttr::ConvertConventionKindToStr(getConvention()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftErrorAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_error";
  }
}


// SwiftErrorResultAttr implementation

SwiftErrorResultAttr *SwiftErrorResultAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorResultAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorResultAttr *SwiftErrorResultAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftErrorResultAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftErrorResultAttr *SwiftErrorResultAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftErrorResultAttr *SwiftErrorResultAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftErrorResultAttr::SwiftErrorResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftErrorResult, false, false)
  {
}

SwiftErrorResultAttr *SwiftErrorResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftErrorResultAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftErrorResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_error_result";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_error_result";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_error_result";
    OS << "]]";
    break;
  }
}
}

const char *SwiftErrorResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_error_result";
  case 1:
    return "swift_error_result";
  case 2:
    return "swift_error_result";
  }
}


// SwiftIndirectResultAttr implementation

SwiftIndirectResultAttr *SwiftIndirectResultAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftIndirectResultAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftIndirectResultAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftIndirectResultAttr::SwiftIndirectResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : ParameterABIAttr(Ctx, CommonInfo, attr::SwiftIndirectResult, false, false)
  {
}

SwiftIndirectResultAttr *SwiftIndirectResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftIndirectResultAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftIndirectResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_indirect_result";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::swift_indirect_result";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::swift_indirect_result";
    OS << "]]";
    break;
  }
}
}

const char *SwiftIndirectResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_indirect_result";
  case 1:
    return "swift_indirect_result";
  case 2:
    return "swift_indirect_result";
  }
}


// SwiftNameAttr implementation

SwiftNameAttr *SwiftNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNameAttr(Ctx, CommonInfo, Name);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftNameAttr *SwiftNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNameAttr(Ctx, CommonInfo, Name);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftNameAttr *SwiftNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Name, I);
}

SwiftNameAttr *SwiftNameAttr::Create(ASTContext &Ctx, llvm::StringRef Name, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Name, I);
}

SwiftNameAttr::SwiftNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Name
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftName, false, false)
              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
  {
    if (!Name.empty())
      std::memcpy(name, Name.data(), nameLength);
}



SwiftNameAttr *SwiftNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftNameAttr(C, *this, getName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_name";
  }
}


// SwiftNewTypeAttr implementation

SwiftNewTypeAttr *SwiftNewTypeAttr::CreateImplicit(ASTContext &Ctx, NewtypeKind NewtypeKind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNewTypeAttr(Ctx, CommonInfo, NewtypeKind);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftNewTypeAttr *SwiftNewTypeAttr::Create(ASTContext &Ctx, NewtypeKind NewtypeKind, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftNewTypeAttr(Ctx, CommonInfo, NewtypeKind);
  return A;
}

SwiftNewTypeAttr *SwiftNewTypeAttr::CreateImplicit(ASTContext &Ctx, NewtypeKind NewtypeKind, SourceRange Range, AttributeCommonInfo::Syntax Syntax, SwiftNewTypeAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, NewtypeKind, I);
}

SwiftNewTypeAttr *SwiftNewTypeAttr::Create(ASTContext &Ctx, NewtypeKind NewtypeKind, SourceRange Range, AttributeCommonInfo::Syntax Syntax, SwiftNewTypeAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, NewtypeKind, I);
}

SwiftNewTypeAttr::SwiftNewTypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , NewtypeKind NewtypeKind
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftNewType, false, false)
              , newtypeKind(NewtypeKind)
  {
}

SwiftNewTypeAttr::Spelling SwiftNewTypeAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_swift_newtype;
    case 1: return GNU_swift_wrapper;
  }
}


bool SwiftNewTypeAttr::ConvertStrToNewtypeKind(StringRef Val, NewtypeKind &Out) {
  Optional<NewtypeKind> R = llvm::StringSwitch<Optional<NewtypeKind>>(Val)
    .Case("struct", SwiftNewTypeAttr::NK_Struct)
    .Case("enum", SwiftNewTypeAttr::NK_Enum)
    .Default(Optional<NewtypeKind>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *SwiftNewTypeAttr::ConvertNewtypeKindToStr(NewtypeKind Val) {
  switch(Val) {
  case SwiftNewTypeAttr::NK_Struct: return "struct";
  case SwiftNewTypeAttr::NK_Enum: return "enum";
  }
  llvm_unreachable("No enumerator with that value");
}
SwiftNewTypeAttr *SwiftNewTypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftNewTypeAttr(C, *this, newtypeKind);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftNewTypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_newtype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftNewTypeAttr::ConvertNewtypeKindToStr(getNewtypeKind()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " __attribute__((swift_wrapper";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << SwiftNewTypeAttr::ConvertNewtypeKindToStr(getNewtypeKind()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *SwiftNewTypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_newtype";
  case 1:
    return "swift_wrapper";
  }
}


// SwiftObjCMembersAttr implementation

SwiftObjCMembersAttr *SwiftObjCMembersAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftObjCMembersAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftObjCMembersAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftObjCMembersAttr::SwiftObjCMembersAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::SwiftObjCMembers, false)
  {
}

SwiftObjCMembersAttr *SwiftObjCMembersAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftObjCMembersAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftObjCMembersAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_objc_members";
    OS << "))";
    break;
  }
}
}

const char *SwiftObjCMembersAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_objc_members";
  }
}


// SwiftPrivateAttr implementation

SwiftPrivateAttr *SwiftPrivateAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftPrivateAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftPrivateAttr *SwiftPrivateAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SwiftPrivateAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SwiftPrivateAttr *SwiftPrivateAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SwiftPrivateAttr *SwiftPrivateAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SwiftPrivateAttr::SwiftPrivateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SwiftPrivate, false, false)
  {
}

SwiftPrivateAttr *SwiftPrivateAttr::clone(ASTContext &C) const {
  auto *A = new (C) SwiftPrivateAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SwiftPrivateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((swift_private";
    OS << "))";
    break;
  }
}
}

const char *SwiftPrivateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "swift_private";
  }
}


// SysVABIAttr implementation

SysVABIAttr *SysVABIAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SysVABIAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SysVABIAttr *SysVABIAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) SysVABIAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

SysVABIAttr *SysVABIAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

SysVABIAttr *SysVABIAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

SysVABIAttr::SysVABIAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::SysVABI, false, false)
  {
}

SysVABIAttr *SysVABIAttr::clone(ASTContext &C) const {
  auto *A = new (C) SysVABIAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void SysVABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((sysv_abi";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::sysv_abi";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::sysv_abi";
    OS << "]]";
    break;
  }
}
}

const char *SysVABIAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "sysv_abi";
  case 1:
    return "sysv_abi";
  case 2:
    return "sysv_abi";
  }
}


// TLSModelAttr implementation

TLSModelAttr *TLSModelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TLSModelAttr(Ctx, CommonInfo, Model);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TLSModelAttr *TLSModelAttr::Create(ASTContext &Ctx, llvm::StringRef Model, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TLSModelAttr(Ctx, CommonInfo, Model);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TLSModelAttr *TLSModelAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Model, I);
}

TLSModelAttr *TLSModelAttr::Create(ASTContext &Ctx, llvm::StringRef Model, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Model, I);
}

TLSModelAttr::TLSModelAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Model
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TLSModel, false, false)
              , modelLength(Model.size()),model(new (Ctx, 1) char[modelLength])
  {
    if (!Model.empty())
      std::memcpy(model, Model.data(), modelLength);
}



TLSModelAttr *TLSModelAttr::clone(ASTContext &C) const {
  auto *A = new (C) TLSModelAttr(C, *this, getModel());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TLSModelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((tls_model";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getModel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::tls_model";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getModel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::tls_model";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getModel() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TLSModelAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "tls_model";
  case 1:
    return "tls_model";
  case 2:
    return "tls_model";
  }
}


// TargetAttr implementation

TargetAttr *TargetAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef FeaturesStr, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetAttr(Ctx, CommonInfo, FeaturesStr);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetAttr *TargetAttr::Create(ASTContext &Ctx, llvm::StringRef FeaturesStr, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetAttr(Ctx, CommonInfo, FeaturesStr);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetAttr *TargetAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef FeaturesStr, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, FeaturesStr, I);
}

TargetAttr *TargetAttr::Create(ASTContext &Ctx, llvm::StringRef FeaturesStr, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, FeaturesStr, I);
}

TargetAttr::TargetAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef FeaturesStr
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Target, false, false)
              , featuresStrLength(FeaturesStr.size()),featuresStr(new (Ctx, 1) char[featuresStrLength])
  {
    if (!FeaturesStr.empty())
      std::memcpy(featuresStr, FeaturesStr.data(), featuresStrLength);
}



TargetAttr *TargetAttr::clone(ASTContext &C) const {
  auto *A = new (C) TargetAttr(C, *this, getFeaturesStr());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TargetAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((target";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getFeaturesStr() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::target";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getFeaturesStr() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::target";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getFeaturesStr() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TargetAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "target";
  case 1:
    return "target";
  case 2:
    return "target";
  }
}


// TargetClonesAttr implementation

TargetClonesAttr *TargetClonesAttr::CreateImplicit(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetClonesAttr(Ctx, CommonInfo, FeaturesStrs, FeaturesStrsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetClonesAttr *TargetClonesAttr::Create(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TargetClonesAttr(Ctx, CommonInfo, FeaturesStrs, FeaturesStrsSize);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TargetClonesAttr *TargetClonesAttr::CreateImplicit(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, FeaturesStrs, FeaturesStrsSize, I);
}

TargetClonesAttr *TargetClonesAttr::Create(ASTContext &Ctx, StringRef *FeaturesStrs, unsigned FeaturesStrsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, FeaturesStrs, FeaturesStrsSize, I);
}

TargetClonesAttr::TargetClonesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , StringRef *FeaturesStrs, unsigned FeaturesStrsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TargetClones, false, false)
              , featuresStrs_Size(FeaturesStrsSize), featuresStrs_(new (Ctx, 16) StringRef[featuresStrs_Size])
  {
  for (size_t I = 0, E = featuresStrs_Size; I != E;
       ++I) {
    StringRef Ref = FeaturesStrs[I];
    if (!Ref.empty()) {
      char *Mem = new (Ctx, 1) char[Ref.size()];
      std::memcpy(Mem, Ref.data(), Ref.size());
      featuresStrs_[I] = StringRef(Mem, Ref.size());
    }
  }
}

TargetClonesAttr::TargetClonesAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TargetClones, false, false)
              , featuresStrs_Size(0), featuresStrs_(nullptr)
  {
}



TargetClonesAttr *TargetClonesAttr::clone(ASTContext &C) const {
  auto *A = new (C) TargetClonesAttr(C, *this, featuresStrs_, featuresStrs_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TargetClonesAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((target_clones";
    OS << "";
  for (const auto &Val : featuresStrs()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::target_clones";
    OS << "";
  for (const auto &Val : featuresStrs()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::target_clones";
    OS << "";
  for (const auto &Val : featuresStrs()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << Val << "\"";
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TargetClonesAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "target_clones";
  case 1:
    return "target_clones";
  case 2:
    return "target_clones";
  }
}


// TestTypestateAttr implementation

TestTypestateAttr *TestTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState TestState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TestTypestateAttr(Ctx, CommonInfo, TestState);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TestTypestateAttr *TestTypestateAttr::Create(ASTContext &Ctx, ConsumedState TestState, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TestTypestateAttr(Ctx, CommonInfo, TestState);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TestTypestateAttr *TestTypestateAttr::CreateImplicit(ASTContext &Ctx, ConsumedState TestState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TestState, I);
}

TestTypestateAttr *TestTypestateAttr::Create(ASTContext &Ctx, ConsumedState TestState, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TestState, I);
}

TestTypestateAttr::TestTypestateAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , ConsumedState TestState
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TestTypestate, false, false)
              , testState(TestState)
  {
}



bool TestTypestateAttr::ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
  Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
    .Case("consumed", TestTypestateAttr::Consumed)
    .Case("unconsumed", TestTypestateAttr::Unconsumed)
    .Default(Optional<ConsumedState>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *TestTypestateAttr::ConvertConsumedStateToStr(ConsumedState Val) {
  switch(Val) {
  case TestTypestateAttr::Consumed: return "consumed";
  case TestTypestateAttr::Unconsumed: return "unconsumed";
  }
  llvm_unreachable("No enumerator with that value");
}
TestTypestateAttr *TestTypestateAttr::clone(ASTContext &C) const {
  auto *A = new (C) TestTypestateAttr(C, *this, testState);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TestTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((test_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TestTypestateAttr::ConvertConsumedStateToStr(getTestState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::test_typestate";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TestTypestateAttr::ConvertConsumedStateToStr(getTestState()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TestTypestateAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "test_typestate";
  case 1:
    return "test_typestate";
  }
}


// ThisCallAttr implementation

ThisCallAttr *ThisCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThisCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThisCallAttr *ThisCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThisCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThisCallAttr *ThisCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ThisCallAttr *ThisCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ThisCallAttr::ThisCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::ThisCall, false, false)
  {
}

ThisCallAttr *ThisCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) ThisCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ThisCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((thiscall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::thiscall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::thiscall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __thiscall";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _thiscall";
    OS << "";
    break;
  }
}
}

const char *ThisCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "thiscall";
  case 1:
    return "thiscall";
  case 2:
    return "thiscall";
  case 3:
    return "__thiscall";
  case 4:
    return "_thiscall";
  }
}


// ThreadAttr implementation

ThreadAttr *ThreadAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThreadAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThreadAttr *ThreadAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) ThreadAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

ThreadAttr *ThreadAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

ThreadAttr *ThreadAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

ThreadAttr::ThreadAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : Attr(Ctx, CommonInfo, attr::Thread, false)
  {
}

ThreadAttr *ThreadAttr::clone(ASTContext &C) const {
  auto *A = new (C) ThreadAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void ThreadAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(thread";
    OS << ")";
    break;
  }
}
}

const char *ThreadAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "thread";
  }
}


// TransparentUnionAttr implementation

TransparentUnionAttr *TransparentUnionAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TransparentUnionAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TransparentUnionAttr *TransparentUnionAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TransparentUnionAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TransparentUnionAttr *TransparentUnionAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TransparentUnionAttr *TransparentUnionAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TransparentUnionAttr::TransparentUnionAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TransparentUnion, false, false)
  {
}

TransparentUnionAttr *TransparentUnionAttr::clone(ASTContext &C) const {
  auto *A = new (C) TransparentUnionAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TransparentUnionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((transparent_union";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::transparent_union";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::transparent_union";
    OS << "]]";
    break;
  }
}
}

const char *TransparentUnionAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "transparent_union";
  case 1:
    return "transparent_union";
  case 2:
    return "transparent_union";
  }
}


// TrivialABIAttr implementation

TrivialABIAttr *TrivialABIAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TrivialABIAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TrivialABIAttr *TrivialABIAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TrivialABIAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TrivialABIAttr *TrivialABIAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TrivialABIAttr *TrivialABIAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TrivialABIAttr::TrivialABIAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TrivialABI, false, false)
  {
}

TrivialABIAttr *TrivialABIAttr::clone(ASTContext &C) const {
  auto *A = new (C) TrivialABIAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TrivialABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((trivial_abi";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::trivial_abi";
    OS << "]]";
    break;
  }
}
}

const char *TrivialABIAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "trivial_abi";
  case 1:
    return "trivial_abi";
  }
}


// TryAcquireCapabilityAttr implementation

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TryAcquireCapabilityAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TryAcquireCapabilityAttr(Ctx, CommonInfo, SuccessValue, Args, ArgsSize);
  return A;
}

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, TryAcquireCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, SuccessValue, Args, ArgsSize, I);
}

TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::Create(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Range, AttributeCommonInfo::Syntax Syntax, TryAcquireCapabilityAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, SuccessValue, Args, ArgsSize, I);
}

TryAcquireCapabilityAttr::TryAcquireCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
              , Expr * *Args, unsigned ArgsSize
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TryAcquireCapability, true, true)
              , successValue(SuccessValue)
              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
  {
  std::copy(Args, Args + args_Size, args_);
}

TryAcquireCapabilityAttr::TryAcquireCapabilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , Expr * SuccessValue
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TryAcquireCapability, true, true)
              , successValue(SuccessValue)
              , args_Size(0), args_(nullptr)
  {
}

TryAcquireCapabilityAttr::Spelling TryAcquireCapabilityAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_try_acquire_capability;
    case 1: return CXX11_clang_try_acquire_capability;
    case 2: return GNU_try_acquire_shared_capability;
    case 3: return CXX11_clang_try_acquire_shared_capability;
  }
}




TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) TryAcquireCapabilityAttr(C, *this, successValue, args_, args_Size);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TryAcquireCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((try_acquire_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::try_acquire_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " __attribute__((try_acquire_shared_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 3 : {
    OS << " [[clang::try_acquire_shared_capability";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getSuccessValue() << "";
    OS << "";
  for (const auto &Val : args()) {
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << Val;
  }
  OS << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TryAcquireCapabilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "try_acquire_capability";
  case 1:
    return "try_acquire_capability";
  case 2:
    return "try_acquire_shared_capability";
  case 3:
    return "try_acquire_shared_capability";
  }
}


// TypeNonNullAttr implementation

TypeNonNullAttr *TypeNonNullAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNonNullAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNonNullAttr *TypeNonNullAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNonNullAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNonNullAttr *TypeNonNullAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNonNullAttr *TypeNonNullAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNonNullAttr::TypeNonNullAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNonNull, false)
  {
}

TypeNonNullAttr *TypeNonNullAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNonNullAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNonNullAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Nonnull";
    OS << "";
    break;
  }
}
}

const char *TypeNonNullAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Nonnull";
  }
}


// TypeNullUnspecifiedAttr implementation

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullUnspecifiedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullUnspecifiedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNullUnspecifiedAttr::TypeNullUnspecifiedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNullUnspecified, false)
  {
}

TypeNullUnspecifiedAttr *TypeNullUnspecifiedAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNullUnspecifiedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNullUnspecifiedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Null_unspecified";
    OS << "";
    break;
  }
}
}

const char *TypeNullUnspecifiedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Null_unspecified";
  }
}


// TypeNullableAttr implementation

TypeNullableAttr *TypeNullableAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableAttr *TypeNullableAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableAttr *TypeNullableAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNullableAttr *TypeNullableAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNullableAttr::TypeNullableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNullable, false)
  {
}

TypeNullableAttr *TypeNullableAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNullableAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNullableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Nullable";
    OS << "";
    break;
  }
}
}

const char *TypeNullableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Nullable";
  }
}


// TypeNullableResultAttr implementation

TypeNullableResultAttr *TypeNullableResultAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableResultAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableResultAttr *TypeNullableResultAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeNullableResultAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeNullableResultAttr *TypeNullableResultAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

TypeNullableResultAttr *TypeNullableResultAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

TypeNullableResultAttr::TypeNullableResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::TypeNullableResult, false)
  {
}

TypeNullableResultAttr *TypeNullableResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeNullableResultAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeNullableResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " _Nullable_result";
    OS << "";
    break;
  }
}
}

const char *TypeNullableResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "_Nullable_result";
  }
}


// TypeTagForDatatypeAttr implementation

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeTagForDatatypeAttr(Ctx, CommonInfo, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeTagForDatatypeAttr(Ctx, CommonInfo, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, I);
}

TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::Create(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, I);
}

TypeTagForDatatypeAttr::TypeTagForDatatypeAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , IdentifierInfo * ArgumentKind
              , TypeSourceInfo * MatchingCType
              , bool LayoutCompatible
              , bool MustBeNull
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TypeTagForDatatype, false, false)
              , argumentKind(ArgumentKind)
              , matchingCType(MatchingCType)
              , layoutCompatible(LayoutCompatible)
              , mustBeNull(MustBeNull)
  {
}









TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeTagForDatatypeAttr(C, *this, argumentKind, matchingCType, layoutCompatible, mustBeNull);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeTagForDatatypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((type_tag_for_datatype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMatchingCType().getAsString() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getLayoutCompatible() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMustBeNull() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::type_tag_for_datatype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMatchingCType().getAsString() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getLayoutCompatible() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMustBeNull() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::type_tag_for_datatype";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << (getArgumentKind() ? getArgumentKind()->getName() : "") << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMatchingCType().getAsString() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getLayoutCompatible() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getMustBeNull() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TypeTagForDatatypeAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "type_tag_for_datatype";
  case 1:
    return "type_tag_for_datatype";
  case 2:
    return "type_tag_for_datatype";
  }
}


// TypeVisibilityAttr implementation

TypeVisibilityAttr *TypeVisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeVisibilityAttr(Ctx, CommonInfo, Visibility);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeVisibilityAttr *TypeVisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) TypeVisibilityAttr(Ctx, CommonInfo, Visibility);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

TypeVisibilityAttr *TypeVisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Visibility, I);
}

TypeVisibilityAttr *TypeVisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Visibility, I);
}

TypeVisibilityAttr::TypeVisibilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , VisibilityType Visibility
             )
  : InheritableAttr(Ctx, CommonInfo, attr::TypeVisibility, false, false)
              , visibility(Visibility)
  {
}



bool TypeVisibilityAttr::ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
  Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
    .Case("default", TypeVisibilityAttr::Default)
    .Case("hidden", TypeVisibilityAttr::Hidden)
    .Case("internal", TypeVisibilityAttr::Hidden)
    .Case("protected", TypeVisibilityAttr::Protected)
    .Default(Optional<VisibilityType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *TypeVisibilityAttr::ConvertVisibilityTypeToStr(VisibilityType Val) {
  switch(Val) {
  case TypeVisibilityAttr::Default: return "default";
  case TypeVisibilityAttr::Hidden: return "hidden";
  case TypeVisibilityAttr::Protected: return "protected";
  }
  llvm_unreachable("No enumerator with that value");
}
TypeVisibilityAttr *TypeVisibilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) TypeVisibilityAttr(C, *this, visibility);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void TypeVisibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((type_visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TypeVisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::type_visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TypeVisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::type_visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << TypeVisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *TypeVisibilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "type_visibility";
  case 1:
    return "type_visibility";
  case 2:
    return "type_visibility";
  }
}


// UPtrAttr implementation

UPtrAttr *UPtrAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UPtrAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UPtrAttr *UPtrAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UPtrAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UPtrAttr *UPtrAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UPtrAttr *UPtrAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UPtrAttr::UPtrAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : TypeAttr(Ctx, CommonInfo, attr::UPtr, false)
  {
}

UPtrAttr *UPtrAttr::clone(ASTContext &C) const {
  auto *A = new (C) UPtrAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UPtrAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __uptr";
    OS << "";
    break;
  }
}
}

const char *UPtrAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "__uptr";
  }
}


// UnavailableAttr implementation

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message, ImplicitReason);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message, ImplicitReason);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Message, ImplicitReason, I);
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Message, ImplicitReason, I);
}

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnavailableAttr(Ctx, CommonInfo, Message);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnavailableAttr *UnavailableAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Message, I);
}

UnavailableAttr *UnavailableAttr::Create(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Message, I);
}

UnavailableAttr::UnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
              , ImplicitReason ImplicitReason
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unavailable, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , implicitReason(ImplicitReason)
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

UnavailableAttr::UnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unavailable, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
              , implicitReason(ImplicitReason(0))
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

UnavailableAttr::UnavailableAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unavailable, false, false)
              , messageLength(0),message(nullptr)
              , implicitReason(ImplicitReason(0))
  {
}





UnavailableAttr *UnavailableAttr::clone(ASTContext &C) const {
  auto *A = new (C) UnavailableAttr(C, *this, getMessage(), implicitReason);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UnavailableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((unavailable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::unavailable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::unavailable";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *UnavailableAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "unavailable";
  case 1:
    return "unavailable";
  case 2:
    return "unavailable";
  }
}


// UninitializedAttr implementation

UninitializedAttr *UninitializedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UninitializedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UninitializedAttr *UninitializedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UninitializedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UninitializedAttr *UninitializedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UninitializedAttr *UninitializedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UninitializedAttr::UninitializedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Uninitialized, false, false)
  {
}

UninitializedAttr *UninitializedAttr::clone(ASTContext &C) const {
  auto *A = new (C) UninitializedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UninitializedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((uninitialized";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::uninitialized";
    OS << "]]";
    break;
  }
}
}

const char *UninitializedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "uninitialized";
  case 1:
    return "uninitialized";
  }
}


// UnlikelyAttr implementation

UnlikelyAttr *UnlikelyAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnlikelyAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnlikelyAttr *UnlikelyAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnlikelyAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnlikelyAttr *UnlikelyAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UnlikelyAttr *UnlikelyAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UnlikelyAttr::UnlikelyAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : StmtAttr(Ctx, CommonInfo, attr::Unlikely, false)
  {
}

UnlikelyAttr *UnlikelyAttr::clone(ASTContext &C) const {
  auto *A = new (C) UnlikelyAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UnlikelyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[unlikely";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[clang::unlikely";
    OS << "]]";
    break;
  }
}
}

const char *UnlikelyAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "unlikely";
  case 1:
    return "unlikely";
  }
}


// UnusedAttr implementation

UnusedAttr *UnusedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnusedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UnusedAttr *UnusedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UnusedAttr(Ctx, CommonInfo);
  return A;
}

UnusedAttr *UnusedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, UnusedAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

UnusedAttr *UnusedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, UnusedAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

UnusedAttr::UnusedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Unused, false, false)
  {
}

UnusedAttr::Spelling UnusedAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return CXX11_maybe_unused;
    case 1: return GNU_unused;
    case 2: return CXX11_gnu_unused;
    case 3: return C2x_gnu_unused;
    case 4: return C2x_maybe_unused;
  }
}
UnusedAttr *UnusedAttr::clone(ASTContext &C) const {
  auto *A = new (C) UnusedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UnusedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[maybe_unused";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " __attribute__((unused";
    OS << "))";
    break;
  }
  case 2 : {
    OS << " [[gnu::unused";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " [[gnu::unused";
    OS << "]]";
    break;
  }
  case 4 : {
    OS << " [[maybe_unused";
    OS << "]]";
    break;
  }
}
}

const char *UnusedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "maybe_unused";
  case 1:
    return "unused";
  case 2:
    return "unused";
  case 3:
    return "unused";
  case 4:
    return "maybe_unused";
  }
}


// UseHandleAttr implementation

UseHandleAttr *UseHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UseHandleAttr(Ctx, CommonInfo, HandleType);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UseHandleAttr *UseHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UseHandleAttr(Ctx, CommonInfo, HandleType);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UseHandleAttr *UseHandleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, HandleType, I);
}

UseHandleAttr *UseHandleAttr::Create(ASTContext &Ctx, llvm::StringRef HandleType, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, HandleType, I);
}

UseHandleAttr::UseHandleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef HandleType
             )
  : InheritableParamAttr(Ctx, CommonInfo, attr::UseHandle, false, false)
              , handleTypeLength(HandleType.size()),handleType(new (Ctx, 1) char[handleTypeLength])
  {
    if (!HandleType.empty())
      std::memcpy(handleType, HandleType.data(), handleTypeLength);
}



UseHandleAttr *UseHandleAttr::clone(ASTContext &C) const {
  auto *A = new (C) UseHandleAttr(C, *this, getHandleType());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UseHandleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((use_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::use_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::use_handle";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getHandleType() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *UseHandleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "use_handle";
  case 1:
    return "use_handle";
  case 2:
    return "use_handle";
  }
}


// UsedAttr implementation

UsedAttr *UsedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsedAttr *UsedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsedAttr *UsedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UsedAttr *UsedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UsedAttr::UsedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Used, false, false)
  {
}

UsedAttr *UsedAttr::clone(ASTContext &C) const {
  auto *A = new (C) UsedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UsedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((used";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::used";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::used";
    OS << "]]";
    break;
  }
}
}

const char *UsedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "used";
  case 1:
    return "used";
  case 2:
    return "used";
  }
}


// UsingIfExistsAttr implementation

UsingIfExistsAttr *UsingIfExistsAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsingIfExistsAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsingIfExistsAttr *UsingIfExistsAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UsingIfExistsAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UsingIfExistsAttr *UsingIfExistsAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

UsingIfExistsAttr *UsingIfExistsAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

UsingIfExistsAttr::UsingIfExistsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::UsingIfExists, false, false)
  {
}

UsingIfExistsAttr *UsingIfExistsAttr::clone(ASTContext &C) const {
  auto *A = new (C) UsingIfExistsAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UsingIfExistsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((using_if_exists";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::using_if_exists";
    OS << "]]";
    break;
  }
}
}

const char *UsingIfExistsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "using_if_exists";
  case 1:
    return "using_if_exists";
  }
}


// UuidAttr implementation

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid, GuidDecl);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid, GuidDecl);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Guid, GuidDecl, I);
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, MSGuidDecl * GuidDecl, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Guid, GuidDecl, I);
}

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) UuidAttr(Ctx, CommonInfo, Guid);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

UuidAttr *UuidAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Guid, I);
}

UuidAttr *UuidAttr::Create(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Guid, I);
}

UuidAttr::UuidAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Guid
              , MSGuidDecl * GuidDecl
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Uuid, false, false)
              , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength])
              , guidDecl(GuidDecl)
  {
    if (!Guid.empty())
      std::memcpy(guid, Guid.data(), guidLength);
}

UuidAttr::UuidAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Guid
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Uuid, false, false)
              , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength])
              , guidDecl()
  {
    if (!Guid.empty())
      std::memcpy(guid, Guid.data(), guidLength);
}





UuidAttr *UuidAttr::clone(ASTContext &C) const {
  auto *A = new (C) UuidAttr(C, *this, getGuid(), guidDecl);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void UuidAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __declspec(uuid";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getGuid() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << ")";
    break;
  }
  case 1 : {
    OS << "[uuid";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getGuid() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]";
    break;
  }
}
}

const char *UuidAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "uuid";
  case 1:
    return "uuid";
  }
}


// VecReturnAttr implementation

VecReturnAttr *VecReturnAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecReturnAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecReturnAttr *VecReturnAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecReturnAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecReturnAttr *VecReturnAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

VecReturnAttr *VecReturnAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

VecReturnAttr::VecReturnAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::VecReturn, false, false)
  {
}

VecReturnAttr *VecReturnAttr::clone(ASTContext &C) const {
  auto *A = new (C) VecReturnAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VecReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((vecreturn";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::vecreturn";
    OS << "]]";
    break;
  }
}
}

const char *VecReturnAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "vecreturn";
  case 1:
    return "vecreturn";
  }
}


// VecTypeHintAttr implementation

VecTypeHintAttr *VecTypeHintAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecTypeHintAttr(Ctx, CommonInfo, TypeHint);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecTypeHintAttr *VecTypeHintAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypeHint, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VecTypeHintAttr(Ctx, CommonInfo, TypeHint);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VecTypeHintAttr *VecTypeHintAttr::CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, TypeHint, I);
}

VecTypeHintAttr *VecTypeHintAttr::Create(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, TypeHint, I);
}

VecTypeHintAttr::VecTypeHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , TypeSourceInfo * TypeHint
             )
  : InheritableAttr(Ctx, CommonInfo, attr::VecTypeHint, false, false)
              , typeHint(TypeHint)
  {
}



VecTypeHintAttr *VecTypeHintAttr::clone(ASTContext &C) const {
  auto *A = new (C) VecTypeHintAttr(C, *this, typeHint);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VecTypeHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((vec_type_hint";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getTypeHint().getAsString() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *VecTypeHintAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "vec_type_hint";
  }
}


// VectorCallAttr implementation

VectorCallAttr *VectorCallAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VectorCallAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VectorCallAttr *VectorCallAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VectorCallAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VectorCallAttr *VectorCallAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

VectorCallAttr *VectorCallAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

VectorCallAttr::VectorCallAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::VectorCall, false, false)
  {
}

VectorCallAttr *VectorCallAttr::clone(ASTContext &C) const {
  auto *A = new (C) VectorCallAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VectorCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((vectorcall";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::vectorcall";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::vectorcall";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __vectorcall";
    OS << "";
    break;
  }
  case 4 : {
    OS << " _vectorcall";
    OS << "";
    break;
  }
}
}

const char *VectorCallAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "vectorcall";
  case 1:
    return "vectorcall";
  case 2:
    return "vectorcall";
  case 3:
    return "__vectorcall";
  case 4:
    return "_vectorcall";
  }
}


// VisibilityAttr implementation

VisibilityAttr *VisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VisibilityAttr(Ctx, CommonInfo, Visibility);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VisibilityAttr *VisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) VisibilityAttr(Ctx, CommonInfo, Visibility);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

VisibilityAttr *VisibilityAttr::CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Visibility, I);
}

VisibilityAttr *VisibilityAttr::Create(ASTContext &Ctx, VisibilityType Visibility, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Visibility, I);
}

VisibilityAttr::VisibilityAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , VisibilityType Visibility
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Visibility, false, false)
              , visibility(Visibility)
  {
}



bool VisibilityAttr::ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
  Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
    .Case("default", VisibilityAttr::Default)
    .Case("hidden", VisibilityAttr::Hidden)
    .Case("internal", VisibilityAttr::Hidden)
    .Case("protected", VisibilityAttr::Protected)
    .Default(Optional<VisibilityType>());
  if (R) {
    Out = *R;
      return true;
    }
  return false;
}

const char *VisibilityAttr::ConvertVisibilityTypeToStr(VisibilityType Val) {
  switch(Val) {
  case VisibilityAttr::Default: return "default";
  case VisibilityAttr::Hidden: return "hidden";
  case VisibilityAttr::Protected: return "protected";
  }
  llvm_unreachable("No enumerator with that value");
}
VisibilityAttr *VisibilityAttr::clone(ASTContext &C) const {
  auto *A = new (C) VisibilityAttr(C, *this, visibility);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void VisibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << VisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << VisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::visibility";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << VisibilityAttr::ConvertVisibilityTypeToStr(getVisibility()) << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *VisibilityAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "visibility";
  case 1:
    return "visibility";
  case 2:
    return "visibility";
  }
}


// WarnUnusedAttr implementation

WarnUnusedAttr *WarnUnusedAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WarnUnusedAttr *WarnUnusedAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WarnUnusedAttr *WarnUnusedAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

WarnUnusedAttr *WarnUnusedAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

WarnUnusedAttr::WarnUnusedAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WarnUnused, false, false)
  {
}

WarnUnusedAttr *WarnUnusedAttr::clone(ASTContext &C) const {
  auto *A = new (C) WarnUnusedAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WarnUnusedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((warn_unused";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::warn_unused";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::warn_unused";
    OS << "]]";
    break;
  }
}
}

const char *WarnUnusedAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "warn_unused";
  case 1:
    return "warn_unused";
  case 2:
    return "warn_unused";
  }
}


// WarnUnusedResultAttr implementation

WarnUnusedResultAttr *WarnUnusedResultAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedResultAttr(Ctx, CommonInfo, Message);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WarnUnusedResultAttr *WarnUnusedResultAttr::Create(ASTContext &Ctx, llvm::StringRef Message, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WarnUnusedResultAttr(Ctx, CommonInfo, Message);
  return A;
}

WarnUnusedResultAttr *WarnUnusedResultAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax, WarnUnusedResultAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, Message, I);
}

WarnUnusedResultAttr *WarnUnusedResultAttr::Create(ASTContext &Ctx, llvm::StringRef Message, SourceRange Range, AttributeCommonInfo::Syntax Syntax, WarnUnusedResultAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, Message, I);
}

WarnUnusedResultAttr::WarnUnusedResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Message
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WarnUnusedResult, false, false)
              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
  {
    if (!Message.empty())
      std::memcpy(message, Message.data(), messageLength);
}

WarnUnusedResultAttr::WarnUnusedResultAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WarnUnusedResult, false, false)
              , messageLength(0),message(nullptr)
  {
}

WarnUnusedResultAttr::Spelling WarnUnusedResultAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return CXX11_nodiscard;
    case 1: return C2x_nodiscard;
    case 2: return CXX11_clang_warn_unused_result;
    case 3: return GNU_warn_unused_result;
    case 4: return CXX11_gnu_warn_unused_result;
    case 5: return C2x_gnu_warn_unused_result;
  }
}


WarnUnusedResultAttr *WarnUnusedResultAttr::clone(ASTContext &C) const {
  auto *A = new (C) WarnUnusedResultAttr(C, *this, getMessage());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WarnUnusedResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " [[nodiscard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 1 : {
    OS << " [[nodiscard";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[gnu::warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[gnu::warn_unused_result";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getMessage() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WarnUnusedResultAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "nodiscard";
  case 1:
    return "nodiscard";
  case 2:
    return "warn_unused_result";
  case 3:
    return "warn_unused_result";
  case 4:
    return "warn_unused_result";
  case 5:
    return "warn_unused_result";
  }
}


// WeakAttr implementation

WeakAttr *WeakAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakAttr *WeakAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakAttr *WeakAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

WeakAttr *WeakAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

WeakAttr::WeakAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::Weak, false, false)
  {
}

WeakAttr *WeakAttr::clone(ASTContext &C) const {
  auto *A = new (C) WeakAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WeakAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((weak";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::weak";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::weak";
    OS << "]]";
    break;
  }
}
}

const char *WeakAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "weak";
  case 1:
    return "weak";
  case 2:
    return "weak";
  }
}


// WeakImportAttr implementation

WeakImportAttr *WeakImportAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakImportAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakImportAttr *WeakImportAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakImportAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakImportAttr *WeakImportAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

WeakImportAttr *WeakImportAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

WeakImportAttr::WeakImportAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WeakImport, false, false)
  {
}

WeakImportAttr *WeakImportAttr::clone(ASTContext &C) const {
  auto *A = new (C) WeakImportAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WeakImportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((weak_import";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::weak_import";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::weak_import";
    OS << "]]";
    break;
  }
}
}

const char *WeakImportAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "weak_import";
  case 1:
    return "weak_import";
  case 2:
    return "weak_import";
  }
}


// WeakRefAttr implementation

WeakRefAttr *WeakRefAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakRefAttr(Ctx, CommonInfo, Aliasee);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakRefAttr *WeakRefAttr::Create(ASTContext &Ctx, llvm::StringRef Aliasee, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WeakRefAttr(Ctx, CommonInfo, Aliasee);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WeakRefAttr *WeakRefAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, Aliasee, I);
}

WeakRefAttr *WeakRefAttr::Create(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, Aliasee, I);
}

WeakRefAttr::WeakRefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef Aliasee
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WeakRef, false, false)
              , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
  {
    if (!Aliasee.empty())
      std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
}

WeakRefAttr::WeakRefAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WeakRef, false, false)
              , aliaseeLength(0),aliasee(nullptr)
  {
}



WeakRefAttr *WeakRefAttr::clone(ASTContext &C) const {
  auto *A = new (C) WeakRefAttr(C, *this, getAliasee());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WeakRefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((weakref";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::weakref";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::weakref";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getAliasee() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WeakRefAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "weakref";
  case 1:
    return "weakref";
  case 2:
    return "weakref";
  }
}


// WebAssemblyExportNameAttr implementation

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ExportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyExportNameAttr(Ctx, CommonInfo, ExportName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ExportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyExportNameAttr(Ctx, CommonInfo, ExportName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ExportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ExportName, I);
}

WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ExportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ExportName, I);
}

WebAssemblyExportNameAttr::WebAssemblyExportNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef ExportName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WebAssemblyExportName, false, false)
              , exportNameLength(ExportName.size()),exportName(new (Ctx, 1) char[exportNameLength])
  {
    if (!ExportName.empty())
      std::memcpy(exportName, ExportName.data(), exportNameLength);
}



WebAssemblyExportNameAttr *WebAssemblyExportNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) WebAssemblyExportNameAttr(C, *this, getExportName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WebAssemblyExportNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((export_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getExportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::export_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getExportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::export_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getExportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WebAssemblyExportNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "export_name";
  case 1:
    return "export_name";
  case 2:
    return "export_name";
  }
}


// WebAssemblyImportModuleAttr implementation

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportModule, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportModuleAttr(Ctx, CommonInfo, ImportModule);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::Create(ASTContext &Ctx, llvm::StringRef ImportModule, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportModuleAttr(Ctx, CommonInfo, ImportModule);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportModule, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ImportModule, I);
}

WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::Create(ASTContext &Ctx, llvm::StringRef ImportModule, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ImportModule, I);
}

WebAssemblyImportModuleAttr::WebAssemblyImportModuleAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef ImportModule
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WebAssemblyImportModule, false, false)
              , importModuleLength(ImportModule.size()),importModule(new (Ctx, 1) char[importModuleLength])
  {
    if (!ImportModule.empty())
      std::memcpy(importModule, ImportModule.data(), importModuleLength);
}



WebAssemblyImportModuleAttr *WebAssemblyImportModuleAttr::clone(ASTContext &C) const {
  auto *A = new (C) WebAssemblyImportModuleAttr(C, *this, getImportModule());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WebAssemblyImportModuleAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((import_module";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportModule() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::import_module";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportModule() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::import_module";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportModule() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WebAssemblyImportModuleAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "import_module";
  case 1:
    return "import_module";
  case 2:
    return "import_module";
  }
}


// WebAssemblyImportNameAttr implementation

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportNameAttr(Ctx, CommonInfo, ImportName);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ImportName, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WebAssemblyImportNameAttr(Ctx, CommonInfo, ImportName);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ImportName, I);
}

WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::Create(ASTContext &Ctx, llvm::StringRef ImportName, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ImportName, I);
}

WebAssemblyImportNameAttr::WebAssemblyImportNameAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , llvm::StringRef ImportName
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WebAssemblyImportName, false, false)
              , importNameLength(ImportName.size()),importName(new (Ctx, 1) char[importNameLength])
  {
    if (!ImportName.empty())
      std::memcpy(importName, ImportName.data(), importNameLength);
}



WebAssemblyImportNameAttr *WebAssemblyImportNameAttr::clone(ASTContext &C) const {
  auto *A = new (C) WebAssemblyImportNameAttr(C, *this, getImportName());
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WebAssemblyImportNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((import_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::import_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::import_name";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "\"" << getImportName() << "\"";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *WebAssemblyImportNameAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "import_name";
  case 1:
    return "import_name";
  case 2:
    return "import_name";
  }
}


// WorkGroupSizeHintAttr implementation

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WorkGroupSizeHintAttr(Ctx, CommonInfo, XDim, YDim, ZDim);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::Create(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) WorkGroupSizeHintAttr(Ctx, CommonInfo, XDim, YDim, ZDim);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, XDim, YDim, ZDim, I);
}

WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::Create(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, XDim, YDim, ZDim, I);
}

WorkGroupSizeHintAttr::WorkGroupSizeHintAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned XDim
              , unsigned YDim
              , unsigned ZDim
             )
  : InheritableAttr(Ctx, CommonInfo, attr::WorkGroupSizeHint, false, false)
              , xDim(XDim)
              , yDim(YDim)
              , zDim(ZDim)
  {
}







WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::clone(ASTContext &C) const {
  auto *A = new (C) WorkGroupSizeHintAttr(C, *this, xDim, yDim, zDim);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void WorkGroupSizeHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((work_group_size_hint";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getXDim() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getYDim() << "";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getZDim() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
}
}

const char *WorkGroupSizeHintAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "work_group_size_hint";
  }
}


// X86ForceAlignArgPointerAttr implementation

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) X86ForceAlignArgPointerAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) X86ForceAlignArgPointerAttr(Ctx, CommonInfo);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, I);
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, I);
}

X86ForceAlignArgPointerAttr::X86ForceAlignArgPointerAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::X86ForceAlignArgPointer, false, false)
  {
}

X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::clone(ASTContext &C) const {
  auto *A = new (C) X86ForceAlignArgPointerAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void X86ForceAlignArgPointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((force_align_arg_pointer";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[gnu::force_align_arg_pointer";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[gnu::force_align_arg_pointer";
    OS << "]]";
    break;
  }
}
}

const char *X86ForceAlignArgPointerAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "force_align_arg_pointer";
  case 1:
    return "force_align_arg_pointer";
  case 2:
    return "force_align_arg_pointer";
  }
}


// XRayInstrumentAttr implementation

XRayInstrumentAttr *XRayInstrumentAttr::CreateImplicit(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayInstrumentAttr(Ctx, CommonInfo);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

XRayInstrumentAttr *XRayInstrumentAttr::Create(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayInstrumentAttr(Ctx, CommonInfo);
  return A;
}

XRayInstrumentAttr *XRayInstrumentAttr::CreateImplicit(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, XRayInstrumentAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return CreateImplicit(Ctx, I);
}

XRayInstrumentAttr *XRayInstrumentAttr::Create(ASTContext &Ctx, SourceRange Range, AttributeCommonInfo::Syntax Syntax, XRayInstrumentAttr::Spelling S) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax, S);
  return Create(Ctx, I);
}

XRayInstrumentAttr::XRayInstrumentAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
             )
  : InheritableAttr(Ctx, CommonInfo, attr::XRayInstrument, false, false)
  {
}

XRayInstrumentAttr::Spelling XRayInstrumentAttr::getSemanticSpelling() const {
  switch (getAttributeSpellingListIndex()) {
    default: llvm_unreachable("Unknown spelling list index");
    case 0: return GNU_xray_always_instrument;
    case 1: return CXX11_clang_xray_always_instrument;
    case 2: return C2x_clang_xray_always_instrument;
    case 3: return GNU_xray_never_instrument;
    case 4: return CXX11_clang_xray_never_instrument;
    case 5: return C2x_clang_xray_never_instrument;
  }
}
XRayInstrumentAttr *XRayInstrumentAttr::clone(ASTContext &C) const {
  auto *A = new (C) XRayInstrumentAttr(C, *this);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void XRayInstrumentAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((xray_always_instrument";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::xray_always_instrument";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::xray_always_instrument";
    OS << "]]";
    break;
  }
  case 3 : {
    OS << " __attribute__((xray_never_instrument";
    OS << "))";
    break;
  }
  case 4 : {
    OS << " [[clang::xray_never_instrument";
    OS << "]]";
    break;
  }
  case 5 : {
    OS << " [[clang::xray_never_instrument";
    OS << "]]";
    break;
  }
}
}

const char *XRayInstrumentAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "xray_always_instrument";
  case 1:
    return "xray_always_instrument";
  case 2:
    return "xray_always_instrument";
  case 3:
    return "xray_never_instrument";
  case 4:
    return "xray_never_instrument";
  case 5:
    return "xray_never_instrument";
  }
}


// XRayLogArgsAttr implementation

XRayLogArgsAttr *XRayLogArgsAttr::CreateImplicit(ASTContext &Ctx, unsigned ArgumentCount, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayLogArgsAttr(Ctx, CommonInfo, ArgumentCount);
  A->setImplicit(true);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

XRayLogArgsAttr *XRayLogArgsAttr::Create(ASTContext &Ctx, unsigned ArgumentCount, const AttributeCommonInfo &CommonInfo) {
  auto *A = new (Ctx) XRayLogArgsAttr(Ctx, CommonInfo, ArgumentCount);
  if (!A->isAttributeSpellingListCalculated() && !A->getAttrName())
    A->setAttributeSpellingListIndex(0);
  return A;
}

XRayLogArgsAttr *XRayLogArgsAttr::CreateImplicit(ASTContext &Ctx, unsigned ArgumentCount, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return CreateImplicit(Ctx, ArgumentCount, I);
}

XRayLogArgsAttr *XRayLogArgsAttr::Create(ASTContext &Ctx, unsigned ArgumentCount, SourceRange Range, AttributeCommonInfo::Syntax Syntax) {
  AttributeCommonInfo I(Range, NoSemaHandlerAttribute, Syntax);
  return Create(Ctx, ArgumentCount, I);
}

XRayLogArgsAttr::XRayLogArgsAttr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo
              , unsigned ArgumentCount
             )
  : InheritableAttr(Ctx, CommonInfo, attr::XRayLogArgs, false, false)
              , argumentCount(ArgumentCount)
  {
}



XRayLogArgsAttr *XRayLogArgsAttr::clone(ASTContext &C) const {
  auto *A = new (C) XRayLogArgsAttr(C, *this, argumentCount);
  A->Inherited = Inherited;
  A->IsPackExpansion = IsPackExpansion;
  A->setImplicit(Implicit);
  return A;
}

void XRayLogArgsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
  bool IsFirstArgument = true; (void)IsFirstArgument;
  unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    break;
  case 0 : {
    OS << " __attribute__((xray_log_args";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentCount() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "))";
    break;
  }
  case 1 : {
    OS << " [[clang::xray_log_args";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentCount() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
  case 2 : {
    OS << " [[clang::xray_log_args";
    DelimitAttributeArgument(OS, IsFirstArgument);
    OS << "" << getArgumentCount() << "";
    if (!IsFirstArgument)
      OS << ")";
    OS << "]]";
    break;
  }
}
}

const char *XRayLogArgsAttr::getSpelling() const {
  switch (getAttributeSpellingListIndex()) {
  default:
    llvm_unreachable("Unknown attribute spelling!");
    return "(No spelling)";
  case 0:
    return "xray_log_args";
  case 1:
    return "xray_log_args";
  case 2:
    return "xray_log_args";
  }
}

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::BTFDeclTag:
    return cast<BTFDeclTagAttr>(this)->getSpelling();
  case attr::BTFTypeTag:
    return cast<BTFTypeTagAttr>(this)->getSpelling();
  case attr::Blocks:
    return cast<BlocksAttr>(this)->getSpelling();
  case attr::Builtin:
    return cast<BuiltinAttr>(this)->getSpelling();
  case attr::BuiltinAlias:
    return cast<BuiltinAliasAttr>(this)->getSpelling();
  case attr::C11NoReturn:
    return cast<C11NoReturnAttr>(this)->getSpelling();
  case attr::CDecl:
    return cast<CDeclAttr>(this)->getSpelling();
  case attr::CFAuditedTransfer:
    return cast<CFAuditedTransferAttr>(this)->getSpelling();
  case attr::CFConsumed:
    return cast<CFConsumedAttr>(this)->getSpelling();
  case attr::CFGuard:
    return cast<CFGuardAttr>(this)->getSpelling();
  case attr::CFICanonicalJumpTable:
    return cast<CFICanonicalJumpTableAttr>(this)->getSpelling();
  case attr::CFReturnsNotRetained:
    return cast<CFReturnsNotRetainedAttr>(this)->getSpelling();
  case attr::CFReturnsRetained:
    return cast<CFReturnsRetainedAttr>(this)->getSpelling();
  case attr::CFUnknownTransfer:
    return cast<CFUnknownTransferAttr>(this)->getSpelling();
  case attr::CPUDispatch:
    return cast<CPUDispatchAttr>(this)->getSpelling();
  case attr::CPUSpecific:
    return cast<CPUSpecificAttr>(this)->getSpelling();
  case attr::CUDAConstant:
    return cast<CUDAConstantAttr>(this)->getSpelling();
  case attr::CUDADevice:
    return cast<CUDADeviceAttr>(this)->getSpelling();
  case attr::CUDADeviceBuiltinSurfaceType:
    return cast<CUDADeviceBuiltinSurfaceTypeAttr>(this)->getSpelling();
  case attr::CUDADeviceBuiltinTextureType:
    return cast<CUDADeviceBuiltinTextureTypeAttr>(this)->getSpelling();
  case attr::CUDAGlobal:
    return cast<CUDAGlobalAttr>(this)->getSpelling();
  case attr::CUDAHost:
    return cast<CUDAHostAttr>(this)->getSpelling();
  case attr::CUDAInvalidTarget:
    return cast<CUDAInvalidTargetAttr>(this)->getSpelling();
  case attr::CUDALaunchBounds:
    return cast<CUDALaunchBoundsAttr>(this)->getSpelling();
  case attr::CUDAShared:
    return cast<CUDASharedAttr>(this)->getSpelling();
  case attr::CXX11NoReturn:
    return cast<CXX11NoReturnAttr>(this)->getSpelling();
  case attr::CallableWhen:
    return cast<CallableWhenAttr>(this)->getSpelling();
  case attr::Callback:
    return cast<CallbackAttr>(this)->getSpelling();
  case attr::CalledOnce:
    return cast<CalledOnceAttr>(this)->getSpelling();
  case attr::Capability:
    return cast<CapabilityAttr>(this)->getSpelling();
  case attr::CapturedRecord:
    return cast<CapturedRecordAttr>(this)->getSpelling();
  case attr::CarriesDependency:
    return cast<CarriesDependencyAttr>(this)->getSpelling();
  case attr::Cleanup:
    return cast<CleanupAttr>(this)->getSpelling();
  case attr::CmseNSCall:
    return cast<CmseNSCallAttr>(this)->getSpelling();
  case attr::CmseNSEntry:
    return cast<CmseNSEntryAttr>(this)->getSpelling();
  case attr::CodeSeg:
    return cast<CodeSegAttr>(this)->getSpelling();
  case attr::Cold:
    return cast<ColdAttr>(this)->getSpelling();
  case attr::Common:
    return cast<CommonAttr>(this)->getSpelling();
  case attr::Const:
    return cast<ConstAttr>(this)->getSpelling();
  case attr::ConstInit:
    return cast<ConstInitAttr>(this)->getSpelling();
  case attr::Constructor:
    return cast<ConstructorAttr>(this)->getSpelling();
  case attr::Consumable:
    return cast<ConsumableAttr>(this)->getSpelling();
  case attr::ConsumableAutoCast:
    return cast<ConsumableAutoCastAttr>(this)->getSpelling();
  case attr::ConsumableSetOnRead:
    return cast<ConsumableSetOnReadAttr>(this)->getSpelling();
  case attr::Convergent:
    return cast<ConvergentAttr>(this)->getSpelling();
  case attr::DLLExport:
    return cast<DLLExportAttr>(this)->getSpelling();
  case attr::DLLExportStaticLocal:
    return cast<DLLExportStaticLocalAttr>(this)->getSpelling();
  case attr::DLLImport:
    return cast<DLLImportAttr>(this)->getSpelling();
  case attr::DLLImportStaticLocal:
    return cast<DLLImportStaticLocalAttr>(this)->getSpelling();
  case attr::Deprecated:
    return cast<DeprecatedAttr>(this)->getSpelling();
  case attr::Destructor:
    return cast<DestructorAttr>(this)->getSpelling();
  case attr::DiagnoseIf:
    return cast<DiagnoseIfAttr>(this)->getSpelling();
  case attr::DisableSanitizerInstrumentation:
    return cast<DisableSanitizerInstrumentationAttr>(this)->getSpelling();
  case attr::DisableTailCalls:
    return cast<DisableTailCallsAttr>(this)->getSpelling();
  case attr::EmptyBases:
    return cast<EmptyBasesAttr>(this)->getSpelling();
  case attr::EnableIf:
    return cast<EnableIfAttr>(this)->getSpelling();
  case attr::EnforceTCB:
    return cast<EnforceTCBAttr>(this)->getSpelling();
  case attr::EnforceTCBLeaf:
    return cast<EnforceTCBLeafAttr>(this)->getSpelling();
  case attr::EnumExtensibility:
    return cast<EnumExtensibilityAttr>(this)->getSpelling();
  case attr::Error:
    return cast<ErrorAttr>(this)->getSpelling();
  case attr::ExcludeFromExplicitInstantiation:
    return cast<ExcludeFromExplicitInstantiationAttr>(this)->getSpelling();
  case attr::ExclusiveTrylockFunction:
    return cast<ExclusiveTrylockFunctionAttr>(this)->getSpelling();
  case attr::ExternalSourceSymbol:
    return cast<ExternalSourceSymbolAttr>(this)->getSpelling();
  case attr::FallThrough:
    return cast<FallThroughAttr>(this)->getSpelling();
  case attr::FastCall:
    return cast<FastCallAttr>(this)->getSpelling();
  case attr::Final:
    return cast<FinalAttr>(this)->getSpelling();
  case attr::FlagEnum:
    return cast<FlagEnumAttr>(this)->getSpelling();
  case attr::Flatten:
    return cast<FlattenAttr>(this)->getSpelling();
  case attr::Format:
    return cast<FormatAttr>(this)->getSpelling();
  case attr::FormatArg:
    return cast<FormatArgAttr>(this)->getSpelling();
  case attr::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::NoProfileFunction:
    return cast<NoProfileFunctionAttr>(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::SwiftAsyncCall:
    return cast<SwiftAsyncCallAttr>(this)->getSpelling();
  case attr::SwiftAsyncContext:
    return cast<SwiftAsyncContextAttr>(this)->getSpelling();
  case attr::SwiftAsyncError:
    return cast<SwiftAsyncErrorAttr>(this)->getSpelling();
  case attr::SwiftAsyncName:
    return cast<SwiftAsyncNameAttr>(this)->getSpelling();
  case attr::SwiftAttr:
    return cast<SwiftAttrAttr>(this)->getSpelling();
  case attr::SwiftBridge:
    return cast<SwiftBridgeAttr>(this)->getSpelling();
  case attr::SwiftBridgedTypedef:
    return cast<SwiftBridgedTypedefAttr>(this)->getSpelling();
  case attr::SwiftCall:
    return cast<SwiftCallAttr>(this)->getSpelling();
  case attr::SwiftContext:
    return cast<SwiftContextAttr>(this)->getSpelling();
  case attr::SwiftError:
    return cast<SwiftErrorAttr>(this)->getSpelling();
  case attr::SwiftErrorResult:
    return cast<SwiftErrorResultAttr>(this)->getSpelling();
  case attr::SwiftIndirectResult:
    return cast<SwiftIndirectResultAttr>(this)->getSpelling();
  case attr::SwiftName:
    return cast<SwiftNameAttr>(this)->getSpelling();
  case attr::SwiftNewType:
    return cast<SwiftNewTypeAttr>(this)->getSpelling();
  case attr::SwiftObjCMembers:
    return cast<SwiftObjCMembersAttr>(this)->getSpelling();
  case attr::SwiftPrivate:
    return cast<SwiftPrivateAttr>(this)->getSpelling();
  case attr::SysVABI:
    return cast<SysVABIAttr>(this)->getSpelling();
  case attr::TLSModel:
    return cast<TLSModelAttr>(this)->getSpelling();
  case attr::Target:
    return cast<TargetAttr>(this)->getSpelling();
  case attr::TargetClones:
    return cast<TargetClonesAttr>(this)->getSpelling();
  case attr::TestTypestate:
    return cast<TestTypestateAttr>(this)->getSpelling();
  case attr::ThisCall:
    return cast<ThisCallAttr>(this)->getSpelling();
  case attr::Thread:
    return cast<ThreadAttr>(this)->getSpelling();
  case attr::TransparentUnion:
    return cast<TransparentUnionAttr>(this)->getSpelling();
  case attr::TrivialABI:
    return cast<TrivialABIAttr>(this)->getSpelling();
  case attr::TryAcquireCapability:
    return cast<TryAcquireCapabilityAttr>(this)->getSpelling();
  case attr::TypeNonNull:
    return cast<TypeNonNullAttr>(this)->getSpelling();
  case attr::TypeNullUnspecified:
    return cast<TypeNullUnspecifiedAttr>(this)->getSpelling();
  case attr::TypeNullable:
    return cast<TypeNullableAttr>(this)->getSpelling();
  case attr::TypeNullableResult:
    return cast<TypeNullableResultAttr>(this)->getSpelling();
  case attr::TypeTagForDatatype:
    return cast<TypeTagForDatatypeAttr>(this)->getSpelling();
  case attr::TypeVisibility:
    return cast<TypeVisibilityAttr>(this)->getSpelling();
  case attr::UPtr:
    return cast<UPtrAttr>(this)->getSpelling();
  case attr::Unavailable:
    return cast<UnavailableAttr>(this)->getSpelling();
  case attr::Uninitialized:
    return cast<UninitializedAttr>(this)->getSpelling();
  case attr::Unlikely:
    return cast<UnlikelyAttr>(this)->getSpelling();
  case attr::Unused:
    return cast<UnusedAttr>(this)->getSpelling();
  case attr::UseHandle:
    return cast<UseHandleAttr>(this)->getSpelling();
  case attr::Used:
    return cast<UsedAttr>(this)->getSpelling();
  case attr::UsingIfExists:
    return cast<UsingIfExistsAttr>(this)->getSpelling();
  case attr::Uuid:
    return cast<UuidAttr>(this)->getSpelling();
  case attr::VecReturn:
    return cast<VecReturnAttr>(this)->getSpelling();
  case attr::VecTypeHint:
    return cast<VecTypeHintAttr>(this)->getSpelling();
  case attr::VectorCall:
    return cast<VectorCallAttr>(this)->getSpelling();
  case attr::Visibility:
    return cast<VisibilityAttr>(this)->getSpelling();
  case attr::WarnUnused:
    return cast<WarnUnusedAttr>(this)->getSpelling();
  case attr::WarnUnusedResult:
    return cast<WarnUnusedResultAttr>(this)->getSpelling();
  case attr::Weak:
    return cast<WeakAttr>(this)->getSpelling();
  case attr::WeakImport:
    return cast<WeakImportAttr>(this)->getSpelling();
  case attr::WeakRef:
    return cast<WeakRefAttr>(this)->getSpelling();
  case attr::WebAssemblyExportName:
    return cast<WebAssemblyExportNameAttr>(this)->getSpelling();
  case attr::WebAssemblyImportModule:
    return cast<WebAssemblyImportModuleAttr>(this)->getSpelling();
  case attr::WebAssemblyImportName:
    return cast<WebAssemblyImportNameAttr>(this)->getSpelling();
  case attr::WorkGroupSizeHint:
    return cast<WorkGroupSizeHintAttr>(this)->getSpelling();
  case attr::X86ForceAlignArgPointer:
    return cast<X86ForceAlignArgPointerAttr>(this)->getSpelling();
  case attr::XRayInstrument:
    return cast<XRayInstrumentAttr>(this)->getSpelling();
  case attr::XRayLogArgs:
    return cast<XRayLogArgsAttr>(this)->getSpelling();
  }
  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::BTFDeclTag:
    return cast<BTFDeclTagAttr>(this)->clone(C);
  case attr::BTFTypeTag:
    return cast<BTFTypeTagAttr>(this)->clone(C);
  case attr::Blocks:
    return cast<BlocksAttr>(this)->clone(C);
  case attr::Builtin:
    return cast<BuiltinAttr>(this)->clone(C);
  case attr::BuiltinAlias:
    return cast<BuiltinAliasAttr>(this)->clone(C);
  case attr::C11NoReturn:
    return cast<C11NoReturnAttr>(this)->clone(C);
  case attr::CDecl:
    return cast<CDeclAttr>(this)->clone(C);
  case attr::CFAuditedTransfer:
    return cast<CFAuditedTransferAttr>(this)->clone(C);
  case attr::CFConsumed:
    return cast<CFConsumedAttr>(this)->clone(C);
  case attr::CFGuard:
    return cast<CFGuardAttr>(this)->clone(C);
  case attr::CFICanonicalJumpTable:
    return cast<CFICanonicalJumpTableAttr>(this)->clone(C);
  case attr::CFReturnsNotRetained:
    return cast<CFReturnsNotRetainedAttr>(this)->clone(C);
  case attr::CFReturnsRetained:
    return cast<CFReturnsRetainedAttr>(this)->clone(C);
  case attr::CFUnknownTransfer:
    return cast<CFUnknownTransferAttr>(this)->clone(C);
  case attr::CPUDispatch:
    return cast<CPUDispatchAttr>(this)->clone(C);
  case attr::CPUSpecific:
    return cast<CPUSpecificAttr>(this)->clone(C);
  case attr::CUDAConstant:
    return cast<CUDAConstantAttr>(this)->clone(C);
  case attr::CUDADevice:
    return cast<CUDADeviceAttr>(this)->clone(C);
  case attr::CUDADeviceBuiltinSurfaceType:
    return cast<CUDADeviceBuiltinSurfaceTypeAttr>(this)->clone(C);
  case attr::CUDADeviceBuiltinTextureType:
    return cast<CUDADeviceBuiltinTextureTypeAttr>(this)->clone(C);
  case attr::CUDAGlobal:
    return cast<CUDAGlobalAttr>(this)->clone(C);
  case attr::CUDAHost:
    return cast<CUDAHostAttr>(this)->clone(C);
  case attr::CUDAInvalidTarget:
    return cast<CUDAInvalidTargetAttr>(this)->clone(C);
  case attr::CUDALaunchBounds:
    return cast<CUDALaunchBoundsAttr>(this)->clone(C);
  case attr::CUDAShared:
    return cast<CUDASharedAttr>(this)->clone(C);
  case attr::CXX11NoReturn:
    return cast<CXX11NoReturnAttr>(this)->clone(C);
  case attr::CallableWhen:
    return cast<CallableWhenAttr>(this)->clone(C);
  case attr::Callback:
    return cast<CallbackAttr>(this)->clone(C);
  case attr::CalledOnce:
    return cast<CalledOnceAttr>(this)->clone(C);
  case attr::Capability:
    return cast<CapabilityAttr>(this)->clone(C);
  case attr::CapturedRecord:
    return cast<CapturedRecordAttr>(this)->clone(C);
  case attr::CarriesDependency:
    return cast<CarriesDependencyAttr>(this)->clone(C);
  case attr::Cleanup:
    return cast<CleanupAttr>(this)->clone(C);
  case attr::CmseNSCall:
    return cast<CmseNSCallAttr>(this)->clone(C);
  case attr::CmseNSEntry:
    return cast<CmseNSEntryAttr>(this)->clone(C);
  case attr::CodeSeg:
    return cast<CodeSegAttr>(this)->clone(C);
  case attr::Cold:
    return cast<ColdAttr>(this)->clone(C);
  case attr::Common:
    return cast<CommonAttr>(this)->clone(C);
  case attr::Const:
    return cast<ConstAttr>(this)->clone(C);
  case attr::ConstInit:
    return cast<ConstInitAttr>(this)->clone(C);
  case attr::Constructor:
    return cast<ConstructorAttr>(this)->clone(C);
  case attr::Consumable:
    return cast<ConsumableAttr>(this)->clone(C);
  case attr::ConsumableAutoCast:
    return cast<ConsumableAutoCastAttr>(this)->clone(C);
  case attr::ConsumableSetOnRead:
    return cast<ConsumableSetOnReadAttr>(this)->clone(C);
  case attr::Convergent:
    return cast<ConvergentAttr>(this)->clone(C);
  case attr::DLLExport:
    return cast<DLLExportAttr>(this)->clone(C);
  case attr::DLLExportStaticLocal:
    return cast<DLLExportStaticLocalAttr>(this)->clone(C);
  case attr::DLLImport:
    return cast<DLLImportAttr>(this)->clone(C);
  case attr::DLLImportStaticLocal:
    return cast<DLLImportStaticLocalAttr>(this)->clone(C);
  case attr::Deprecated:
    return cast<DeprecatedAttr>(this)->clone(C);
  case attr::Destructor:
    return cast<DestructorAttr>(this)->clone(C);
  case attr::DiagnoseIf:
    return cast<DiagnoseIfAttr>(this)->clone(C);
  case attr::DisableSanitizerInstrumentation:
    return cast<DisableSanitizerInstrumentationAttr>(this)->clone(C);
  case attr::DisableTailCalls:
    return cast<DisableTailCallsAttr>(this)->clone(C);
  case attr::EmptyBases:
    return cast<EmptyBasesAttr>(this)->clone(C);
  case attr::EnableIf:
    return cast<EnableIfAttr>(this)->clone(C);
  case attr::EnforceTCB:
    return cast<EnforceTCBAttr>(this)->clone(C);
  case attr::EnforceTCBLeaf:
    return cast<EnforceTCBLeafAttr>(this)->clone(C);
  case attr::EnumExtensibility:
    return cast<EnumExtensibilityAttr>(this)->clone(C);
  case attr::Error:
    return cast<ErrorAttr>(this)->clone(C);
  case attr::ExcludeFromExplicitInstantiation:
    return cast<ExcludeFromExplicitInstantiationAttr>(this)->clone(C);
  case attr::ExclusiveTrylockFunction:
    return cast<ExclusiveTrylockFunctionAttr>(this)->clone(C);
  case attr::ExternalSourceSymbol:
    return cast<ExternalSourceSymbolAttr>(this)->clone(C);
  case attr::FallThrough:
    return cast<FallThroughAttr>(this)->clone(C);
  case attr::FastCall:
    return cast<FastCallAttr>(this)->clone(C);
  case attr::Final:
    return cast<FinalAttr>(this)->clone(C);
  case attr::FlagEnum:
    return cast<FlagEnumAttr>(this)->clone(C);
  case attr::Flatten:
    return cast<FlattenAttr>(this)->clone(C);
  case attr::Format:
    return cast<FormatAttr>(this)->clone(C);
  case attr::FormatArg:
    return cast<FormatArgAttr>(this)->clone(C);
  case attr::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::NoProfileFunction:
    return cast<NoProfileFunctionAttr>(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::SwiftAsyncCall:
    return cast<SwiftAsyncCallAttr>(this)->clone(C);
  case attr::SwiftAsyncContext:
    return cast<SwiftAsyncContextAttr>(this)->clone(C);
  case attr::SwiftAsyncError:
    return cast<SwiftAsyncErrorAttr>(this)->clone(C);
  case attr::SwiftAsyncName:
    return cast<SwiftAsyncNameAttr>(this)->clone(C);
  case attr::SwiftAttr:
    return cast<SwiftAttrAttr>(this)->clone(C);
  case attr::SwiftBridge:
    return cast<SwiftBridgeAttr>(this)->clone(C);
  case attr::SwiftBridgedTypedef:
    return cast<SwiftBridgedTypedefAttr>(this)->clone(C);
  case attr::SwiftCall:
    return cast<SwiftCallAttr>(this)->clone(C);
  case attr::SwiftContext:
    return cast<SwiftContextAttr>(this)->clone(C);
  case attr::SwiftError:
    return cast<SwiftErrorAttr>(this)->clone(C);
  case attr::SwiftErrorResult:
    return cast<SwiftErrorResultAttr>(this)->clone(C);
  case attr::SwiftIndirectResult:
    return cast<SwiftIndirectResultAttr>(this)->clone(C);
  case attr::SwiftName:
    return cast<SwiftNameAttr>(this)->clone(C);
  case attr::SwiftNewType:
    return cast<SwiftNewTypeAttr>(this)->clone(C);
  case attr::SwiftObjCMembers:
    return cast<SwiftObjCMembersAttr>(this)->clone(C);
  case attr::SwiftPrivate:
    return cast<SwiftPrivateAttr>(this)->clone(C);
  case attr::SysVABI:
    return cast<SysVABIAttr>(this)->clone(C);
  case attr::TLSModel:
    return cast<TLSModelAttr>(this)->clone(C);
  case attr::Target:
    return cast<TargetAttr>(this)->clone(C);
  case attr::TargetClones:
    return cast<TargetClonesAttr>(this)->clone(C);
  case attr::TestTypestate:
    return cast<TestTypestateAttr>(this)->clone(C);
  case attr::ThisCall:
    return cast<ThisCallAttr>(this)->clone(C);
  case attr::Thread:
    return cast<ThreadAttr>(this)->clone(C);
  case attr::TransparentUnion:
    return cast<TransparentUnionAttr>(this)->clone(C);
  case attr::TrivialABI:
    return cast<TrivialABIAttr>(this)->clone(C);
  case attr::TryAcquireCapability:
    return cast<TryAcquireCapabilityAttr>(this)->clone(C);
  case attr::TypeNonNull:
    return cast<TypeNonNullAttr>(this)->clone(C);
  case attr::TypeNullUnspecified:
    return cast<TypeNullUnspecifiedAttr>(this)->clone(C);
  case attr::TypeNullable:
    return cast<TypeNullableAttr>(this)->clone(C);
  case attr::TypeNullableResult:
    return cast<TypeNullableResultAttr>(this)->clone(C);
  case attr::TypeTagForDatatype:
    return cast<TypeTagForDatatypeAttr>(this)->clone(C);
  case attr::TypeVisibility:
    return cast<TypeVisibilityAttr>(this)->clone(C);
  case attr::UPtr:
    return cast<UPtrAttr>(this)->clone(C);
  case attr::Unavailable:
    return cast<UnavailableAttr>(this)->clone(C);
  case attr::Uninitialized:
    return cast<UninitializedAttr>(this)->clone(C);
  case attr::Unlikely:
    return cast<UnlikelyAttr>(this)->clone(C);
  case attr::Unused:
    return cast<UnusedAttr>(this)->clone(C);
  case attr::UseHandle:
    return cast<UseHandleAttr>(this)->clone(C);
  case attr::Used:
    return cast<UsedAttr>(this)->clone(C);
  case attr::UsingIfExists:
    return cast<UsingIfExistsAttr>(this)->clone(C);
  case attr::Uuid:
    return cast<UuidAttr>(this)->clone(C);
  case attr::VecReturn:
    return cast<VecReturnAttr>(this)->clone(C);
  case attr::VecTypeHint:
    return cast<VecTypeHintAttr>(this)->clone(C);
  case attr::VectorCall:
    return cast<VectorCallAttr>(this)->clone(C);
  case attr::Visibility:
    return cast<VisibilityAttr>(this)->clone(C);
  case attr::WarnUnused:
    return cast<WarnUnusedAttr>(this)->clone(C);
  case attr::WarnUnusedResult:
    return cast<WarnUnusedResultAttr>(this)->clone(C);
  case attr::Weak:
    return cast<WeakAttr>(this)->clone(C);
  case attr::WeakImport:
    return cast<WeakImportAttr>(this)->clone(C);
  case attr::WeakRef:
    return cast<WeakRefAttr>(this)->clone(C);
  case attr::WebAssemblyExportName:
    return cast<WebAssemblyExportNameAttr>(this)->clone(C);
  case attr::WebAssemblyImportModule:
    return cast<WebAssemblyImportModuleAttr>(this)->clone(C);
  case attr::WebAssemblyImportName:
    return cast<WebAssemblyImportNameAttr>(this)->clone(C);
  case attr::WorkGroupSizeHint:
    return cast<WorkGroupSizeHintAttr>(this)->clone(C);
  case attr::X86ForceAlignArgPointer:
    return cast<X86ForceAlignArgPointerAttr>(this)->clone(C);
  case attr::XRayInstrument:
    return cast<XRayInstrumentAttr>(this)->clone(C);
  case attr::XRayLogArgs:
    return cast<XRayLogArgsAttr>(this)->clone(C);
  }
  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::BTFDeclTag:
    return cast<BTFDeclTagAttr>(this)->printPretty(OS, Policy);
  case attr::BTFTypeTag:
    return cast<BTFTypeTagAttr>(this)->printPretty(OS, Policy);
  case attr::Blocks:
    return cast<BlocksAttr>(this)->printPretty(OS, Policy);
  case attr::Builtin:
    return cast<BuiltinAttr>(this)->printPretty(OS, Policy);
  case attr::BuiltinAlias:
    return cast<BuiltinAliasAttr>(this)->printPretty(OS, Policy);
  case attr::C11NoReturn:
    return cast<C11NoReturnAttr>(this)->printPretty(OS, Policy);
  case attr::CDecl:
    return cast<CDeclAttr>(this)->printPretty(OS, Policy);
  case attr::CFAuditedTransfer:
    return cast<CFAuditedTransferAttr>(this)->printPretty(OS, Policy);
  case attr::CFConsumed:
    return cast<CFConsumedAttr>(this)->printPretty(OS, Policy);
  case attr::CFGuard:
    return cast<CFGuardAttr>(this)->printPretty(OS, Policy);
  case attr::CFICanonicalJumpTable:
    return cast<CFICanonicalJumpTableAttr>(this)->printPretty(OS, Policy);
  case attr::CFReturnsNotRetained:
    return cast<CFReturnsNotRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::CFReturnsRetained:
    return cast<CFReturnsRetainedAttr>(this)->printPretty(OS, Policy);
  case attr::CFUnknownTransfer:
    return cast<CFUnknownTransferAttr>(this)->printPretty(OS, Policy);
  case attr::CPUDispatch:
    return cast<CPUDispatchAttr>(this)->printPretty(OS, Policy);
  case attr::CPUSpecific:
    return cast<CPUSpecificAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAConstant:
    return cast<CUDAConstantAttr>(this)->printPretty(OS, Policy);
  case attr::CUDADevice:
    return cast<CUDADeviceAttr>(this)->printPretty(OS, Policy);
  case attr::CUDADeviceBuiltinSurfaceType:
    return cast<CUDADeviceBuiltinSurfaceTypeAttr>(this)->printPretty(OS, Policy);
  case attr::CUDADeviceBuiltinTextureType:
    return cast<CUDADeviceBuiltinTextureTypeAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAGlobal:
    return cast<CUDAGlobalAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAHost:
    return cast<CUDAHostAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAInvalidTarget:
    return cast<CUDAInvalidTargetAttr>(this)->printPretty(OS, Policy);
  case attr::CUDALaunchBounds:
    return cast<CUDALaunchBoundsAttr>(this)->printPretty(OS, Policy);
  case attr::CUDAShared:
    return cast<CUDASharedAttr>(this)->printPretty(OS, Policy);
  case attr::CXX11NoReturn:
    return cast<CXX11NoReturnAttr>(this)->printPretty(OS, Policy);
  case attr::CallableWhen:
    return cast<CallableWhenAttr>(this)->printPretty(OS, Policy);
  case attr::Callback:
    return cast<CallbackAttr>(this)->printPretty(OS, Policy);
  case attr::CalledOnce:
    return cast<CalledOnceAttr>(this)->printPretty(OS, Policy);
  case attr::Capability:
    return cast<CapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::CapturedRecord:
    return cast<CapturedRecordAttr>(this)->printPretty(OS, Policy);
  case attr::CarriesDependency:
    return cast<CarriesDependencyAttr>(this)->printPretty(OS, Policy);
  case attr::Cleanup:
    return cast<CleanupAttr>(this)->printPretty(OS, Policy);
  case attr::CmseNSCall:
    return cast<CmseNSCallAttr>(this)->printPretty(OS, Policy);
  case attr::CmseNSEntry:
    return cast<CmseNSEntryAttr>(this)->printPretty(OS, Policy);
  case attr::CodeSeg:
    return cast<CodeSegAttr>(this)->printPretty(OS, Policy);
  case attr::Cold:
    return cast<ColdAttr>(this)->printPretty(OS, Policy);
  case attr::Common:
    return cast<CommonAttr>(this)->printPretty(OS, Policy);
  case attr::Const:
    return cast<ConstAttr>(this)->printPretty(OS, Policy);
  case attr::ConstInit:
    return cast<ConstInitAttr>(this)->printPretty(OS, Policy);
  case attr::Constructor:
    return cast<ConstructorAttr>(this)->printPretty(OS, Policy);
  case attr::Consumable:
    return cast<ConsumableAttr>(this)->printPretty(OS, Policy);
  case attr::ConsumableAutoCast:
    return cast<ConsumableAutoCastAttr>(this)->printPretty(OS, Policy);
  case attr::ConsumableSetOnRead:
    return cast<ConsumableSetOnReadAttr>(this)->printPretty(OS, Policy);
  case attr::Convergent:
    return cast<ConvergentAttr>(this)->printPretty(OS, Policy);
  case attr::DLLExport:
    return cast<DLLExportAttr>(this)->printPretty(OS, Policy);
  case attr::DLLExportStaticLocal:
    return cast<DLLExportStaticLocalAttr>(this)->printPretty(OS, Policy);
  case attr::DLLImport:
    return cast<DLLImportAttr>(this)->printPretty(OS, Policy);
  case attr::DLLImportStaticLocal:
    return cast<DLLImportStaticLocalAttr>(this)->printPretty(OS, Policy);
  case attr::Deprecated:
    return cast<DeprecatedAttr>(this)->printPretty(OS, Policy);
  case attr::Destructor:
    return cast<DestructorAttr>(this)->printPretty(OS, Policy);
  case attr::DiagnoseIf:
    return cast<DiagnoseIfAttr>(this)->printPretty(OS, Policy);
  case attr::DisableSanitizerInstrumentation:
    return cast<DisableSanitizerInstrumentationAttr>(this)->printPretty(OS, Policy);
  case attr::DisableTailCalls:
    return cast<DisableTailCallsAttr>(this)->printPretty(OS, Policy);
  case attr::EmptyBases:
    return cast<EmptyBasesAttr>(this)->printPretty(OS, Policy);
  case attr::EnableIf:
    return cast<EnableIfAttr>(this)->printPretty(OS, Policy);
  case attr::EnforceTCB:
    return cast<EnforceTCBAttr>(this)->printPretty(OS, Policy);
  case attr::EnforceTCBLeaf:
    return cast<EnforceTCBLeafAttr>(this)->printPretty(OS, Policy);
  case attr::EnumExtensibility:
    return cast<EnumExtensibilityAttr>(this)->printPretty(OS, Policy);
  case attr::Error:
    return cast<ErrorAttr>(this)->printPretty(OS, Policy);
  case attr::ExcludeFromExplicitInstantiation:
    return cast<ExcludeFromExplicitInstantiationAttr>(this)->printPretty(OS, Policy);
  case attr::ExclusiveTrylockFunction:
    return cast<ExclusiveTrylockFunctionAttr>(this)->printPretty(OS, Policy);
  case attr::ExternalSourceSymbol:
    return cast<ExternalSourceSymbolAttr>(this)->printPretty(OS, Policy);
  case attr::FallThrough:
    return cast<FallThroughAttr>(this)->printPretty(OS, Policy);
  case attr::FastCall:
    return cast<FastCallAttr>(this)->printPretty(OS, Policy);
  case attr::Final:
    return cast<FinalAttr>(this)->printPretty(OS, Policy);
  case attr::FlagEnum:
    return cast<FlagEnumAttr>(this)->printPretty(OS, Policy);
  case attr::Flatten:
    return cast<FlattenAttr>(this)->printPretty(OS, Policy);
  case attr::Format:
    return cast<FormatAttr>(this)->printPretty(OS, Policy);
  case attr::FormatArg:
    return cast<FormatArgAttr>(this)->printPretty(OS, Policy);
  case attr::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::NoProfileFunction:
    return cast<NoProfileFunctionAttr>(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::SwiftAsyncCall:
    return cast<SwiftAsyncCallAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncContext:
    return cast<SwiftAsyncContextAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncError:
    return cast<SwiftAsyncErrorAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAsyncName:
    return cast<SwiftAsyncNameAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftAttr:
    return cast<SwiftAttrAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftBridge:
    return cast<SwiftBridgeAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftBridgedTypedef:
    return cast<SwiftBridgedTypedefAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftCall:
    return cast<SwiftCallAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftContext:
    return cast<SwiftContextAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftError:
    return cast<SwiftErrorAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftErrorResult:
    return cast<SwiftErrorResultAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftIndirectResult:
    return cast<SwiftIndirectResultAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftName:
    return cast<SwiftNameAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftNewType:
    return cast<SwiftNewTypeAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftObjCMembers:
    return cast<SwiftObjCMembersAttr>(this)->printPretty(OS, Policy);
  case attr::SwiftPrivate:
    return cast<SwiftPrivateAttr>(this)->printPretty(OS, Policy);
  case attr::SysVABI:
    return cast<SysVABIAttr>(this)->printPretty(OS, Policy);
  case attr::TLSModel:
    return cast<TLSModelAttr>(this)->printPretty(OS, Policy);
  case attr::Target:
    return cast<TargetAttr>(this)->printPretty(OS, Policy);
  case attr::TargetClones:
    return cast<TargetClonesAttr>(this)->printPretty(OS, Policy);
  case attr::TestTypestate:
    return cast<TestTypestateAttr>(this)->printPretty(OS, Policy);
  case attr::ThisCall:
    return cast<ThisCallAttr>(this)->printPretty(OS, Policy);
  case attr::Thread:
    return cast<ThreadAttr>(this)->printPretty(OS, Policy);
  case attr::TransparentUnion:
    return cast<TransparentUnionAttr>(this)->printPretty(OS, Policy);
  case attr::TrivialABI:
    return cast<TrivialABIAttr>(this)->printPretty(OS, Policy);
  case attr::TryAcquireCapability:
    return cast<TryAcquireCapabilityAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNonNull:
    return cast<TypeNonNullAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNullUnspecified:
    return cast<TypeNullUnspecifiedAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNullable:
    return cast<TypeNullableAttr>(this)->printPretty(OS, Policy);
  case attr::TypeNullableResult:
    return cast<TypeNullableResultAttr>(this)->printPretty(OS, Policy);
  case attr::TypeTagForDatatype:
    return cast<TypeTagForDatatypeAttr>(this)->printPretty(OS, Policy);
  case attr::TypeVisibility:
    return cast<TypeVisibilityAttr>(this)->printPretty(OS, Policy);
  case attr::UPtr:
    return cast<UPtrAttr>(this)->printPretty(OS, Policy);
  case attr::Unavailable:
    return cast<UnavailableAttr>(this)->printPretty(OS, Policy);
  case attr::Uninitialized:
    return cast<UninitializedAttr>(this)->printPretty(OS, Policy);
  case attr::Unlikely:
    return cast<UnlikelyAttr>(this)->printPretty(OS, Policy);
  case attr::Unused:
    return cast<UnusedAttr>(this)->printPretty(OS, Policy);
  case attr::UseHandle:
    return cast<UseHandleAttr>(this)->printPretty(OS, Policy);
  case attr::Used:
    return cast<UsedAttr>(this)->printPretty(OS, Policy);
  case attr::UsingIfExists:
    return cast<UsingIfExistsAttr>(this)->printPretty(OS, Policy);
  case attr::Uuid:
    return cast<UuidAttr>(this)->printPretty(OS, Policy);
  case attr::VecReturn:
    return cast<VecReturnAttr>(this)->printPretty(OS, Policy);
  case attr::VecTypeHint:
    return cast<VecTypeHintAttr>(this)->printPretty(OS, Policy);
  case attr::VectorCall:
    return cast<VectorCallAttr>(this)->printPretty(OS, Policy);
  case attr::Visibility:
    return cast<VisibilityAttr>(this)->printPretty(OS, Policy);
  case attr::WarnUnused:
    return cast<WarnUnusedAttr>(this)->printPretty(OS, Policy);
  case attr::WarnUnusedResult:
    return cast<WarnUnusedResultAttr>(this)->printPretty(OS, Policy);
  case attr::Weak:
    return cast<WeakAttr>(this)->printPretty(OS, Policy);
  case attr::WeakImport:
    return cast<WeakImportAttr>(this)->printPretty(OS, Policy);
  case attr::WeakRef:
    return cast<WeakRefAttr>(this)->printPretty(OS, Policy);
  case attr::WebAssemblyExportName:
    return cast<WebAssemblyExportNameAttr>(this)->printPretty(OS, Policy);
  case attr::WebAssemblyImportModule:
    return cast<WebAssemblyImportModuleAttr>(this)->printPretty(OS, Policy);
  case attr::WebAssemblyImportName:
    return cast<WebAssemblyImportNameAttr>(this)->printPretty(OS, Policy);
  case attr::WorkGroupSizeHint:
    return cast<WorkGroupSizeHintAttr>(this)->printPretty(OS, Policy);
  case attr::X86ForceAlignArgPointer:
    return cast<X86ForceAlignArgPointerAttr>(this)->printPretty(OS, Policy);
  case attr::XRayInstrument:
    return cast<XRayInstrumentAttr>(this)->printPretty(OS, Policy);
  case attr::XRayLogArgs:
    return cast<XRayLogArgsAttr>(this)->printPretty(OS, Policy);
  }
  llvm_unreachable("Unexpected attribute kind!");
}

