xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaSwift.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 {
SemaSwift(Sema & S)24 SemaSwift::SemaSwift(Sema &S) : SemaBase(S) {}
25 
mergeNameAttr(Decl * D,const SwiftNameAttr & SNA,StringRef Name)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.
isValidSwiftContextType(QualType Ty)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.
isValidSwiftIndirectResultType(QualType Ty)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.
isValidSwiftErrorResultType(QualType Ty)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 
handleAttrAttr(Decl * D,const ParsedAttr & AL)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 
handleBridge(Decl * D,const ParsedAttr & AL)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 
isErrorParameter(Sema & S,QualType QT)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 
handleError(Decl * D,const ParsedAttr & AL)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 
checkSwiftAsyncErrorBlock(Sema & S,Decl * D,const SwiftAsyncErrorAttr * ErrorAttr,const SwiftAsyncAttr * AsyncAttr)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 
handleAsyncError(Decl * D,const ParsedAttr & AL)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.
validateSwiftFunctionName(Sema & S,const ParsedAttr & AL,SourceLocation Loc,StringRef Name,unsigned & SwiftParamCount,bool & IsSingleParamInit)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 
DiagnoseName(Decl * D,StringRef Name,SourceLocation Loc,const ParsedAttr & AL,bool IsAsync)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 
handleName(Decl * D,const ParsedAttr & AL)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 
handleAsyncName(Decl * D,const ParsedAttr & AL)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 
handleNewType(Decl * D,const ParsedAttr & AL)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 
handleAsyncAttr(Decl * D,const ParsedAttr & AL)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 
AddParameterABIAttr(Decl * D,const AttributeCommonInfo & CI,ParameterABI abi)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