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