Skip to content

Commit 117f706

Browse files
authored
Merge pull request #2189 from apple/eng/alexattrs
New swift attributes + direct change
2 parents 0daa136 + 66f0b7c commit 117f706

14 files changed

+337
-21
lines changed

Diff for: clang/include/clang/Basic/Attr.td

+14-1
Original file line numberDiff line numberDiff line change
@@ -2106,6 +2106,19 @@ def Regparm : TypeAttr {
21062106
let ASTNode = 0;
21072107
}
21082108

2109+
def SwiftAsyncName : InheritableAttr {
2110+
let Spellings = [GNU<"swift_async_name">];
2111+
let Args = [StringArgument<"Name">];
2112+
let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>;
2113+
let Documentation = [SwiftAsyncNameDocs];
2114+
}
2115+
2116+
def SwiftAttr : InheritableAttr {
2117+
let Spellings = [GNU<"swift_attr">];
2118+
let Args = [StringArgument<"Attribute">];
2119+
let Documentation = [SwiftAttrDocs];
2120+
}
2121+
21092122
def SwiftBridge : Attr {
21102123
let Spellings = [GNU<"swift_bridge">];
21112124
let Subjects = SubjectList<[Tag, TypedefName, ObjCInterface, ObjCProtocol],
@@ -2168,7 +2181,7 @@ def SwiftImportAsNonGeneric : InheritableAttr {
21682181
let Documentation = [Undocumented];
21692182
}
21702183

2171-
def SwiftImportPropertyAsAccessors : InheritableAttr {
2184+
def SwiftImportPropertyAsAccessors : InheritableAttr {
21722185
// This attribute has no spellings as it is only ever created implicitly
21732186
// from API notes.
21742187
let Spellings = [];

Diff for: clang/include/clang/Basic/AttrDocs.td

+34
Original file line numberDiff line numberDiff line change
@@ -3546,6 +3546,40 @@ The ``ns_error_domain`` attribute indicates a global constant representing the e
35463546
}];
35473547
}
35483548

