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