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);
46 if (A->getAttribute() == SAA.getAttribute())
86 if (c ==
'`' || c ==
'\\')
89 unsigned char uc =
static_cast<unsigned char>(c);
91 if (uc < 0x20 || uc >= 0x7F)
101 bool allSpace =
true;
102 for (
char c :
string) {
114 bool inBackticks =
false;
115 for (
size_t i = 0; i < text.size(); ++i) {
118 inBackticks = !inBackticks;
119 }
else if (c == separator && !inBackticks) {
120 return {text.substr(0, i), text.substr(i + 1)};
123 return {text, StringRef()};
128 bool inBackticks =
false;
129 for (
size_t i = text.size(); i > 0; --i) {
130 char c = text[i - 1];
132 inBackticks = !inBackticks;
133 }
else if (c == separator && !inBackticks) {
134 return {text.substr(0, i - 1), text.substr(i)};
137 return {text, StringRef()};
143 if (text.size() > 2 && text.front() ==
'`' && text.back() ==
'`')
150 StringRef
First, Rest = ContextName;
155 }
while (!Rest.empty());
166 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str)) {
178 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, BT))
183 if (
const auto *
Other = D->
getAttr<SwiftBridgeAttr>()) {
184 if (
Other->getSwiftType() != BT)
185 Diag(AL.
getLoc(), diag::warn_duplicate_attribute) << AL;
201 if (
const auto *ID = OPT->getInterfaceDecl())
207 if (
auto *RD = PT->getPointeeType()->getAsRecordDecl();
221 S.
Diag(AL.
getLoc(), diag::err_attr_swift_error_no_error_parameter)
222 << AL << isa<ObjCMethodDecl>(D);
234 S.
Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
245 S.
Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
255 SwiftErrorAttr::ConventionKind Convention;
256 if (!SwiftErrorAttr::ConvertStrToConventionKind(
258 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
263 switch (Convention) {
264 case SwiftErrorAttr::None:
268 case SwiftErrorAttr::NonNullError:
269 if (!hasErrorParameter(
SemaRef, D, AL))
273 case SwiftErrorAttr::NullResult:
274 if (!hasErrorParameter(
SemaRef, D, AL) || !hasPointerResult(
SemaRef, D, AL))
278 case SwiftErrorAttr::NonZeroResult:
279 case SwiftErrorAttr::ZeroResult:
280 if (!hasErrorParameter(
SemaRef, D, AL) || !hasIntegerResult(
SemaRef, D, AL))
290 const SwiftAsyncErrorAttr *ErrorAttr,
291 const SwiftAsyncAttr *AsyncAttr) {
292 if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {
293 if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {
294 S.
Diag(AsyncAttr->getLocation(),
295 diag::err_swift_async_error_without_swift_async)
296 << AsyncAttr << isa<ObjCMethodDecl>(D);
302 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
305 const auto *FuncTy = HandlerParam->
getType()
311 BlockParams = FuncTy->getParamTypes();
313 switch (ErrorAttr->getConvention()) {
314 case SwiftAsyncErrorAttr::ZeroArgument:
315 case SwiftAsyncErrorAttr::NonZeroArgument: {
318 S.
Diag(ErrorAttr->getLocation(),
319 diag::err_attribute_argument_out_of_bounds)
326 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
328 :
"nonzero_argument";
329 S.
Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
330 << ErrorAttr << ConvStr <<
ParamIdx << ErrorParam;
335 case SwiftAsyncErrorAttr::NonNullError: {
336 bool AnyErrorParams =
false;
337 for (
QualType Param : BlockParams) {
340 if (
const auto *ID = ObjCPtrTy->getInterfaceDecl()) {
342 AnyErrorParams =
true;
348 if (
const auto *PtrTy = Param->getAs<
PointerType>()) {
349 if (
auto *RD = PtrTy->getPointeeType()->getAsRecordDecl();
351 AnyErrorParams =
true;
357 if (!AnyErrorParams) {
358 S.
Diag(ErrorAttr->getLocation(),
359 diag::err_swift_async_error_no_error_parameter)
360 << ErrorAttr << isa<ObjCMethodDecl>(D);
365 case SwiftAsyncErrorAttr::None:
372 SwiftAsyncErrorAttr::ConventionKind ConvKind;
373 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(
375 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
382 case SwiftAsyncErrorAttr::ZeroArgument:
383 case SwiftAsyncErrorAttr::NonZeroArgument: {
392 case SwiftAsyncErrorAttr::NonNullError:
393 case SwiftAsyncErrorAttr::None: {
404 if (
auto *AsyncAttr = D->
getAttr<SwiftAsyncAttr>())
418 unsigned &SwiftParamCount,
419 bool &IsSingleParamInit) {
421 IsSingleParamInit =
false;
424 bool IsGetter =
false, IsSetter =
false;
425 if (Name.consume_front(
"getter:"))
427 else if (Name.consume_front(
"setter:"))
430 if (Name.empty() || Name.back() !=
')') {
431 S.
Diag(Loc, diag::warn_attr_swift_name_function) << AL;
435 bool IsMember =
false;
436 StringRef ContextName, BaseName, Parameters;
443 if (BaseName.empty()) {
444 BaseName = ContextName;
445 ContextName = StringRef();
447 S.
Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
455 S.
Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
460 bool IsSubscript = BaseName ==
"subscript";
462 if (IsSubscript && !IsGetter && !IsSetter) {
463 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
468 if (Parameters.empty()) {
469 S.
Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
473 assert(Parameters.back() ==
')' &&
"expected ')'");
474 Parameters = Parameters.drop_back();
476 if (Parameters.empty()) {
479 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
485 S.
Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
492 if (Parameters.back() !=
':') {
493 S.
Diag(Loc, diag::warn_attr_swift_name_function) << AL;
497 StringRef CurrentParam;
498 std::optional<unsigned> SelfLocation;
499 unsigned NewValueCount = 0;
500 std::optional<unsigned> NewValueLocation;
505 S.
Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
510 if (IsMember && CurrentParam ==
"self") {
515 S.
Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
520 SelfLocation = SwiftParamCount;
521 }
else if (CurrentParam ==
"newValue") {
528 NewValueLocation = SwiftParamCount;
532 }
while (!Parameters.empty());
535 if (IsSubscript && !SelfLocation) {
536 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
542 SwiftParamCount == 1 && BaseName ==
"init" && CurrentParam !=
"_";
545 if (IsGetter || IsSetter) {
547 unsigned NumExpectedParams = IsGetter ? 0 : 1;
548 unsigned ParamDiag = IsGetter
549 ? diag::warn_attr_swift_name_getter_parameters
550 : diag::warn_attr_swift_name_setter_parameters;
559 if (SwiftParamCount < NumExpectedParams) {
560 S.
Diag(Loc, ParamDiag) << AL;
567 if (!NewValueLocation) {
568 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
572 if (NewValueCount > 1) {
574 diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
580 if (NewValueLocation) {
581 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
588 if (SwiftParamCount != NumExpectedParams) {
589 S.
Diag(Loc, ParamDiag) << AL;
604 if (
const auto *
Method = dyn_cast<ObjCMethodDecl>(D)) {
605 ParamCount =
Method->getSelector().getNumArgs();
606 Params =
Method->parameters().slice(0, ParamCount);
610 ParamCount = F->getNumParams();
611 Params = F->parameters();
613 if (!F->hasWrittenPrototype()) {
614 Diag(Loc, diag::warn_attribute_wrong_decl_type)
623 if (ParamCount == 0) {
624 Diag(Loc, diag::warn_attr_swift_name_decl_missing_params)
625 << AL << isa<ObjCMethodDecl>(D);
631 unsigned SwiftParamCount;
632 bool IsSingleParamInit;
637 bool ParamCountValid;
638 if (SwiftParamCount == ParamCount) {
639 ParamCountValid =
true;
640 }
else if (SwiftParamCount > ParamCount) {
641 ParamCountValid = IsSingleParamInit && ParamCount == 0;
646 unsigned MaybeOutParamCount =
647 llvm::count_if(Params, [](
const ParmVarDecl *Param) ->
bool {
648 QualType ParamTy = Param->getType();
654 ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
657 if (!ParamCountValid) {
658 Diag(Loc, diag::warn_attr_swift_name_num_params)
659 << (SwiftParamCount > ParamCount) << AL << ParamCount
668 StringRef ContextName, BaseName;
671 if (BaseName.empty()) {
672 BaseName = ContextName;
673 ContextName = StringRef();
675 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
681 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
686 Diag(Loc, diag::warn_attr_swift_name_decl_kind) << AL;
695 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
707 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
723 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
728 SwiftNewTypeAttr::NewtypeKind Kind;
730 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->
getName(), Kind)) {
731 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
736 Diag(AL.
getLoc(), diag::warn_attribute_wrong_decl_type)
747 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
752 SwiftAsyncAttr::Kind Kind;
754 if (!SwiftAsyncAttr::ConvertStrToKind(II->
getName(), Kind)) {
755 Diag(AL.
getLoc(), diag::err_swift_async_no_access) << AL << II;
760 if (Kind == SwiftAsyncAttr::None) {
770 if (!
SemaRef.checkFunctionOrMethodParameterIndex(D, AL, 2, HandlerIdx, Idx))
777 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
784 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
794 if (
auto *ErrorAttr = D->
getAttr<SwiftAsyncErrorAttr>())
804 if (existingAttr->getABI() !=
abi) {
805 Diag(CI.
getLoc(), diag::err_attributes_are_not_compatible)
808 existingAttr->isRegularKeywordAttribute());
809 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
817 llvm_unreachable(
"explicit attribute for non-swift parameter ABI?");
819 llvm_unreachable(
"explicit attribute for ordinary parameter ABI?");
823 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
826 D->
addAttr(::new (Context) SwiftContextAttr(Context, CI));
831 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
834 D->
addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
839 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
842 D->
addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
847 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
850 D->
addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
853 llvm_unreachable(
"bad parameter ABI attribute");
This file declares semantic analysis for Objective-C.
This file declares semantic analysis functions specific to Swift.
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isRegularKeywordAttribute() const
SourceLocation getLoc() const
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
This represents one expression.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
IdentifierInfo * getIdentifierInfo() const
Represents a pointer to an Objective C object.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
unsigned getASTIndex() const
Get the parameter index as it would normally be encoded at the AST level of representation: zero-orig...
A parameter attribute which changes the argument-passing ABI rule for the parameter.
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
IdentifierLoc * getArgAsIdent(unsigned Arg) const
void setInvalid(bool b=true) const
bool isArgIdent(unsigned Arg) const
Expr * getArgAsExpr(unsigned Arg) const
bool isUsedAsTypeAttr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
Base for LValueReferenceType and RValueReferenceType.
ASTContext & getASTContext() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool isCFError(RecordDecl *D)
IdentifierInfo * getNSErrorIdent()
Retrieve the identifier "NSError".
void handleBridge(Decl *D, const ParsedAttr &AL)
void handleAsyncAttr(Decl *D, const ParsedAttr &AL)
bool DiagnoseName(Decl *D, StringRef Name, SourceLocation Loc, const ParsedAttr &AL, bool IsAsync)
Do a check to make sure Name looks like a legal argument for the swift_name attribute applied to decl...
void handleAsyncName(Decl *D, const ParsedAttr &AL)
SwiftNameAttr * mergeNameAttr(Decl *D, const SwiftNameAttr &SNA, StringRef Name)
SwiftAttrAttr * mergeAttrAttr(Decl *D, const SwiftAttrAttr &SAA)
void handleNewType(Decl *D, const ParsedAttr &AL)
void handleError(Decl *D, const ParsedAttr &AL)
void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, ParameterABI abi)
void handleAsyncError(Decl *D, const ParsedAttr &AL)
void handleName(Decl *D, const ParsedAttr &AL)
void handleAttrAttr(Decl *D, const ParsedAttr &AL)
Sema - This implements semantic analysis and AST building for C.
Encodes a location in the source.
bool isBlockPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Top level wrappers for InstallAPI frontend operations.
static bool isValidAsEscapedIdentifier(StringRef string)
static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, const SwiftAsyncErrorAttr *ErrorAttr, const SwiftAsyncAttr *AsyncAttr)
bool isa(CodeGen::Address addr)
@ ExpectedFunctionWithProtoType
static bool isValidSwiftErrorResultType(QualType Ty)
Pointers and references to pointers in the default address space.
llvm::StringRef getParameterABISpelling(ParameterABI kind)
QualType getFunctionOrMethodResultType(const Decl *D)
static bool isValidSwiftContextName(StringRef ContextName)
const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)
getFunctionOrMethodParam - Return parameter declaration for the given index of the passed Decl,...
static bool isErrorParameter(Sema &S, QualType QT)
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
static bool isValidSwiftIndirectResultType(QualType Ty)
Pointers and references in the default address space.
QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx)
static std::pair< StringRef, StringRef > backtickAwareSplit(StringRef text, char separator)
@ AANT_ArgumentIdentifier
static std::pair< StringRef, StringRef > backtickAwareRSplit(StringRef text, char separator)
ParameterABI
Kinds of parameter ABI.
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
@ Ordinary
This parameter uses ordinary ABI rules for its type.
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
static bool isValidSwiftContextType(QualType Ty)
Pointer-like types in the default address space.
static bool isValidSwiftIdentifier(StringRef text)
Returns true if the string is a valid ASCII Swift identifier.
static bool isValidIdentifierEscapedChar(char c)
static bool validateSwiftFunctionName(Sema &S, const ParsedAttr &AL, SourceLocation Loc, StringRef Name, unsigned &SwiftParamCount, bool &IsSingleParamInit)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t