3549+
def SwiftAsyncNameDocs : Documentation {
3550+
let Category = SwiftDocs;
3551+
let Heading = "swift_async_name";
3552+
let Content = [{
3553+
The ``swift_async_name`` attribute provides the name of the ``async`` overload for
3554+
the given declaration in Swift. If this attribute is absent, the name is
3555+
transformed according to the algorithm built into the Swift compiler.
3556+
3557+
The argument is a string literal that contains the Swift name of the function or
3558+
method. The name may be a compound Swift name. The function or method with such
3559+
an attribute must have more than zero parameters, as its last parameter is
3560+
assumed to be a callback that's eliminated in the Swift ``async`` name.
3561+
3562+
.. code-block:: objc
3563+
3564+
@interface URL
3565+
+ (void) loadContentsFrom:(URL *)url callback:(void (^)(NSData *))data __attribute__((__swift_async_name__("URL.loadContentsFrom(_:)")))
3566+
@end
3567+
}];
3568+
}
3569+
3570+
def SwiftAttrDocs : Documentation {
3571+
let Category = SwiftDocs;
3572+
let Heading = "swift_attr";
3573+
let Content = [{
3574+
The ``swift_attr`` provides a Swift-specific annotation for the declaration
3575+
to which the attribute appertains to. It can be used on any declaration
3576+
in Clang. This kind of annotation is ignored by Clang as it doesn't have any
3577+
semantic meaning in languages supported by Clang. The Swift compiler can
3578+
interpret these annotations according to its own rules when importing C or
3579+
Objective-C declarations.
3580+
}];
3581+
}
3582+
35493583
def SwiftBridgeDocs : Documentation {
35503584
let Category = SwiftDocs;
35513585
let Content = [{

Diff for: clang/include/clang/Basic/DiagnosticSemaKinds.td

+13-3
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,10 @@ def warn_objc_direct_property_ignored : Warning<
11091109
InGroup<IgnoredAttributes>;
11101110
def err_objc_direct_dynamic_property : Error<
11111111
"direct property cannot be @dynamic">;
1112+
def err_objc_direct_protocol_conformance : Error<
1113+
"%select{category %1|class extension}0 cannot conform to protocol %2 because "
1114+
"of direct members declared in interface %3">;
1115+
def note_direct_member_here : Note<"direct member declared here">;
11121116

11131117
def warn_conflicting_overriding_ret_types : Warning<
11141118
"conflicting return type in "
@@ -4062,9 +4066,15 @@ def warn_attr_swift_name_multiple_selfs : Warning<
40624066
def warn_attr_swift_name_static_subscript : Warning<
40634067
"%0 attribute for 'subscript' must take a 'self:' parameter">,
40644068
InGroup<SwiftNameAttribute>;
4065-
def warn_attr_swift_name_num_params : Warning<
4066-
"too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">,
4067-
InGroup<SwiftNameAttribute>;
4069+
def warn_attr_swift_name_num_params
4070+
: Warning<"too %select{few|many}0 parameters in the signature specified by "
4071+
"the %1 attribute (expected %2; got %3)">,
4072+
InGroup<SwiftNameAttribute>;
4073+
def warn_attr_swift_name_decl_missing_params
4074+
: Warning<"%0 attribute cannot be applied to a %select{function|method}1 "
4075+
"with no parameters">,
4076+
InGroup<SwiftNameAttribute>;
4077+
40684078
def err_attr_swift_error_no_error_parameter : Error<
40694079
"%0 attribute can only be applied to a %select{function|method}1 "
40704080
"with an error parameter">;

Diff for: clang/include/clang/Sema/Sema.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1857,7 +1857,7 @@ class Sema final {
18571857
/// \returns true if the name is a valid swift name for \p D, false otherwise.
18581858
bool DiagnoseSwiftName(Decl *D, StringRef Name,
18591859
SourceLocation ArgLoc,
1860-
const IdentifierInfo *AttrName);
1860+
const IdentifierInfo *AttrName, bool IsAsync);
18611861

18621862
/// A derivative of BoundTypeDiagnoser for which the diagnostic's type
18631863
/// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless.

Diff for: clang/lib/Sema/SemaAPINotes.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ static void ProcessAPINotes(Sema &S, Decl *D,
316316
auto &APINoteName = S.getASTContext().Idents.get("SwiftName API Note");
317317

318318
if (!S.DiagnoseSwiftName(D, info.SwiftName, D->getLocation(),
319-
&APINoteName)) {
319+
&APINoteName, /*IsAsync=*/false)) {
320320
return nullptr;
321321
}
322322

Diff for: clang/lib/Sema/SemaDeclAttr.cpp

+44-4
Original file line numberDiff line numberDiff line change
@@ -5553,6 +5553,16 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
55535553
D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
55545554
}
55555555

5556+
static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5557+
// Make sure that there is a string literal as the annotation's single
5558+
// argument.
5559+
StringRef Str;
5560+
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
5561+
return;
5562+
5563+
D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
5564+
}
5565+
55565566
static Optional<unsigned>
55575567
validateSwiftFunctionName(StringRef Name,
55585568
unsigned &SwiftParamCount,
@@ -5714,7 +5724,7 @@ validateSwiftFunctionName(StringRef Name,
57145724
/// \returns true if the name is a valid swift name for \p D, false otherwise.
57155725
bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name,
57165726
SourceLocation ArgLoc,
5717-
const IdentifierInfo *AttrName) {
5727+
const IdentifierInfo *AttrName, bool IsAsync) {
57185728
if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
57195729
ArrayRef<ParmVarDecl*> Params;
57205730
unsigned ParamCount;
@@ -5734,6 +5744,16 @@ bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name,
57345744
}
57355745
}
57365746

5747+
// The async name drops the last callback parameter.
5748+
if (IsAsync) {
5749+
if (ParamCount == 0) {
5750+
Diag(ArgLoc, diag::warn_attr_swift_name_decl_missing_params)
5751+
<< AttrName << isa<ObjCMethodDecl>(D);
5752+
return false;
5753+
}
5754+
ParamCount -= 1;
5755+
}
5756+
57375757
unsigned SwiftParamCount;
57385758
bool IsSingleParamInit;
57395759
if (auto diagID = validateSwiftFunctionName(Name, SwiftParamCount,
@@ -5769,10 +5789,10 @@ bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name,
57695789
return false;
57705790
}
57715791

5772-
} else if (isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||
5792+
} else if ((isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||
57735793
isa<ObjCInterfaceDecl>(D) || isa<ObjCPropertyDecl>(D) ||
57745794
isa<VarDecl>(D) || isa<TypedefNameDecl>(D) || isa<TagDecl>(D) ||
5775-
isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) {
5795+
isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) && !IsAsync) {
57765796
StringRef ContextName, BaseName;
57775797
std::tie(ContextName, BaseName) = Name.split('.');
57785798
if (BaseName.empty()) {
@@ -5803,12 +5823,26 @@ static void handleSwiftName(Sema &S, Decl *D, const ParsedAttr &Attr) {
58035823
if (!S.checkStringLiteralArgumentAttr(Attr, 0, Name, &ArgLoc))
58045824
return;
58055825

5806-
if (!S.DiagnoseSwiftName(D, Name, ArgLoc, Attr.getAttrName()))
5826+
if (!S.DiagnoseSwiftName(D, Name, ArgLoc, Attr.getAttrName(),
5827+
/*IsAsync=*/false))
58075828
return;
58085829

58095830
D->addAttr(::new (S.Context) SwiftNameAttr(S.Context, Attr, Name));
58105831
}
58115832

5833+
static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &Attr) {
5834+
StringRef Name;
5835+
SourceLocation ArgLoc;
5836+
if (!S.checkStringLiteralArgumentAttr(Attr, 0, Name, &ArgLoc))
5837+
return;
5838+
5839+
if (!S.DiagnoseSwiftName(D, Name, ArgLoc, Attr.getAttrName(),
5840+
/*IsAsync=*/true))
5841+
return;
5842+
5843+
D->addAttr(::new (S.Context) SwiftAsyncNameAttr(S.Context, Attr, Name));
5844+
}
5845+
58125846
static bool isErrorParameter(Sema &S, QualType paramType) {
58135847
if (auto ptr = paramType->getAs<PointerType>()) {
58145848
auto outerPointee = ptr->getPointeeType();
@@ -7877,6 +7911,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
78777911
break;
78787912

78797913
// Swift attributes.
7914+
case ParsedAttr::AT_SwiftAsyncName:
7915+
handleSwiftAsyncName(S, D, AL);
7916+
break;
7917+
case ParsedAttr::AT_SwiftAttr:
7918+
handleSwiftAttrAttr(S, D, AL);
7919+
break;
78807920
case ParsedAttr::AT_SwiftPrivate:
78817921
handleSimpleAttribute<SwiftPrivateAttr>(S, D, AL);
78827922
break;

Diff for: clang/lib/Sema/SemaDeclObjC.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -3946,6 +3946,55 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) {
39463946
}
39473947
}
39483948

3949+
static void DiagnoseCategoryDirectMembersProtocolConformance(
3950+
Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl);
3951+
3952+
static void DiagnoseCategoryDirectMembersProtocolConformance(
3953+
Sema &S, ObjCCategoryDecl *CDecl,
3954+
const llvm::iterator_range<ObjCProtocolList::iterator> &Protocols) {
3955+
for (auto *PI : Protocols)
3956+
DiagnoseCategoryDirectMembersProtocolConformance(S, PI, CDecl);
3957+
}
3958+
3959+
static void DiagnoseCategoryDirectMembersProtocolConformance(
3960+
Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl) {
3961+
if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
3962+
PDecl = PDecl->getDefinition();
3963+
3964+
llvm::SmallVector<const Decl *, 4> DirectMembers;
3965+
const auto *IDecl = CDecl->getClassInterface();
3966+
for (auto *MD : PDecl->methods()) {
3967+
if (!MD->isPropertyAccessor()) {
3968+
if (const auto *CMD =
3969+
IDecl->getMethod(MD->getSelector(), MD->isInstanceMethod())) {
3970+
if (CMD->isDirectMethod())
3971+
DirectMembers.push_back(CMD);
3972+
}
3973+
}
3974+
}
3975+
for (auto *PD : PDecl->properties()) {
3976+
if (const auto *CPD = IDecl->FindPropertyVisibleInPrimaryClass(
3977+
PD->getIdentifier(),
3978+
PD->isClassProperty()
3979+
? ObjCPropertyQueryKind::OBJC_PR_query_class
3980+
: ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
3981+
if (CPD->isDirectProperty())
3982+
DirectMembers.push_back(CPD);
3983+
}
3984+
}
3985+
if (!DirectMembers.empty()) {
3986+
S.Diag(CDecl->getLocation(), diag::err_objc_direct_protocol_conformance)
3987+
<< CDecl->IsClassExtension() << CDecl << PDecl << IDecl;
3988+
for (const auto *MD : DirectMembers)
3989+
S.Diag(MD->getLocation(), diag::note_direct_member_here);
3990+
return;
3991+
}
3992+
3993+
// Check on this protocols's referenced protocols, recursively.
3994+
DiagnoseCategoryDirectMembersProtocolConformance(S, CDecl,
3995+
PDecl->protocols());
3996+
}
3997+
39493998
// Note: For class/category implementations, allMethods is always null.
39503999
Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
39514000
ArrayRef<DeclGroupPtrTy> allTUVars) {
@@ -4050,6 +4099,8 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
40504099
ObjCInterfaceDecl *CCPrimary = C->getClassInterface();
40514100
DiagnoseClassExtensionDupMethods(C, CCPrimary);
40524101
}
4102+
4103+
DiagnoseCategoryDirectMembersProtocolConformance(*this, C, C->protocols());
40534104
}
40544105
if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
40554106
if (CDecl->getIdentifier())

Diff for: clang/test/AST/attr-swift_attr.m

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
2+
3+
__attribute__((swift_attr("@actor")))
4+
@interface View
5+
@end
6+
7+
// CHECK: InterfaceDecl {{.*}} View
8+
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@actor"

Diff for: clang/test/Misc/pragma-attribute-supported-attributes-list.test

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
// CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
147147
// CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
148148
// CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
149+
// CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function)
149150
// CHECK-NEXT: SwiftBridgedTypedef (SubjectMatchRule_type_alias)
150151
// CHECK-NEXT: SwiftContext (SubjectMatchRule_variable_is_parameter)
151152
// CHECK-NEXT: SwiftError (SubjectMatchRule_function, SubjectMatchRule_objc_method)

Diff for: clang/test/SemaObjC/attr-swift.m

+11-11
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,22 @@ + (SNFoo *)fooWithValue:(int)value value:(int)value2 __attribute__((swift_name("
5151
+ (SNFoo *)fooWithConvertingValue:(int)value value:(int)value2 __attribute__((swift_name("init(_:extra:)")));
5252

5353
+ (SNFoo *)fooWithOtherValue:(int)value __attribute__((swift_name("init"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
54-
+ (SNFoo *)fooWithAnotherValue:(int)value __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
55-
+ (SNFoo *)fooWithYetAnotherValue:(int)value __attribute__((swift_name("foo(value:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 1; got 2)}}
54+
+ (SNFoo *)fooWithAnotherValue:(int)value __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in the signature specified by the 'swift_name' attribute (expected 1; got 0)}}
55+
+ (SNFoo *)fooWithYetAnotherValue:(int)value __attribute__((swift_name("foo(value:extra:)"))); // expected-warning {{too many parameters in the signature specified by the 'swift_name' attribute (expected 1; got 2)}}
5656

5757
+ (SNFoo *)fooAndReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo()"))); // no-warning
5858
+ (SNFoo *)fooWithValue:(int)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(value:)"))); // no-warning
59-
+ (SNFoo *)fooFromErrorCode:(const int *)errorCode __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
60-
+ (SNFoo *)fooWithValue:(int)value fromErrorCode:(const int *)errorCode __attribute__((swift_name("foo(value:)"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 2; got 1)}}
59+
+ (SNFoo *)fooFromErrorCode:(const int *)errorCode __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in the signature specified by the 'swift_name' attribute (expected 1; got 0)}}
60+
+ (SNFoo *)fooWithValue:(int)value fromErrorCode:(const int *)errorCode __attribute__((swift_name("foo(value:)"))); // expected-warning {{too few parameters in the signature specified by the 'swift_name' attribute (expected 2; got 1)}}
6161
+ (SNFoo *)fooWithPointerA:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo()"))); // no-warning
6262
+ (SNFoo *)fooWithPointerB:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(pointer:)"))); // no-warning
6363
+ (SNFoo *)fooWithPointerC:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(pointer:errorCode:)"))); // no-warning
64-
+ (SNFoo *)fooWithOtherFoo:(SNFoo *)other __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
64+
+ (SNFoo *)fooWithOtherFoo:(SNFoo *)other __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in the signature specified by the 'swift_name' attribute (expected 1; got 0)}}
6565

6666
+ (instancetype)specialFoo __attribute__((swift_name("init(options:)")));
67-
+ (instancetype)specialBar __attribute__((swift_name("init(options:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 2)}}
68-
+ (instancetype)specialBaz __attribute__((swift_name("init(_:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}}
69-
+ (instancetype)specialGarply __attribute__((swift_name("foo(options:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}}
67+
+ (instancetype)specialBar __attribute__((swift_name("init(options:extra:)"))); // expected-warning {{too many parameters in the signature specified by the 'swift_name' attribute (expected 0; got 2)}}
68+
+ (instancetype)specialBaz __attribute__((swift_name("init(_:)"))); // expected-warning {{too many parameters in the signature specified by the 'swift_name' attribute (expected 0; got 1)}}
69+
+ (instancetype)specialGarply __attribute__((swift_name("foo(options:)"))); // expected-warning {{too many parameters in the signature specified by the 'swift_name' attribute (expected 0; got 1)}}
7070

7171
+ (instancetype)trailingParen __attribute__((swift_name("foo("))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
7272
+ (instancetype)trailingColon:(int)value __attribute__((swift_name("foo(value)"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
@@ -90,16 +90,16 @@ struct __attribute__((swift_name("FooStruct"))) BarStruct {
9090
int global_int __attribute__((swift_name("GlobalInt")));
9191

9292
void foo1(int i) __attribute__((swift_name("foo"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
93-
void foo2(int i) __attribute__((swift_name("foo()"))); // expected-warning{{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
94-
void foo2(int i) __attribute__((swift_name("foo(a:b:)"))); // expected-warning{{too many parameters in 'swift_name' attribute (expected 1; got 2)}}
93+
void foo2(int i) __attribute__((swift_name("foo()"))); // expected-warning{{too few parameters in the signature specified by the 'swift_name' attribute (expected 1; got 0)}}
94+
void foo2(int i) __attribute__((swift_name("foo(a:b:)"))); // expected-warning{{too many parameters in the signature specified by the 'swift_name' attribute (expected 1; got 2)}}
9595
void foo3(int i, int j) __attribute__((swift_name("fooWithX(_:y:)"))); // okay
9696
void foo4(int i, int *error) __attribute__((swift_name("fooWithA(_:)"))); // okay
9797

9898
typedef int some_int_type __attribute__((swift_name("SomeInt")));
9999

100100
struct Point3D createPoint3D(float x, float y, float z) __attribute__((swift_name("Point3D.init(x:y:z:)")));
101101
struct Point3D rotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(self:radians:)")));
102-
struct Point3D badRotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(radians:)"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 2; got 1)}}
102+
struct Point3D badRotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(radians:)"))); // expected-warning {{too few parameters in the signature specified by the 'swift_name' attribute (expected 2; got 1)}}
103103

104104
extern struct Point3D identityPoint __attribute__((swift_name("Point3D.identity")));
105105

Diff for: clang/test/SemaObjC/attr-swift_name.m

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
2+
3+
#define SWIFT_NAME(name) __attribute__((__swift_name__(name)))
4+
#define SWIFT_ASYNC_NAME(name) __attribute__((__swift_async_name__(name)))
5+
6+
@protocol P
7+
@end
8+
9+
typedef int (^CallbackTy)(void);
10+
11+
@interface AsyncI<P>
12+
13+
- (void)doSomethingWithCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething()");
14+
- (void)doSomethingX:(int)x withCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething(x:)");
15+
16+
// expected-warning@+1 {{too many parameters in the signature specified by the '__swift_async_name__' attribute (expected 1; got 2)}}
17+
- (void)doSomethingY:(int)x withCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething(x:y:)");
18+
19+
// expected-warning@+1 {{too few parameters in the signature specified by the '__swift_async_name__' attribute (expected 1; got 0)}}
20+
- (void)doSomethingZ:(int)x withCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething()");
21+
22+
// expected-warning@+1 {{'__swift_async_name__' attribute cannot be applied to a method with no parameters}}
23+
- (void)doSomethingNone SWIFT_ASYNC_NAME("doSomething()");
24+
25+
// expected-error@+1 {{'__swift_async_name__' attribute takes one argument}}
26+
- (void)brokenAttr __attribute__((__swift_async_name__("brokenAttr", 2)));
27+
28+
@end
29+
30+
void asyncFunc(CallbackTy callback) SWIFT_ASYNC_NAME("asyncFunc()");
31+
32+
// expected-warning@+1 {{'__swift_async_name__' attribute cannot be applied to a function with no parameters}}
33+
void asyncNoParams(void) SWIFT_ASYNC_NAME("asyncNoParams()");
34+
35+
// expected-error@+1 {{'__swift_async_name__' attribute only applies to Objective-C methods and functions}}
36+
SWIFT_ASYNC_NAME("NoAsync")
37+
@protocol NoAsync @end

0 commit comments

Comments
 (0)