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