xref: /llvm-project/clang/test/SemaObjC/method-direct.m (revision 20d704a75ed51c7a9a155aa3978d0c02671c3f69)
1// RUN: %clang_cc1 -fsyntax-only -verify -Wselector-type-mismatch %s
2
3@protocol Proto
4- (void)protoMethod;      // expected-note {{previous declaration is here}}
5+ (void)classProtoMethod; // expected-note {{previous declaration is here}}
6@end
7
8@protocol ProtoDirectFail
9- (void)protoMethod __attribute__((objc_direct));      // expected-error {{'objc_direct' attribute cannot be applied to methods declared in an Objective-C protocol}}
10+ (void)classProtoMethod __attribute__((objc_direct)); // expected-error {{'objc_direct' attribute cannot be applied to methods declared in an Objective-C protocol}}
11@end
12
13__attribute__((objc_root_class))
14@interface Root
15- (void)unavailableInChild;
16- (void)rootRegular;                                  // expected-note {{previous declaration is here}}
17+ (void)classRootRegular;                             // expected-note {{previous declaration is here}}
18- (void)rootDirect __attribute__((objc_direct));      // expected-note {{previous declaration is here}};
19+ (void)classRootDirect __attribute__((objc_direct)); // expected-note {{previous declaration is here}};
20- (void)otherRootDirect __attribute__((objc_direct)); // expected-note {{direct method 'otherRootDirect' declared here}}
21+ (void)otherClassRootDirect __attribute__((objc_direct)); // expected-note {{direct method 'otherClassRootDirect' declared here}}
22+ (void)otherOtherClassRootDirect __attribute__((objc_direct)); // expected-note {{direct method 'otherOtherClassRootDirect' declared here}}
23- (void)notDirectInIface;                             // expected-note {{previous declaration is here}}
24+ (void)classNotDirectInIface;                        // expected-note {{previous declaration is here}}
25@end
26
27__attribute__((objc_direct_members))
28@interface Root ()
29- (void)rootExtensionDirect;      // expected-note {{previous declaration is here}}
30+ (void)classRootExtensionDirect; // expected-note {{previous declaration is here}}
31@end
32
33__attribute__((objc_direct_members))
34@interface Root(Direct)
35- (void)rootCategoryDirect;      // expected-note {{previous declaration is here}}
36+ (void)classRootCategoryDirect; // expected-note {{previous declaration is here}}
37@end
38
39@interface Root ()
40- (void)rootExtensionRegular;                                   // expected-note {{previous declaration is here}}
41+ (void)classRootExtensionRegular;                              // expected-note {{previous declaration is here}}
42- (void)rootExtensionDirect2 __attribute__((objc_direct));      // expected-note {{previous declaration is here}}
43+ (void)classRootExtensionDirect2 __attribute__((objc_direct)); // expected-note {{previous declaration is here}}
44@end
45
46@interface Root (Direct2)
47- (void)rootCategoryRegular;                                   // expected-note {{previous declaration is here}}
48+ (void)classRootCategoryRegular;                              // expected-note {{previous declaration is here}}
49- (void)rootCategoryDirect2 __attribute__((objc_direct));      // expected-note {{previous declaration is here}}
50+ (void)classRootCategoryDirect2 __attribute__((objc_direct)); // expected-note {{previous declaration is here}}
51@end
52
53__attribute__((objc_direct_members))
54@interface SubDirectMembers : Root
55@property int foo; // expected-note {{previous declaration is here}}
56- (void)unavailableInChild __attribute__((unavailable)); // should not warn
57- (instancetype)init;
58@end
59
60@interface Sub : Root <Proto>
61/* invalid overrides with directs */
62- (void)rootRegular __attribute__((objc_direct));               // expected-error {{methods that override superclass methods cannot be direct}}
63+ (void)classRootRegular __attribute__((objc_direct));          // expected-error {{methods that override superclass methods cannot be direct}}
64- (void)protoMethod __attribute__((objc_direct));               // expected-error {{methods that implement protocol requirements cannot be direct}}
65+ (void)classProtoMethod __attribute__((objc_direct));          // expected-error {{methods that implement protocol requirements cannot be direct}}
66- (void)rootExtensionRegular __attribute__((objc_direct));      // expected-error {{methods that override superclass methods cannot be direct}}
67+ (void)classRootExtensionRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
68- (void)rootCategoryRegular __attribute__((objc_direct));       // expected-error {{methods that override superclass methods cannot be direct}}
69+ (void)classRootCategoryRegular __attribute__((objc_direct));  // expected-error {{methods that override superclass methods cannot be direct}}
70
71/* invalid overrides of directs */
72- (void)rootDirect;                // expected-error {{cannot override a method that is declared direct by a superclass}}
73+ (void)classRootDirect;           // expected-error {{cannot override a method that is declared direct by a superclass}}
74- (void)rootExtensionDirect;       // expected-error {{cannot override a method that is declared direct by a superclass}}
75+ (void)classRootExtensionDirect;  // expected-error {{cannot override a method that is declared direct by a superclass}}
76- (void)rootExtensionDirect2;      // expected-error {{cannot override a method that is declared direct by a superclass}}
77+ (void)classRootExtensionDirect2; // expected-error {{cannot override a method that is declared direct by a superclass}}
78- (void)rootCategoryDirect;        // expected-error {{cannot override a method that is declared direct by a superclass}}
79+ (void)classRootCategoryDirect;   // expected-error {{cannot override a method that is declared direct by a superclass}}
80- (void)rootCategoryDirect2;       // expected-error {{cannot override a method that is declared direct by a superclass}}
81+ (void)classRootCategoryDirect2;  // expected-error {{cannot override a method that is declared direct by a superclass}}
82@end
83
84__attribute__((objc_direct_members))
85@implementation Root
86- (void)unavailableInChild {
87}
88- (void)rootRegular {
89}
90+ (void)classRootRegular {
91}
92- (void)rootDirect {
93}
94+ (void)classRootDirect {
95}
96- (void)otherRootDirect {
97}
98+ (void)someRootDirectMethod { // expected-note {{direct method 'someRootDirectMethod' declared here}}
99}
100+ (void)otherClassRootDirect {
101  [self someRootDirectMethod]; // expected-error {{messaging a Class with a method that is possibly direct}}
102}
103+ (void)otherOtherClassRootDirect {
104}
105- (void)rootExtensionDirect {
106}
107+ (void)classRootExtensionDirect {
108}
109- (void)rootExtensionRegular {
110}
111+ (void)classRootExtensionRegular {
112}
113- (void)rootExtensionDirect2 {
114}
115+ (void)classRootExtensionDirect2 {
116}
117- (void)notDirectInIface __attribute__((objc_direct)) // expected-error {{direct method implementation was previously declared not direct}}
118{
119}
120+ (void)classNotDirectInIface __attribute__((objc_direct)) // expected-error {{direct method implementation was previously declared not direct}}
121{
122}
123- (void)direct1 { // expected-note {{direct method 'direct1' declared here}}
124}
125- (void)direct2 { // expected-note {{direct method 'direct2' declared here}}
126}
127@end
128
129@interface Foo : Root
130- (id)directMismatch1; // expected-note {{using}}
131- (id)directMismatch2; // expected-note {{method 'directMismatch2' declared here}}
132@end
133
134@interface Bar : Root
135- (void)directMismatch1 __attribute__((objc_direct)); // expected-note {{also found}}
136- (void)directMismatch2 __attribute__((objc_direct)); // expected-note {{method 'directMismatch2' declared here}}
137@end
138
139@interface ValidSub : Root
140@end
141
142@implementation ValidSub
143- (void)someValidSubMethod {
144  [super otherRootDirect]; // expected-error {{messaging super with a direct method}}
145}
146+ (void)someValidSubMethod {
147  [super otherOtherClassRootDirect]; // expected-error {{messaging super with a direct method}}
148}
149@end
150
151@implementation SubDirectMembers
152@dynamic foo; // expected-error {{direct property cannot be @dynamic}}
153- (instancetype)init {
154  return self;
155}
156@end
157
158extern void callMethod(id obj, Class cls);
159extern void useSel(SEL sel);
160
161void callMethod(id obj, Class cls) {
162  [Root otherClassRootDirect];
163  [cls otherClassRootDirect]; // expected-error {{messaging a Class with a method that is possibly direct}}
164  [obj direct1];              // expected-error {{messaging unqualified id with a method that is possibly direct}}
165  [(Root *)obj direct1];
166  [obj directMismatch1];              // expected-warning {{multiple methods named 'directMismatch1' found}}
167  useSel(@selector(direct2));         // expected-error {{@selector expression formed with direct selector 'direct2'}}
168  useSel(@selector(directMismatch2)); // expected-warning {{several methods with selector 'directMismatch2' of mismatched types are found for the @selector expression}}
169}
170