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>();
78 ContextName.split(ContextNameComponents,
'.');
79 return all_of(ContextNameComponents, [&](StringRef Component) {
108 if (
const auto *
Other =
D->getAttr<SwiftBridgeAttr>()) {
109 if (
Other->getSwiftType() != BT)
110 Diag(AL.
getLoc(), diag::warn_duplicate_attribute) << AL;
126 if (
const auto *
ID = OPT->getInterfaceDecl())
132 if (
auto *RD = PT->getPointeeType()->getAsRecordDecl();
146 S.Diag(AL.
getLoc(), diag::err_attr_swift_error_no_error_parameter)
147 << AL << isa<ObjCMethodDecl>(
D);
159 S.Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
161 << isa<ObjCMethodDecl>(
D) << 1;
170 S.Diag(AL.
getLoc(), diag::err_attr_swift_error_return_type)
172 << isa<ObjCMethodDecl>(
D) << 0;
176 if (
D->isInvalidDecl())
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();
188 switch (Convention) {
189 case SwiftErrorAttr::None:
193 case SwiftErrorAttr::NonNullError:
194 if (!hasErrorParameter(
SemaRef,
D, AL))
198 case SwiftErrorAttr::NullResult:
199 if (!hasErrorParameter(
SemaRef,
D, AL) || !hasPointerResult(
SemaRef,
D, AL))
203 case SwiftErrorAttr::NonZeroResult:
204 case SwiftErrorAttr::ZeroResult:
205 if (!hasErrorParameter(
SemaRef,
D, AL) || !hasIntegerResult(
SemaRef,
D, AL))
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);
227 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
230 const auto *FuncTy = HandlerParam->
getType()
236 BlockParams = FuncTy->getParamTypes();
238 switch (ErrorAttr->getConvention()) {
239 case SwiftAsyncErrorAttr::ZeroArgument:
240 case SwiftAsyncErrorAttr::NonZeroArgument: {
241 uint32_t
ParamIdx = ErrorAttr->getHandlerParamIdx();
243 S.
Diag(ErrorAttr->getLocation(),
244 diag::err_attribute_argument_out_of_bounds)
251 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
253 :
"nonzero_argument";
254 S.
Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
255 << ErrorAttr << ConvStr <<
ParamIdx << ErrorParam;
260 case SwiftAsyncErrorAttr::NonNullError: {
261 bool AnyErrorParams =
false;
262 for (
QualType Param : BlockParams) {
265 if (
const auto *
ID = ObjCPtrTy->getInterfaceDecl()) {
267 AnyErrorParams =
true;
273 if (
const auto *PtrTy = Param->getAs<
PointerType>()) {
274 if (
auto *RD = PtrTy->getPointeeType()->getAsRecordDecl();
276 AnyErrorParams =
true;
282 if (!AnyErrorParams) {
283 S.
Diag(ErrorAttr->getLocation(),
284 diag::err_swift_async_error_no_error_parameter)
285 << ErrorAttr << isa<ObjCMethodDecl>(
D);
290 case SwiftAsyncErrorAttr::None:
297 SwiftAsyncErrorAttr::ConventionKind ConvKind;
298 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(
300 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
307 case SwiftAsyncErrorAttr::ZeroArgument:
308 case SwiftAsyncErrorAttr::NonZeroArgument: {
317 case SwiftAsyncErrorAttr::NonNullError:
318 case SwiftAsyncErrorAttr::None: {
327 D->addAttr(ErrorAttr);
329 if (
auto *AsyncAttr =
D->getAttr<SwiftAsyncAttr>())
343 unsigned &SwiftParamCount,
344 bool &IsSingleParamInit) {
346 IsSingleParamInit =
false;
349 bool IsGetter =
false, IsSetter =
false;
350 if (Name.consume_front(
"getter:"))
352 else if (Name.consume_front(
"setter:"))
355 if (Name.back() !=
')') {
356 S.
Diag(
Loc, diag::warn_attr_swift_name_function) << AL;
360 bool IsMember =
false;
361 StringRef ContextName, BaseName, Parameters;
363 std::tie(BaseName, Parameters) = Name.split(
'(');
367 std::tie(ContextName, BaseName) = BaseName.rsplit(
'.');
368 if (BaseName.empty()) {
369 BaseName = ContextName;
370 ContextName = StringRef();
372 S.
Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
380 S.
Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
385 bool IsSubscript = BaseName ==
"subscript";
387 if (IsSubscript && !IsGetter && !IsSetter) {
388 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
393 if (Parameters.empty()) {
394 S.
Diag(
Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
398 assert(Parameters.back() ==
')' &&
"expected ')'");
399 Parameters = Parameters.drop_back();
401 if (Parameters.empty()) {
404 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
410 S.
Diag(
Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
417 if (Parameters.back() !=
':') {
418 S.
Diag(
Loc, diag::warn_attr_swift_name_function) << AL;
422 StringRef CurrentParam;
423 std::optional<unsigned> SelfLocation;
424 unsigned NewValueCount = 0;
425 std::optional<unsigned> NewValueLocation;
427 std::tie(CurrentParam, Parameters) = Parameters.split(
':');
430 S.
Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
435 if (IsMember && CurrentParam ==
"self") {
440 S.
Diag(
Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
445 SelfLocation = SwiftParamCount;
446 }
else if (CurrentParam ==
"newValue") {
453 NewValueLocation = SwiftParamCount;
457 }
while (!Parameters.empty());
460 if (IsSubscript && !SelfLocation) {
461 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
467 SwiftParamCount == 1 && BaseName ==
"init" && CurrentParam !=
"_";
470 if (IsGetter || IsSetter) {
472 unsigned NumExpectedParams = IsGetter ? 0 : 1;
473 unsigned ParamDiag = IsGetter
474 ? diag::warn_attr_swift_name_getter_parameters
475 : diag::warn_attr_swift_name_setter_parameters;
484 if (SwiftParamCount < NumExpectedParams) {
492 if (!NewValueLocation) {
493 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
497 if (NewValueCount > 1) {
499 diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
505 if (NewValueLocation) {
506 S.
Diag(
Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
513 if (SwiftParamCount != NumExpectedParams) {
525 if (isa<ObjCMethodDecl>(
D) || isa<FunctionDecl>(
D)) {
529 if (
const auto *
Method = dyn_cast<ObjCMethodDecl>(
D)) {
530 ParamCount =
Method->getSelector().getNumArgs();
531 Params =
Method->parameters().slice(0, ParamCount);
533 const auto *F = cast<FunctionDecl>(
D);
535 ParamCount = F->getNumParams();
536 Params = F->parameters();
538 if (!F->hasWrittenPrototype()) {
539 Diag(
Loc, diag::warn_attribute_wrong_decl_type)
548 if (ParamCount == 0) {
549 Diag(
Loc, diag::warn_attr_swift_name_decl_missing_params)
550 << AL << isa<ObjCMethodDecl>(
D);
556 unsigned SwiftParamCount;
557 bool IsSingleParamInit;
562 bool ParamCountValid;
563 if (SwiftParamCount == ParamCount) {
564 ParamCountValid =
true;
565 }
else if (SwiftParamCount > ParamCount) {
566 ParamCountValid = IsSingleParamInit && ParamCount == 0;
571 unsigned MaybeOutParamCount =
572 llvm::count_if(Params, [](
const ParmVarDecl *Param) ->
bool {
579 ParamCountValid = SwiftParamCount + MaybeOutParamCount >= ParamCount;
582 if (!ParamCountValid) {
583 Diag(
Loc, diag::warn_attr_swift_name_num_params)
584 << (SwiftParamCount > ParamCount) << AL << ParamCount
588 }
else if ((isa<EnumConstantDecl>(
D) || isa<ObjCProtocolDecl>(
D) ||
589 isa<ObjCInterfaceDecl>(
D) || isa<ObjCPropertyDecl>(
D) ||
590 isa<VarDecl>(
D) || isa<TypedefNameDecl>(
D) || isa<TagDecl>(
D) ||
591 isa<IndirectFieldDecl>(
D) || isa<FieldDecl>(
D)) &&
593 StringRef ContextName, BaseName;
595 std::tie(ContextName, BaseName) = Name.rsplit(
'.');
596 if (BaseName.empty()) {
597 BaseName = ContextName;
598 ContextName = StringRef();
600 Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
606 Diag(
Loc, diag::warn_attr_swift_name_invalid_identifier)
611 Diag(
Loc, diag::warn_attr_swift_name_decl_kind) << AL;
648 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
653 SwiftNewTypeAttr::NewtypeKind
Kind;
655 if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->
getName(),
Kind)) {
656 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
660 if (!isa<TypedefNameDecl>(
D)) {
661 Diag(AL.
getLoc(), diag::warn_attribute_wrong_decl_type)
672 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
677 SwiftAsyncAttr::Kind
Kind;
679 if (!SwiftAsyncAttr::ConvertStrToKind(II->
getName(),
Kind)) {
680 Diag(AL.
getLoc(), diag::err_swift_async_no_access) << AL << II;
685 if (
Kind == SwiftAsyncAttr::None) {
702 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
709 Diag(CompletionBlock->
getLocation(), diag::err_swift_async_bad_block_type)
717 D->addAttr(AsyncAttr);
719 if (
auto *ErrorAttr =
D->getAttr<SwiftAsyncErrorAttr>())
729 if (existingAttr->getABI() != abi) {
730 Diag(CI.
getLoc(), diag::err_attributes_are_not_compatible)
733 existingAttr->isRegularKeywordAttribute());
734 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
742 llvm_unreachable(
"explicit attribute for non-swift parameter ABI?");
744 llvm_unreachable(
"explicit attribute for ordinary parameter ABI?");
748 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
751 D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
756 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
759 D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
764 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
767 D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
772 Diag(CI.
getLoc(), diag::err_swift_abi_parameter_wrong_type)
775 D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
778 llvm_unreachable(
"bad parameter ABI attribute");
enum clang::sema::@1840::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.
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.
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 checkFunctionOrMethodParameterIndex(const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis=false, bool CanIndexVariadicArguments=false)
Check if IdxExpr is a valid parameter index for a function or instance method D.
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 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)
static bool isValidSwiftContextName(StringRef ContextName)
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.