brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.6 KiB · f0c9cc8 Raw
782 lines · cpp
1//===------ SemaSwift.cpp ------ Swift language-specific routines ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file implements semantic analysis functions specific to Swift.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Sema/SemaSwift.h"14#include "clang/AST/DeclBase.h"15#include "clang/Basic/AttributeCommonInfo.h"16#include "clang/Basic/DiagnosticSema.h"17#include "clang/Basic/Specifiers.h"18#include "clang/Sema/Attr.h"19#include "clang/Sema/ParsedAttr.h"20#include "clang/Sema/Sema.h"21#include "clang/Sema/SemaObjC.h"22 23namespace clang {24SemaSwift::SemaSwift(Sema &S) : SemaBase(S) {}25 26SwiftNameAttr *SemaSwift::mergeNameAttr(Decl *D, const SwiftNameAttr &SNA,27                                        StringRef Name) {28  if (const auto *PrevSNA = D->getAttr<SwiftNameAttr>()) {29    if (PrevSNA->getName() != Name && !PrevSNA->isImplicit()) {30      Diag(PrevSNA->getLocation(), diag::err_attributes_are_not_compatible)31          << PrevSNA << &SNA32          << (PrevSNA->isRegularKeywordAttribute() ||33              SNA.isRegularKeywordAttribute());34      Diag(SNA.getLoc(), diag::note_conflicting_attribute);35    }36 37    D->dropAttr<SwiftNameAttr>();38  }39  return ::new (getASTContext()) SwiftNameAttr(getASTContext(), SNA, Name);40}41 42/// Pointer-like types in the default address space.43static bool isValidSwiftContextType(QualType Ty) {44  if (!Ty->hasPointerRepresentation())45    return Ty->isDependentType();46  return Ty->getPointeeType().getAddressSpace() == LangAS::Default;47}48 49/// Pointers and references in the default address space.50static bool isValidSwiftIndirectResultType(QualType Ty) {51  if (const auto *PtrType = Ty->getAs<PointerType>()) {52    Ty = PtrType->getPointeeType();53  } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {54    Ty = RefType->getPointeeType();55  } else {56    return Ty->isDependentType();57  }58  return Ty.getAddressSpace() == LangAS::Default;59}60 61/// Pointers and references to pointers in the default address space.62static bool isValidSwiftErrorResultType(QualType Ty) {63  if (const auto *PtrType = Ty->getAs<PointerType>()) {64    Ty = PtrType->getPointeeType();65  } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {66    Ty = RefType->getPointeeType();67  } else {68    return Ty->isDependentType();69  }70  if (!Ty.getQualifiers().empty())71    return false;72  return isValidSwiftContextType(Ty);73}74 75static bool isValidSwiftContextName(StringRef ContextName) {76  // ContextName might be qualified, e.g. 'MyNamespace.MyStruct'.77  SmallVector<StringRef, 1> ContextNameComponents;78  ContextName.split(ContextNameComponents, '.');79  return all_of(ContextNameComponents, [&](StringRef Component) {80    return isValidAsciiIdentifier(Component);81  });82}83 84void SemaSwift::handleAttrAttr(Decl *D, const ParsedAttr &AL) {85  if (AL.isInvalid() || AL.isUsedAsTypeAttr())86    return;87 88  // Make sure that there is a string literal as the annotation's single89  // argument.90  StringRef Str;91  if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str)) {92    AL.setInvalid();93    return;94  }95 96  D->addAttr(::new (getASTContext()) SwiftAttrAttr(getASTContext(), AL, Str));97}98 99void SemaSwift::handleBridge(Decl *D, const ParsedAttr &AL) {100  // Make sure that there is a string literal as the annotation's single101  // argument.102  StringRef BT;103  if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, BT))104    return;105 106  // Warn about duplicate attributes if they have different arguments, but drop107  // any duplicate attributes regardless.108  if (const auto *Other = D->getAttr<SwiftBridgeAttr>()) {109    if (Other->getSwiftType() != BT)110      Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;111    return;112  }113 114  D->addAttr(::new (getASTContext()) SwiftBridgeAttr(getASTContext(), AL, BT));115}116 117static bool isErrorParameter(Sema &S, QualType QT) {118  const auto *PT = QT->getAs<PointerType>();119  if (!PT)120    return false;121 122  QualType Pointee = PT->getPointeeType();123 124  // Check for NSError**.125  if (const auto *OPT = Pointee->getAs<ObjCObjectPointerType>())126    if (const auto *ID = OPT->getInterfaceDecl())127      if (ID->getIdentifier() == S.ObjC().getNSErrorIdent())128        return true;129 130  // Check for CFError**.131  if (const auto *PT = Pointee->getAs<PointerType>())132    if (auto *RD = PT->getPointeeType()->getAsRecordDecl();133        RD && S.ObjC().isCFError(RD))134      return true;135 136  return false;137}138 139void SemaSwift::handleError(Decl *D, const ParsedAttr &AL) {140  auto hasErrorParameter = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {141    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); I != E; ++I) {142      if (isErrorParameter(S, getFunctionOrMethodParamType(D, I)))143        return true;144    }145 146    S.Diag(AL.getLoc(), diag::err_attr_swift_error_no_error_parameter)147        << AL << isa<ObjCMethodDecl>(D);148    return false;149  };150 151  auto hasPointerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {152    // - C, ObjC, and block pointers are definitely okay.153    // - References are definitely not okay.154    // - nullptr_t is weird, but acceptable.155    QualType RT = getFunctionOrMethodResultType(D);156    if (RT->hasPointerRepresentation() && !RT->isReferenceType())157      return true;158 159    S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)160        << AL << AL.getArgAsIdent(0)->getIdentifierInfo()->getName()161        << isa<ObjCMethodDecl>(D) << /*pointer*/ 1;162    return false;163  };164 165  auto hasIntegerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {166    QualType RT = getFunctionOrMethodResultType(D);167    if (RT->isIntegralType(S.Context))168      return true;169 170    S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)171        << AL << AL.getArgAsIdent(0)->getIdentifierInfo()->getName()172        << isa<ObjCMethodDecl>(D) << /*integral*/ 0;173    return false;174  };175 176  if (D->isInvalidDecl())177    return;178 179  IdentifierLoc *Loc = AL.getArgAsIdent(0);180  SwiftErrorAttr::ConventionKind Convention;181  if (!SwiftErrorAttr::ConvertStrToConventionKind(182          Loc->getIdentifierInfo()->getName(), Convention)) {183    Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)184        << AL << Loc->getIdentifierInfo();185    return;186  }187 188  switch (Convention) {189  case SwiftErrorAttr::None:190    // No additional validation required.191    break;192 193  case SwiftErrorAttr::NonNullError:194    if (!hasErrorParameter(SemaRef, D, AL))195      return;196    break;197 198  case SwiftErrorAttr::NullResult:199    if (!hasErrorParameter(SemaRef, D, AL) || !hasPointerResult(SemaRef, D, AL))200      return;201    break;202 203  case SwiftErrorAttr::NonZeroResult:204  case SwiftErrorAttr::ZeroResult:205    if (!hasErrorParameter(SemaRef, D, AL) || !hasIntegerResult(SemaRef, D, AL))206      return;207    break;208  }209 210  D->addAttr(::new (getASTContext())211                 SwiftErrorAttr(getASTContext(), AL, Convention));212}213 214static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D,215                                      const SwiftAsyncErrorAttr *ErrorAttr,216                                      const SwiftAsyncAttr *AsyncAttr) {217  if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {218    if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {219      S.Diag(AsyncAttr->getLocation(),220             diag::err_swift_async_error_without_swift_async)221          << AsyncAttr << isa<ObjCMethodDecl>(D);222    }223    return;224  }225 226  const ParmVarDecl *HandlerParam = getFunctionOrMethodParam(227      D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());228  // handleSwiftAsyncAttr already verified the type is correct, so no need to229  // double-check it here.230  const auto *FuncTy = HandlerParam->getType()231                           ->castAs<BlockPointerType>()232                           ->getPointeeType()233                           ->getAs<FunctionProtoType>();234  ArrayRef<QualType> BlockParams;235  if (FuncTy)236    BlockParams = FuncTy->getParamTypes();237 238  switch (ErrorAttr->getConvention()) {239  case SwiftAsyncErrorAttr::ZeroArgument:240  case SwiftAsyncErrorAttr::NonZeroArgument: {241    uint32_t ParamIdx = ErrorAttr->getHandlerParamIdx();242    if (ParamIdx == 0 || ParamIdx > BlockParams.size()) {243      S.Diag(ErrorAttr->getLocation(),244             diag::err_attribute_argument_out_of_bounds)245          << ErrorAttr << 2;246      return;247    }248    QualType ErrorParam = BlockParams[ParamIdx - 1];249    if (!ErrorParam->isIntegralType(S.Context)) {250      StringRef ConvStr =251          ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument252              ? "zero_argument"253              : "nonzero_argument";254      S.Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)255          << ErrorAttr << ConvStr << ParamIdx << ErrorParam;256      return;257    }258    break;259  }260  case SwiftAsyncErrorAttr::NonNullError: {261    bool AnyErrorParams = false;262    for (QualType Param : BlockParams) {263      // Check for NSError *.264      if (const auto *ObjCPtrTy = Param->getAs<ObjCObjectPointerType>()) {265        if (const auto *ID = ObjCPtrTy->getInterfaceDecl()) {266          if (ID->getIdentifier() == S.ObjC().getNSErrorIdent()) {267            AnyErrorParams = true;268            break;269          }270        }271      }272      // Check for CFError *.273      if (const auto *PtrTy = Param->getAs<PointerType>()) {274        if (auto *RD = PtrTy->getPointeeType()->getAsRecordDecl();275            RD && S.ObjC().isCFError(RD)) {276          AnyErrorParams = true;277          break;278        }279      }280    }281 282    if (!AnyErrorParams) {283      S.Diag(ErrorAttr->getLocation(),284             diag::err_swift_async_error_no_error_parameter)285          << ErrorAttr << isa<ObjCMethodDecl>(D);286      return;287    }288    break;289  }290  case SwiftAsyncErrorAttr::None:291    break;292  }293}294 295void SemaSwift::handleAsyncError(Decl *D, const ParsedAttr &AL) {296  IdentifierLoc *IDLoc = AL.getArgAsIdent(0);297  SwiftAsyncErrorAttr::ConventionKind ConvKind;298  if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(299          IDLoc->getIdentifierInfo()->getName(), ConvKind)) {300    Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)301        << AL << IDLoc->getIdentifierInfo();302    return;303  }304 305  uint32_t ParamIdx = 0;306  switch (ConvKind) {307  case SwiftAsyncErrorAttr::ZeroArgument:308  case SwiftAsyncErrorAttr::NonZeroArgument: {309    if (!AL.checkExactlyNumArgs(SemaRef, 2))310      return;311 312    Expr *IdxExpr = AL.getArgAsExpr(1);313    if (!SemaRef.checkUInt32Argument(AL, IdxExpr, ParamIdx))314      return;315    break;316  }317  case SwiftAsyncErrorAttr::NonNullError:318  case SwiftAsyncErrorAttr::None: {319    if (!AL.checkExactlyNumArgs(SemaRef, 1))320      return;321    break;322  }323  }324 325  auto *ErrorAttr = ::new (getASTContext())326      SwiftAsyncErrorAttr(getASTContext(), AL, ConvKind, ParamIdx);327  D->addAttr(ErrorAttr);328 329  if (auto *AsyncAttr = D->getAttr<SwiftAsyncAttr>())330    checkSwiftAsyncErrorBlock(SemaRef, D, ErrorAttr, AsyncAttr);331}332 333// For a function, this will validate a compound Swift name, e.g.334// <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, and335// the function will output the number of parameter names, and whether this is a336// single-arg initializer.337//338// For a type, enum constant, property, or variable declaration, this will339// validate either a simple identifier, or a qualified340// <code>context.identifier</code> name.341static bool validateSwiftFunctionName(Sema &S, const ParsedAttr &AL,342                                      SourceLocation Loc, StringRef Name,343                                      unsigned &SwiftParamCount,344                                      bool &IsSingleParamInit) {345  SwiftParamCount = 0;346  IsSingleParamInit = false;347 348  // Check whether this will be mapped to a getter or setter of a property.349  bool IsGetter = false, IsSetter = false;350  if (Name.consume_front("getter:"))351    IsGetter = true;352  else if (Name.consume_front("setter:"))353    IsSetter = true;354 355  if (Name.empty() || Name.back() != ')') {356    S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;357    return false;358  }359 360  bool IsMember = false;361  StringRef ContextName, BaseName, Parameters;362 363  std::tie(BaseName, Parameters) = Name.split('(');364 365  // Split at the first '.', if it exists, which separates the context name366  // from the base name.367  std::tie(ContextName, BaseName) = BaseName.rsplit('.');368  if (BaseName.empty()) {369    BaseName = ContextName;370    ContextName = StringRef();371  } else if (ContextName.empty() || !isValidSwiftContextName(ContextName)) {372    S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)373        << AL << /*context*/ 1;374    return false;375  } else {376    IsMember = true;377  }378 379  if (!isValidAsciiIdentifier(BaseName) || BaseName == "_") {380    S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)381        << AL << /*basename*/ 0;382    return false;383  }384 385  bool IsSubscript = BaseName == "subscript";386  // A subscript accessor must be a getter or setter.387  if (IsSubscript && !IsGetter && !IsSetter) {388    S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)389        << AL << /* getter or setter */ 0;390    return false;391  }392 393  if (Parameters.empty()) {394    S.Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;395    return false;396  }397 398  assert(Parameters.back() == ')' && "expected ')'");399  Parameters = Parameters.drop_back(); // ')'400 401  if (Parameters.empty()) {402    // Setters and subscripts must have at least one parameter.403    if (IsSubscript) {404      S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)405          << AL << /* have at least one parameter */ 1;406      return false;407    }408 409    if (IsSetter) {410      S.Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;411      return false;412    }413 414    return true;415  }416 417  if (Parameters.back() != ':') {418    S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;419    return false;420  }421 422  StringRef CurrentParam;423  std::optional<unsigned> SelfLocation;424  unsigned NewValueCount = 0;425  std::optional<unsigned> NewValueLocation;426  do {427    std::tie(CurrentParam, Parameters) = Parameters.split(':');428 429    if (!isValidAsciiIdentifier(CurrentParam)) {430      S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)431          << AL << /*parameter*/ 2;432      return false;433    }434 435    if (IsMember && CurrentParam == "self") {436      // "self" indicates the "self" argument for a member.437 438      // More than one "self"?439      if (SelfLocation) {440        S.Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;441        return false;442      }443 444      // The "self" location is the current parameter.445      SelfLocation = SwiftParamCount;446    } else if (CurrentParam == "newValue") {447      // "newValue" indicates the "newValue" argument for a setter.448 449      // There should only be one 'newValue', but it's only significant for450      // subscript accessors, so don't error right away.451      ++NewValueCount;452 453      NewValueLocation = SwiftParamCount;454    }455 456    ++SwiftParamCount;457  } while (!Parameters.empty());458 459  // Only instance subscripts are currently supported.460  if (IsSubscript && !SelfLocation) {461    S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)462        << AL << /*have a 'self:' parameter*/ 2;463    return false;464  }465 466  IsSingleParamInit =467      SwiftParamCount == 1 && BaseName == "init" && CurrentParam != "_";468 469  // Check the number of parameters for a getter/setter.470  if (IsGetter || IsSetter) {471    // Setters have one parameter for the new value.472    unsigned NumExpectedParams = IsGetter ? 0 : 1;473    unsigned ParamDiag = IsGetter474                             ? diag::warn_attr_swift_name_getter_parameters475                             : diag::warn_attr_swift_name_setter_parameters;476 477    // Instance methods have one parameter for "self".478    if (SelfLocation)479      ++NumExpectedParams;480 481    // Subscripts may have additional parameters beyond the expected params for482    // the index.483    if (IsSubscript) {484      if (SwiftParamCount < NumExpectedParams) {485        S.Diag(Loc, ParamDiag) << AL;486        return false;487      }488 489      // A subscript setter must explicitly label its newValue parameter to490      // distinguish it from index parameters.491      if (IsSetter) {492        if (!NewValueLocation) {493          S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)494              << AL;495          return false;496        }497        if (NewValueCount > 1) {498          S.Diag(Loc,499                 diag::warn_attr_swift_name_subscript_setter_multiple_newValues)500              << AL;501          return false;502        }503      } else {504        // Subscript getters should have no 'newValue:' parameter.505        if (NewValueLocation) {506          S.Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)507              << AL;508          return false;509        }510      }511    } else {512      // Property accessors must have exactly the number of expected params.513      if (SwiftParamCount != NumExpectedParams) {514        S.Diag(Loc, ParamDiag) << AL;515        return false;516      }517    }518  }519 520  return true;521}522 523bool SemaSwift::DiagnoseName(Decl *D, StringRef Name, SourceLocation Loc,524                             const ParsedAttr &AL, bool IsAsync) {525  if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {526    ArrayRef<ParmVarDecl *> Params;527    unsigned ParamCount;528 529    if (const auto *Method = dyn_cast<ObjCMethodDecl>(D)) {530      ParamCount = Method->getSelector().getNumArgs();531      Params = Method->parameters().slice(0, ParamCount);532    } else {533      const auto *F = cast<FunctionDecl>(D);534 535      ParamCount = F->getNumParams();536      Params = F->parameters();537 538      if (!F->hasWrittenPrototype()) {539        Diag(Loc, diag::warn_attribute_wrong_decl_type)540            << AL << AL.isRegularKeywordAttribute()541            << ExpectedFunctionWithProtoType;542        return false;543      }544    }545 546    // The async name drops the last callback parameter.547    if (IsAsync) {548      if (ParamCount == 0) {549        Diag(Loc, diag::warn_attr_swift_name_decl_missing_params)550            << AL << isa<ObjCMethodDecl>(D);551        return false;552      }553      ParamCount -= 1;554    }555 556    unsigned SwiftParamCount;557    bool IsSingleParamInit;558    if (!validateSwiftFunctionName(SemaRef, AL, Loc, Name, SwiftParamCount,559                                   IsSingleParamInit))560      return false;561 562    bool ParamCountValid;563    if (SwiftParamCount == ParamCount) {564      ParamCountValid = true;565    } else if (SwiftParamCount > ParamCount) {566      ParamCountValid = IsSingleParamInit && ParamCount == 0;567    } else {568      // We have fewer Swift parameters than Objective-C parameters, but that569      // might be because we've transformed some of them. Check for potential570      // "out" parameters and err on the side of not warning.571      unsigned MaybeOutParamCount =572          llvm::count_if(Params, [](const ParmVarDecl *Param) -> bool {573            QualType ParamTy = Param->getType();574            if (ParamTy->isReferenceType() || ParamTy->isPointerType())575              return !ParamTy->getPointeeType().isConstQualified();576            return false;577          });578 579      ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;580    }581 582    if (!ParamCountValid) {583      Diag(Loc, diag::warn_attr_swift_name_num_params)584          << (SwiftParamCount > ParamCount) << AL << ParamCount585          << SwiftParamCount;586      return false;587    }588  } else if ((isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||589              isa<ObjCInterfaceDecl>(D) || isa<ObjCPropertyDecl>(D) ||590              isa<VarDecl>(D) || isa<TypedefNameDecl>(D) || isa<TagDecl>(D) ||591              isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) &&592             !IsAsync) {593    StringRef ContextName, BaseName;594 595    std::tie(ContextName, BaseName) = Name.rsplit('.');596    if (BaseName.empty()) {597      BaseName = ContextName;598      ContextName = StringRef();599    } else if (!isValidSwiftContextName(ContextName)) {600      Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)601          << AL << /*context*/ 1;602      return false;603    }604 605    if (!isValidAsciiIdentifier(BaseName)) {606      Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)607          << AL << /*basename*/ 0;608      return false;609    }610  } else {611    Diag(Loc, diag::warn_attr_swift_name_decl_kind) << AL;612    return false;613  }614  return true;615}616 617void SemaSwift::handleName(Decl *D, const ParsedAttr &AL) {618  StringRef Name;619  SourceLocation Loc;620  if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))621    return;622 623  if (!DiagnoseName(D, Name, Loc, AL, /*IsAsync=*/false))624    return;625 626  D->addAttr(::new (getASTContext()) SwiftNameAttr(getASTContext(), AL, Name));627}628 629void SemaSwift::handleAsyncName(Decl *D, const ParsedAttr &AL) {630  StringRef Name;631  SourceLocation Loc;632  if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))633    return;634 635  if (!DiagnoseName(D, Name, Loc, AL, /*IsAsync=*/true))636    return;637 638  D->addAttr(::new (getASTContext())639                 SwiftAsyncNameAttr(getASTContext(), AL, Name));640}641 642void SemaSwift::handleNewType(Decl *D, const ParsedAttr &AL) {643  // Make sure that there is an identifier as the annotation's single argument.644  if (!AL.checkExactlyNumArgs(SemaRef, 1))645    return;646 647  if (!AL.isArgIdent(0)) {648    Diag(AL.getLoc(), diag::err_attribute_argument_type)649        << AL << AANT_ArgumentIdentifier;650    return;651  }652 653  SwiftNewTypeAttr::NewtypeKind Kind;654  IdentifierInfo *II = AL.getArgAsIdent(0)->getIdentifierInfo();655  if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->getName(), Kind)) {656    Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;657    return;658  }659 660  if (!isa<TypedefNameDecl>(D)) {661    Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)662        << AL << AL.isRegularKeywordAttribute() << ExpectedTypedef;663    return;664  }665 666  D->addAttr(::new (getASTContext())667                 SwiftNewTypeAttr(getASTContext(), AL, Kind));668}669 670void SemaSwift::handleAsyncAttr(Decl *D, const ParsedAttr &AL) {671  if (!AL.isArgIdent(0)) {672    Diag(AL.getLoc(), diag::err_attribute_argument_n_type)673        << AL << 1 << AANT_ArgumentIdentifier;674    return;675  }676 677  SwiftAsyncAttr::Kind Kind;678  IdentifierInfo *II = AL.getArgAsIdent(0)->getIdentifierInfo();679  if (!SwiftAsyncAttr::ConvertStrToKind(II->getName(), Kind)) {680    Diag(AL.getLoc(), diag::err_swift_async_no_access) << AL << II;681    return;682  }683 684  ParamIdx Idx;685  if (Kind == SwiftAsyncAttr::None) {686    // If this is 'none', then there shouldn't be any additional arguments.687    if (!AL.checkExactlyNumArgs(SemaRef, 1))688      return;689  } else {690    // Non-none swift_async requires a completion handler index argument.691    if (!AL.checkExactlyNumArgs(SemaRef, 2))692      return;693 694    Expr *HandlerIdx = AL.getArgAsExpr(1);695    if (!SemaRef.checkFunctionOrMethodParameterIndex(D, AL, 2, HandlerIdx, Idx))696      return;697 698    const ParmVarDecl *CompletionBlock =699        getFunctionOrMethodParam(D, Idx.getASTIndex());700    QualType CompletionBlockType = CompletionBlock->getType();701    if (!CompletionBlockType->isBlockPointerType()) {702      Diag(CompletionBlock->getLocation(), diag::err_swift_async_bad_block_type)703          << CompletionBlock->getType();704      return;705    }706    QualType BlockTy =707        CompletionBlockType->castAs<BlockPointerType>()->getPointeeType();708    if (!BlockTy->castAs<FunctionType>()->getReturnType()->isVoidType()) {709      Diag(CompletionBlock->getLocation(), diag::err_swift_async_bad_block_type)710          << CompletionBlock->getType();711      return;712    }713  }714 715  auto *AsyncAttr =716      ::new (getASTContext()) SwiftAsyncAttr(getASTContext(), AL, Kind, Idx);717  D->addAttr(AsyncAttr);718 719  if (auto *ErrorAttr = D->getAttr<SwiftAsyncErrorAttr>())720    checkSwiftAsyncErrorBlock(SemaRef, D, ErrorAttr, AsyncAttr);721}722 723void SemaSwift::AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,724                                    ParameterABI abi) {725  ASTContext &Context = getASTContext();726  QualType type = cast<ParmVarDecl>(D)->getType();727 728  if (auto existingAttr = D->getAttr<ParameterABIAttr>()) {729    if (existingAttr->getABI() != abi) {730      Diag(CI.getLoc(), diag::err_attributes_are_not_compatible)731          << getParameterABISpelling(abi) << existingAttr732          << (CI.isRegularKeywordAttribute() ||733              existingAttr->isRegularKeywordAttribute());734      Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);735      return;736    }737  }738 739  switch (abi) {740  case ParameterABI::HLSLOut:741  case ParameterABI::HLSLInOut:742    llvm_unreachable("explicit attribute for non-swift parameter ABI?");743  case ParameterABI::Ordinary:744    llvm_unreachable("explicit attribute for ordinary parameter ABI?");745 746  case ParameterABI::SwiftContext:747    if (!isValidSwiftContextType(type)) {748      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)749          << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;750    }751    D->addAttr(::new (Context) SwiftContextAttr(Context, CI));752    return;753 754  case ParameterABI::SwiftAsyncContext:755    if (!isValidSwiftContextType(type)) {756      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)757          << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;758    }759    D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));760    return;761 762  case ParameterABI::SwiftErrorResult:763    if (!isValidSwiftErrorResultType(type)) {764      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)765          << getParameterABISpelling(abi) << /*pointer to pointer */ 1 << type;766    }767    D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));768    return;769 770  case ParameterABI::SwiftIndirectResult:771    if (!isValidSwiftIndirectResultType(type)) {772      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)773          << getParameterABISpelling(abi) << /*pointer*/ 0 << type;774    }775    D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));776    return;777  }778  llvm_unreachable("bad parameter ABI attribute");779}780 781} // namespace clang782