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