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);
76 if (c ==
'`' || c ==
'\\')
79 unsigned char uc =
static_cast<unsigned char>(c);
81 if (uc < 0x20 || uc >= 0x7F)
92 for (
char c :
string) {
104 bool inBackticks =
false;
105 for (
size_t i = 0; i < text.size(); ++i) {
108 inBackticks = !inBackticks;
109 }
else if (c == separator && !inBackticks) {
110 return {text.substr(0, i), text.substr(i + 1)};
113 return {text, StringRef()};
118 bool inBackticks =
false;
119 for (
size_t i = text.size(); i > 0; --i) {
120 char c = text[i - 1];
122 inBackticks = !inBackticks;
123 }
else if (c == separator && !inBackticks) {
124 return {text.substr(0, i - 1), text.substr(i)};
127 return {text, StringRef()};
133 if (text.size() > 2 && text.front() ==
'`' && text.back() ==
'`')
140 StringRef
First, Rest = ContextName;
145 }
while (!Rest.empty());
156 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str)) {
168 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, BT))
173 if (
const auto *
Other = D->
getAttr<SwiftBridgeAttr>()) {
174 if (
Other->getSwiftType() != BT)
175 Diag(AL.
getLoc(), diag::warn_duplicate_attribute) << AL;
191 if (
const auto *ID = OPT->getInterfaceDecl())
197 if (
auto *RD = PT->getPointeeType()->getAsRecordDecl();
211 S.
Diag(AL.
getLoc(), diag::err_attr_swift_error_no_error_parameter)
212 << AL << isa<ObjCMethodDecl>(D);
224 S.
Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
235 S.
Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
245 SwiftErrorAttr::ConventionKind Convention;
246 if (!SwiftErrorAttr::ConvertStrToConventionKind(
248 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
253 switch (Convention) {
254 case SwiftErrorAttr::None:
258 case SwiftErrorAttr::NonNullError:
259 if (!hasErrorParameter(
SemaRef, D, AL))
263 case SwiftErrorAttr::NullResult:
264 if (!hasErrorParameter(
SemaRef, D, AL) || !hasPointerResult(
SemaRef, D, AL))
268 case SwiftErrorAttr::NonZeroResult:
269 case SwiftErrorAttr::ZeroResult:
270 if (!hasErrorParameter(
SemaRef, D, AL) || !hasIntegerResult(
SemaRef, D, AL))
280 const SwiftAsyncErrorAttr *ErrorAttr,
281 const SwiftAsyncAttr *AsyncAttr) {
282 if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {
283 if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {
284 S.
Diag(AsyncAttr->getLocation(),
285 diag::err_swift_async_error_without_swift_async)
286 << AsyncAttr << isa<ObjCMethodDecl>(D);
292 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
295 const auto *FuncTy = HandlerParam->
getType()
301 BlockParams = FuncTy->getParamTypes();
303 switch (ErrorAttr->getConvention()) {
304 case SwiftAsyncErrorAttr::ZeroArgument:
305 case SwiftAsyncErrorAttr::NonZeroArgument: {
308 S.
Diag(ErrorAttr->getLocation(),
309 diag::err_attribute_argument_out_of_bounds)
316 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
318 :
"nonzero_argument";
319 S.
Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
320 << ErrorAttr << ConvStr <<
ParamIdx << ErrorParam;
325 case SwiftAsyncErrorAttr::NonNullError: {
326 bool AnyErrorParams =
false;
327 for (
QualType Param : BlockParams) {
330 if (
const auto *ID = ObjCPtrTy->getInterfaceDecl()) {
332 AnyErrorParams =
true;
338 if (
const auto *PtrTy = Param->getAs<
PointerType>()) {
339 if (
auto *RD = PtrTy->getPointeeType()->getAsRecordDecl();
341 AnyErrorParams =
true;
347 if (!AnyErrorParams) {
348 S.
Diag(ErrorAttr->getLocation(),
349 diag::err_swift_async_error_no_error_parameter)
350 << ErrorAttr << isa<ObjCMethodDecl>(D);
355 case SwiftAsyncErrorAttr::None:
362 SwiftAsyncErrorAttr::ConventionKind ConvKind;
363 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(
365 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
372 case SwiftAsyncErrorAttr::ZeroArgument:
373 case SwiftAsyncErrorAttr::NonZeroArgument: {
382 case SwiftAsyncErrorAttr::NonNullError:
383 case SwiftAsyncErrorAttr::None: {
394 if (
auto *AsyncAttr = D->
getAttr<SwiftAsyncAttr>())
408 unsigned &SwiftParamCount,
409 bool &IsSingleParamInit) {
411 IsSingleParamInit =
false;
414 bool IsGetter =
false, IsSetter =
false;
415 if (Name.consume_front(
"getter:"))
417 else if (Name.consume_front(
"setter:"))
420 if (Name.empty() || Name.back() !=
')') {
421 S.
Diag(Loc, diag::warn_attr_swift_name_function) << AL;
425 bool IsMember =
false;
426 StringRef ContextName, BaseName, Parameters;
433 if (BaseName.empty()) {
434 BaseName = ContextName;
435 ContextName = StringRef();
437 S.
Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
445 S.
Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
450 bool IsSubscript = BaseName ==
"subscript";
452 if (IsSubscript && !IsGetter && !IsSetter) {
453 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
458 if (Parameters.empty()) {
459 S.
Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
463 assert(Parameters.back() ==
')' &&
"expected ')'");
464 Parameters = Parameters.drop_back();
466 if (Parameters.empty()) {
469 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
475 S.
Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
482 if (Parameters.back() !=
':') {
483 S.
Diag(Loc, diag::warn_attr_swift_name_function) << AL;
487 StringRef CurrentParam;
488 std::optional<unsigned> SelfLocation;
489 unsigned NewValueCount = 0;
490 std::optional<unsigned> NewValueLocation;
495 S.
Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
500 if (IsMember && CurrentParam ==
"self") {
505 S.
Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
510 SelfLocation = SwiftParamCount;
511 }
else if (CurrentParam ==
"newValue") {
518 NewValueLocation = SwiftParamCount;
522 }
while (!Parameters.empty());
525 if (IsSubscript && !SelfLocation) {
526 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
532 SwiftParamCount == 1 && BaseName ==
"init" && CurrentParam !=
"_";
535 if (IsGetter || IsSetter) {
537 unsigned NumExpectedParams = IsGetter ? 0 : 1;
538 unsigned ParamDiag = IsGetter
539 ? diag::warn_attr_swift_name_getter_parameters
540 : diag::warn_attr_swift_name_setter_parameters;
549 if (SwiftParamCount < NumExpectedParams) {
550 S.
Diag(Loc, ParamDiag) << AL;
557 if (!NewValueLocation) {
558 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
562 if (NewValueCount > 1) {
564 diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
570 if (NewValueLocation) {
571 S.
Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
578 if (SwiftParamCount != NumExpectedParams) {
579 S.
Diag(Loc, ParamDiag) << AL;
594 if (
const auto *
Method = dyn_cast<ObjCMethodDecl>(D)) {
595 ParamCount =
Method->getSelector().getNumArgs();
596 Params =
Method->parameters().slice(0, ParamCount);
600 ParamCount = F->getNumParams();
601 Params = F->parameters();
603 if (!F->hasWrittenPrototype()) {
604 Diag(Loc, diag::warn_attribute_wrong_decl_type)
613 if (ParamCount == 0) {
614 Diag(Loc, diag::warn_attr_swift_name_decl_missing_params)
615 << AL << isa<ObjCMethodDecl>(D);
621 unsigned SwiftParamCount;
622 bool IsSingleParamInit;
627 bool ParamCountValid;
628 if (SwiftParamCount == ParamCount) {
629 ParamCountValid =
true;
630 }
else if (SwiftParamCount > ParamCount) {
631 ParamCountValid = IsSingleParamInit && ParamCount == 0;
636 unsigned MaybeOutParamCount =
637 llvm::count_if(Params, [](
const ParmVarDecl *Param) ->
bool {
638 QualType ParamTy = Param->getType();
644 ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
647 if (!ParamCountValid) {
648 Diag(Loc, diag::warn_attr_swift_name_num_params)
649 << (SwiftParamCount > ParamCount) << AL << ParamCount
658 StringRef ContextName, BaseName;
661 if (BaseName.empty()) {
662 BaseName = ContextName;
663 ContextName = StringRef();
665 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
671 Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
676 Diag(Loc, diag::warn_attr_swift_name_decl_kind) << AL;
685 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
697 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
713 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
718 SwiftNewTypeAttr::NewtypeKind Kind;
720 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->
getName(), Kind)) {
721 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
726 Diag(AL.
getLoc(), diag::warn_attribute_wrong_decl_type)
737 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
742 SwiftAsyncAttr::Kind Kind;
744 if (!SwiftAsyncAttr::ConvertStrToKind(II->
getName(), Kind)) {
745 Diag(AL.
getLoc(), diag::err_swift_async_no_access) << AL << II;
750 if (Kind == SwiftAsyncAttr::None) {
760 if (!
SemaRef.checkFunctionOrMethodParameterIndex(D, AL, 2, HandlerIdx, Idx))
767 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
774 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
784 if (
auto *ErrorAttr = D->
getAttr<SwiftAsyncErrorAttr>())
794 if (existingAttr->getABI() !=
abi) {
795 Diag(CI.
getLoc(), diag::err_attributes_are_not_compatible)
798 existingAttr->isRegularKeywordAttribute());
799 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
807 llvm_unreachable(
"explicit attribute for non-swift parameter ABI?");
809 llvm_unreachable(
"explicit attribute for ordinary parameter ABI?");
813 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
816 D->
addAttr(::new (Context) SwiftContextAttr(Context, CI));
821 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
824 D->
addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
829 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
832 D->
addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
837 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
840 D->
addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
843 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
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)
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