xref: /llvm-project/clang/lib/Sema/SemaSwift.cpp (revision 41a94de75caacb979070ec7a010dfe3c4e9f116f)
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