1 //===------ SemaSwift.cpp ------ Swift language-specific routines ---------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis functions specific to Swift.
11 //===----------------------------------------------------------------------===//
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"
24 SemaSwift::SemaSwift(Sema
&S
) : SemaBase(S
) {}
26 SwiftNameAttr
*SemaSwift::mergeNameAttr(Decl
*D
, const SwiftNameAttr
&SNA
,
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
)
32 << (PrevSNA
->isRegularKeywordAttribute() ||
33 SNA
.isRegularKeywordAttribute());
34 Diag(SNA
.getLoc(), diag::note_conflicting_attribute
);
37 D
->dropAttr
<SwiftNameAttr
>();
39 return ::new (getASTContext()) SwiftNameAttr(getASTContext(), SNA
, Name
);
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
;
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();
56 return Ty
->isDependentType();
58 return Ty
.getAddressSpace() == LangAS::Default
;
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();
68 return Ty
->isDependentType();
70 if (!Ty
.getQualifiers().empty())
72 return isValidSwiftContextType(Ty
);
75 void SemaSwift::handleAttrAttr(Decl
*D
, const ParsedAttr
&AL
) {
76 if (AL
.isInvalid() || AL
.isUsedAsTypeAttr())
79 // Make sure that there is a string literal as the annotation's single
82 if (!SemaRef
.checkStringLiteralArgumentAttr(AL
, 0, Str
)) {
87 D
->addAttr(::new (getASTContext()) SwiftAttrAttr(getASTContext(), AL
, Str
));
90 void SemaSwift::handleBridge(Decl
*D
, const ParsedAttr
&AL
) {
91 // Make sure that there is a string literal as the annotation's single
94 if (!SemaRef
.checkStringLiteralArgumentAttr(AL
, 0, BT
))
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
;
105 D
->addAttr(::new (getASTContext()) SwiftBridgeAttr(getASTContext(), AL
, BT
));
108 static bool isErrorParameter(Sema
&S
, QualType QT
) {
109 const auto *PT
= QT
->getAs
<PointerType
>();
113 QualType Pointee
= PT
->getPointeeType();
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())
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()))
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
)))
137 S
.Diag(AL
.getLoc(), diag::err_attr_swift_error_no_error_parameter
)
138 << AL
<< isa
<ObjCMethodDecl
>(D
);
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())
150 S
.Diag(AL
.getLoc(), diag::err_attr_swift_error_return_type
)
151 << AL
<< AL
.getArgAsIdent(0)->Ident
->getName() << isa
<ObjCMethodDecl
>(D
)
156 auto hasIntegerResult
= [](Sema
&S
, Decl
*D
, const ParsedAttr
&AL
) -> bool {
157 QualType RT
= getFunctionOrMethodResultType(D
);
158 if (RT
->isIntegralType(S
.Context
))
161 S
.Diag(AL
.getLoc(), diag::err_attr_swift_error_return_type
)
162 << AL
<< AL
.getArgAsIdent(0)->Ident
->getName() << isa
<ObjCMethodDecl
>(D
)
167 if (D
->isInvalidDecl())
170 IdentifierLoc
*Loc
= AL
.getArgAsIdent(0);
171 SwiftErrorAttr::ConventionKind Convention
;
172 if (!SwiftErrorAttr::ConvertStrToConventionKind(Loc
->Ident
->getName(),
174 Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
179 switch (Convention
) {
180 case SwiftErrorAttr::None
:
181 // No additional validation required.
184 case SwiftErrorAttr::NonNullError
:
185 if (!hasErrorParameter(SemaRef
, D
, AL
))
189 case SwiftErrorAttr::NullResult
:
190 if (!hasErrorParameter(SemaRef
, D
, AL
) || !hasPointerResult(SemaRef
, D
, AL
))
194 case SwiftErrorAttr::NonZeroResult
:
195 case SwiftErrorAttr::ZeroResult
:
196 if (!hasErrorParameter(SemaRef
, D
, AL
) || !hasIntegerResult(SemaRef
, D
, AL
))
201 D
->addAttr(::new (getASTContext())
202 SwiftErrorAttr(getASTContext(), AL
, Convention
));
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
);
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
>()
224 ->getAs
<FunctionProtoType
>();
225 ArrayRef
<QualType
> BlockParams
;
227 BlockParams
= FuncTy
->getParamTypes();
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
)
239 QualType ErrorParam
= BlockParams
[ParamIdx
- 1];
240 if (!ErrorParam
->isIntegralType(S
.Context
)) {
242 ErrorAttr
->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
244 : "nonzero_argument";
245 S
.Diag(ErrorAttr
->getLocation(), diag::err_swift_async_error_non_integral
)
246 << ErrorAttr
<< ConvStr
<< ParamIdx
<< ErrorParam
;
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;
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;
274 if (!AnyErrorParams
) {
275 S
.Diag(ErrorAttr
->getLocation(),
276 diag::err_swift_async_error_no_error_parameter
)
277 << ErrorAttr
<< isa
<ObjCMethodDecl
>(D
);
282 case SwiftAsyncErrorAttr::None
:
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(),
292 Diag(AL
.getLoc(), diag::warn_attribute_type_not_supported
)
293 << AL
<< IDLoc
->Ident
;
297 uint32_t ParamIdx
= 0;
299 case SwiftAsyncErrorAttr::ZeroArgument
:
300 case SwiftAsyncErrorAttr::NonZeroArgument
: {
301 if (!AL
.checkExactlyNumArgs(SemaRef
, 2))
304 Expr
*IdxExpr
= AL
.getArgAsExpr(1);
305 if (!SemaRef
.checkUInt32Argument(AL
, IdxExpr
, ParamIdx
))
309 case SwiftAsyncErrorAttr::NonNullError
:
310 case SwiftAsyncErrorAttr::None
: {
311 if (!AL
.checkExactlyNumArgs(SemaRef
, 1))
317 auto *ErrorAttr
= ::new (getASTContext())
318 SwiftAsyncErrorAttr(getASTContext(), AL
, ConvKind
, ParamIdx
);
319 D
->addAttr(ErrorAttr
);
321 if (auto *AsyncAttr
= D
->getAttr
<SwiftAsyncAttr
>())
322 checkSwiftAsyncErrorBlock(SemaRef
, D
, ErrorAttr
, AsyncAttr
);
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.
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
) {
338 IsSingleParamInit
= false;
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:"))
344 else if (Name
.consume_front("setter:"))
347 if (Name
.back() != ')') {
348 S
.Diag(Loc
, diag::warn_attr_swift_name_function
) << AL
;
352 bool IsMember
= false;
353 StringRef ContextName
, BaseName
, Parameters
;
355 std::tie(BaseName
, Parameters
) = Name
.split('(');
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;
371 if (!isValidAsciiIdentifier(BaseName
) || BaseName
== "_") {
372 S
.Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
)
373 << AL
<< /*basename*/ 0;
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;
385 if (Parameters
.empty()) {
386 S
.Diag(Loc
, diag::warn_attr_swift_name_missing_parameters
) << AL
;
390 assert(Parameters
.back() == ')' && "expected ')'");
391 Parameters
= Parameters
.drop_back(); // ')'
393 if (Parameters
.empty()) {
394 // Setters and subscripts must have at least one parameter.
396 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_invalid_parameter
)
397 << AL
<< /* have at least one parameter */ 1;
402 S
.Diag(Loc
, diag::warn_attr_swift_name_setter_parameters
) << AL
;
409 if (Parameters
.back() != ':') {
410 S
.Diag(Loc
, diag::warn_attr_swift_name_function
) << AL
;
414 StringRef CurrentParam
;
415 std::optional
<unsigned> SelfLocation
;
416 unsigned NewValueCount
= 0;
417 std::optional
<unsigned> NewValueLocation
;
419 std::tie(CurrentParam
, Parameters
) = Parameters
.split(':');
421 if (!isValidAsciiIdentifier(CurrentParam
)) {
422 S
.Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
)
423 << AL
<< /*parameter*/ 2;
427 if (IsMember
&& CurrentParam
== "self") {
428 // "self" indicates the "self" argument for a member.
430 // More than one "self"?
432 S
.Diag(Loc
, diag::warn_attr_swift_name_multiple_selfs
) << AL
;
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.
441 // There should only be one 'newValue', but it's only significant for
442 // subscript accessors, so don't error right away.
445 NewValueLocation
= SwiftParamCount
;
449 } while (!Parameters
.empty());
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;
459 SwiftParamCount
== 1 && BaseName
== "init" && CurrentParam
!= "_";
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
;
469 // Instance methods have one parameter for "self".
473 // Subscripts may have additional parameters beyond the expected params for
476 if (SwiftParamCount
< NumExpectedParams
) {
477 S
.Diag(Loc
, ParamDiag
) << AL
;
481 // A subscript setter must explicitly label its newValue parameter to
482 // distinguish it from index parameters.
484 if (!NewValueLocation
) {
485 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_setter_no_newValue
)
489 if (NewValueCount
> 1) {
491 diag::warn_attr_swift_name_subscript_setter_multiple_newValues
)
496 // Subscript getters should have no 'newValue:' parameter.
497 if (NewValueLocation
) {
498 S
.Diag(Loc
, diag::warn_attr_swift_name_subscript_getter_newValue
)
504 // Property accessors must have exactly the number of expected params.
505 if (SwiftParamCount
!= NumExpectedParams
) {
506 S
.Diag(Loc
, ParamDiag
) << AL
;
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
;
521 if (const auto *Method
= dyn_cast
<ObjCMethodDecl
>(D
)) {
522 ParamCount
= Method
->getSelector().getNumArgs();
523 Params
= Method
->parameters().slice(0, ParamCount
);
525 const auto *F
= cast
<FunctionDecl
>(D
);
527 ParamCount
= F
->getNumParams();
528 Params
= F
->parameters();
530 if (!F
->hasWrittenPrototype()) {
531 Diag(Loc
, diag::warn_attribute_wrong_decl_type
)
532 << AL
<< AL
.isRegularKeywordAttribute()
533 << ExpectedFunctionWithProtoType
;
538 // The async name drops the last callback parameter.
540 if (ParamCount
== 0) {
541 Diag(Loc
, diag::warn_attr_swift_name_decl_missing_params
)
542 << AL
<< isa
<ObjCMethodDecl
>(D
);
548 unsigned SwiftParamCount
;
549 bool IsSingleParamInit
;
550 if (!validateSwiftFunctionName(SemaRef
, AL
, Loc
, Name
, SwiftParamCount
,
554 bool ParamCountValid
;
555 if (SwiftParamCount
== ParamCount
) {
556 ParamCountValid
= true;
557 } else if (SwiftParamCount
> ParamCount
) {
558 ParamCountValid
= IsSingleParamInit
&& ParamCount
== 0;
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();
571 ParamCountValid
= SwiftParamCount
+ MaybeOutParamCount
>= ParamCount
;
574 if (!ParamCountValid
) {
575 Diag(Loc
, diag::warn_attr_swift_name_num_params
)
576 << (SwiftParamCount
> ParamCount
) << AL
<< ParamCount
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
)) &&
585 StringRef ContextName
, BaseName
;
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;
597 if (!isValidAsciiIdentifier(BaseName
)) {
598 Diag(Loc
, diag::warn_attr_swift_name_invalid_identifier
)
599 << AL
<< /*basename*/ 0;
603 Diag(Loc
, diag::warn_attr_swift_name_decl_kind
) << AL
;
609 void SemaSwift::handleName(Decl
*D
, const ParsedAttr
&AL
) {
612 if (!SemaRef
.checkStringLiteralArgumentAttr(AL
, 0, Name
, &Loc
))
615 if (!DiagnoseName(D
, Name
, Loc
, AL
, /*IsAsync=*/false))
618 D
->addAttr(::new (getASTContext()) SwiftNameAttr(getASTContext(), AL
, Name
));
621 void SemaSwift::handleAsyncName(Decl
*D
, const ParsedAttr
&AL
) {
624 if (!SemaRef
.checkStringLiteralArgumentAttr(AL
, 0, Name
, &Loc
))
627 if (!DiagnoseName(D
, Name
, Loc
, AL
, /*IsAsync=*/true))
630 D
->addAttr(::new (getASTContext())
631 SwiftAsyncNameAttr(getASTContext(), AL
, Name
));
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))
639 if (!AL
.isArgIdent(0)) {
640 Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
641 << AL
<< AANT_ArgumentIdentifier
;
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
;
652 if (!isa
<TypedefNameDecl
>(D
)) {
653 Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type_str
)
654 << AL
<< AL
.isRegularKeywordAttribute() << "typedefs";
658 D
->addAttr(::new (getASTContext())
659 SwiftNewTypeAttr(getASTContext(), AL
, Kind
));
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
;
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
;
677 if (Kind
== SwiftAsyncAttr::None
) {
678 // If this is 'none', then there shouldn't be any additional arguments.
679 if (!AL
.checkExactlyNumArgs(SemaRef
, 1))
682 // Non-none swift_async requires a completion handler index argument.
683 if (!AL
.checkExactlyNumArgs(SemaRef
, 2))
686 Expr
*HandlerIdx
= AL
.getArgAsExpr(1);
687 if (!SemaRef
.checkFunctionOrMethodParameterIndex(D
, AL
, 2, HandlerIdx
, Idx
))
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();
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();
708 ::new (getASTContext()) SwiftAsyncAttr(getASTContext(), AL
, Kind
, Idx
);
709 D
->addAttr(AsyncAttr
);
711 if (auto *ErrorAttr
= D
->getAttr
<SwiftAsyncErrorAttr
>())
712 checkSwiftAsyncErrorBlock(SemaRef
, D
, ErrorAttr
, AsyncAttr
);
715 void SemaSwift::AddParameterABIAttr(Decl
*D
, const AttributeCommonInfo
&CI
,
717 ASTContext
&Context
= getASTContext();
718 QualType type
= cast
<ParmVarDecl
>(D
)->getType();
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
);
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?");
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
;
743 D
->addAttr(::new (Context
) SwiftContextAttr(Context
, CI
));
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
;
751 D
->addAttr(::new (Context
) SwiftAsyncContextAttr(Context
, CI
));
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
;
759 D
->addAttr(::new (Context
) SwiftErrorResultAttr(Context
, CI
));
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
;
767 D
->addAttr(::new (Context
) SwiftIndirectResultAttr(Context
, CI
));
770 llvm_unreachable("bad parameter ABI attribute");