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);
37 D->dropAttr<SwiftNameAttr>();
94 if (
const auto *
Other =
D->getAttr<SwiftBridgeAttr>()) {
95 if (
Other->getSwiftType() != BT)
96 Diag(AL.
getLoc(), diag::warn_duplicate_attribute) << AL;
112 if (
const auto *
ID = OPT->getInterfaceDecl())
118 if (
const auto *RT = PT->getPointeeType()->getAs<
RecordType>())
132 S.Diag(AL.
getLoc(), diag::err_attr_swift_error_no_error_parameter)
133 << AL << isa<ObjCMethodDecl>(
D);
145 S.Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
156 S.Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
162 if (
D->isInvalidDecl())
166 SwiftErrorAttr::ConventionKind Convention;
167 if (!SwiftErrorAttr::ConvertStrToConventionKind(
Loc->Ident->getName(),
169 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
174 switch (Convention) {
175 case SwiftErrorAttr::None:
179 case SwiftErrorAttr::NonNullError:
180 if (!hasErrorParameter(
SemaRef,
D, AL))
184 case SwiftErrorAttr::NullResult:
185 if (!hasErrorParameter(
SemaRef,
D, AL) || !hasPointerResult(
SemaRef,
D, AL))
189 case SwiftErrorAttr::NonZeroResult:
190 case SwiftErrorAttr::ZeroResult:
191 if (!hasErrorParameter(
SemaRef,
D, AL) || !hasIntegerResult(
SemaRef,
D, AL))
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);
213 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
216 const auto *FuncTy = HandlerParam->
getType()
222 BlockParams = FuncTy->getParamTypes();
224 switch (ErrorAttr->getConvention()) {
225 case SwiftAsyncErrorAttr::ZeroArgument:
226 case SwiftAsyncErrorAttr::NonZeroArgument: {
227 uint32_t
ParamIdx = ErrorAttr->getHandlerParamIdx();
229 S.
Diag(ErrorAttr->getLocation(),
230 diag::err_attribute_argument_out_of_bounds)
237 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
239 :
"nonzero_argument";
240 S.
Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
241 << ErrorAttr << ConvStr <<
ParamIdx << ErrorParam;
246 case SwiftAsyncErrorAttr::NonNullError: {
247 bool AnyErrorParams =
false;
248 for (
QualType Param : BlockParams) {
251 if (
const auto *
ID = ObjCPtrTy->getInterfaceDecl()) {
253 AnyErrorParams =
true;
259 if (
const auto *PtrTy = Param->getAs<
PointerType>()) {
260 if (
const auto *RT = PtrTy->getPointeeType()->getAs<
RecordType>()) {
262 AnyErrorParams =
true;
269 if (!AnyErrorParams) {
270 S.
Diag(ErrorAttr->getLocation(),
271 diag::err_swift_async_error_no_error_parameter)
272 << ErrorAttr << isa<ObjCMethodDecl>(
D);
277 case SwiftAsyncErrorAttr::None:
284 SwiftAsyncErrorAttr::ConventionKind ConvKind;
285 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(IDLoc->
Ident->
getName(),
287 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
288 << AL << IDLoc->
Ident;
294 case SwiftAsyncErrorAttr::ZeroArgument:
295 case SwiftAsyncErrorAttr::NonZeroArgument: {
304 case SwiftAsyncErrorAttr::NonNullError:
305 case SwiftAsyncErrorAttr::None: {
314 D->addAttr(ErrorAttr);
316 if (
auto *AsyncAttr =
D->getAttr<SwiftAsyncAttr>())
330 unsigned &SwiftParamCount,
331 bool &IsSingleParamInit) {
333 IsSingleParamInit =
false;
336 bool IsGetter =
false, IsSetter =
false;
337 if (Name.consume_front(
"getter:"))
339 else if (Name.consume_front(
"setter:"))
342 if (Name.back() !=
')') {
343 S.
Diag(
Loc, diag::warn_attr_swift_name_function) << AL;
347 bool IsMember =
false;
348 StringRef ContextName, BaseName, Parameters;
350 std::tie(BaseName, Parameters) = Name.split(
'(');
354 std::tie(ContextName, BaseName) = BaseName.split(
'.');
355 if (BaseName.empty()) {
356 BaseName = ContextName;
357 ContextName = StringRef();
359 S.
Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
367 S.
Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
372 bool IsSubscript = BaseName ==
"subscript";
374 if (IsSubscript && !IsGetter && !IsSetter) {
375 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
380 if (Parameters.empty()) {
381 S.
Diag(
Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
385 assert(Parameters.back() ==
')' &&
"expected ')'");
386 Parameters = Parameters.drop_back();
388 if (Parameters.empty()) {
391 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
397 S.
Diag(
Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
404 if (Parameters.back() !=
':') {
405 S.
Diag(
Loc, diag::warn_attr_swift_name_function) << AL;
409 StringRef CurrentParam;
410 std::optional<unsigned> SelfLocation;
411 unsigned NewValueCount = 0;
412 std::optional<unsigned> NewValueLocation;
414 std::tie(CurrentParam, Parameters) = Parameters.split(
':');
417 S.
Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
422 if (IsMember && CurrentParam ==
"self") {
427 S.
Diag(
Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
432 SelfLocation = SwiftParamCount;
433 }
else if (CurrentParam ==
"newValue") {
440 NewValueLocation = SwiftParamCount;
444 }
while (!Parameters.empty());
447 if (IsSubscript && !SelfLocation) {
448 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
454 SwiftParamCount == 1 && BaseName ==
"init" && CurrentParam !=
"_";
457 if (IsGetter || IsSetter) {
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;
471 if (SwiftParamCount < NumExpectedParams) {
479 if (!NewValueLocation) {
480 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
484 if (NewValueCount > 1) {
486 diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
492 if (NewValueLocation) {
493 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
500 if (SwiftParamCount != NumExpectedParams) {
512 if (isa<ObjCMethodDecl>(
D) || isa<FunctionDecl>(
D)) {
516 if (
const auto *Method = dyn_cast<ObjCMethodDecl>(
D)) {
517 ParamCount = Method->getSelector().getNumArgs();
518 Params = Method->parameters().slice(0, ParamCount);
520 const auto *F = cast<FunctionDecl>(
D);
522 ParamCount = F->getNumParams();
523 Params = F->parameters();
525 if (!F->hasWrittenPrototype()) {
526 Diag(
Loc, diag::warn_attribute_wrong_decl_type)
535 if (ParamCount == 0) {
536 Diag(
Loc, diag::warn_attr_swift_name_decl_missing_params)
537 << AL << isa<ObjCMethodDecl>(
D);
543 unsigned SwiftParamCount;
544 bool IsSingleParamInit;
549 bool ParamCountValid;
550 if (SwiftParamCount == ParamCount) {
551 ParamCountValid =
true;
552 }
else if (SwiftParamCount > ParamCount) {
553 ParamCountValid = IsSingleParamInit && ParamCount == 0;
558 unsigned MaybeOutParamCount =
559 llvm::count_if(Params, [](
const ParmVarDecl *Param) ->
bool {
566 ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
569 if (!ParamCountValid) {
570 Diag(
Loc, diag::warn_attr_swift_name_num_params)
571 << (SwiftParamCount > ParamCount) << AL << ParamCount
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)) &&
580 StringRef ContextName, BaseName;
582 std::tie(ContextName, BaseName) = Name.split(
'.');
583 if (BaseName.empty()) {
584 BaseName = ContextName;
585 ContextName = StringRef();
587 Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
593 Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
598 Diag(
Loc, diag::warn_attr_swift_name_decl_kind) << AL;
635 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
640 SwiftNewTypeAttr::NewtypeKind
Kind;
642 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->
getName(),
Kind)) {
643 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
647 if (!isa<TypedefNameDecl>(
D)) {
648 Diag(AL.
getLoc(), diag::warn_attribute_wrong_decl_type_str)
659 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
664 SwiftAsyncAttr::Kind
Kind;
666 if (!SwiftAsyncAttr::ConvertStrToKind(II->
getName(),
Kind)) {
667 Diag(AL.
getLoc(), diag::err_swift_async_no_access) << AL << II;
672 if (
Kind == SwiftAsyncAttr::None) {
689 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
696 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
704 D->addAttr(AsyncAttr);
706 if (
auto *ErrorAttr =
D->getAttr<SwiftAsyncErrorAttr>())
716 if (existingAttr->getABI() != abi) {
717 Diag(CI.
getLoc(), diag::err_attributes_are_not_compatible)
720 existingAttr->isRegularKeywordAttribute());
721 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
728 llvm_unreachable(
"explicit attribute for ordinary parameter ABI?");
732 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
735 D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
740 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
743 D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
748 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
751 D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
756 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
759 D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
762 llvm_unreachable(
"bad parameter ABI attribute");
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
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.
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.
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
bool isArgIdent(unsigned Arg) const
Expr * getArgAsExpr(unsigned Arg) 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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
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.
bool checkUInt32Argument(const AttrInfo &AI, const Expr *Expr, uint32_t &Val, unsigned Idx=UINT_MAX, bool StrictlyUnsigned=false)
If Expr is a valid integer constant, get the value of the integer expression and return success or fa...
bool checkFunctionOrMethodParameterIndex(const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis=false)
Check if IdxExpr is a valid parameter index for a function or instance method D.
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
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.
The JSON file list parser is used to communicate input to InstallAPI.
static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, const SwiftAsyncErrorAttr *ErrorAttr, const SwiftAsyncAttr *AsyncAttr)
@ 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)
const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)
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)
@ AANT_ArgumentIdentifier
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 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.
@ Other
Other implicit parameter.
Wraps an identifier and optional source location for the identifier.