blob: a6604b7ff9582f12e08619e9b26a80fa5fe506b1 [file] [log] [blame]
Ted Kremenek28eace62013-11-23 01:01:34 +00001// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class
2
Ted Kremenekf41cf7f12013-12-10 19:43:48 +00003// Mark this protocol as requiring all of its methods and properties
4// to be explicitly implemented in the adopting class.
5__attribute__((objc_protocol_requires_explicit_implementation))
Ted Kremenek28eace62013-11-23 01:01:34 +00006@protocol Protocol
Ted Kremenek4b3c66e2014-03-05 08:13:08 +00007- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
Fariborz Jahanianc9b77152014-08-29 18:31:16 +00008@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
Ted Kremenek28eace62013-11-23 01:01:34 +00009@end
10
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000011// In this example, ClassA adopts the protocol. We won't
12// provide the implementation here, but this protocol will
13// be adopted later by a subclass.
Ted Kremenek28eace62013-11-23 01:01:34 +000014@interface ClassA <Protocol>
15- (void) theBestOfTimes;
Fariborz Jahanianc985a7f2014-10-10 22:08:23 +000016@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
Ted Kremenek28eace62013-11-23 01:01:34 +000017@end
18
Ted Kremenek4b3c66e2014-03-05 08:13:08 +000019// This class subclasses ClassA (which also adopts 'Protocol').
Ted Kremenek2ccf19e2013-12-13 05:58:51 +000020@interface ClassB : ClassA <Protocol>
Ted Kremenek28eace62013-11-23 01:01:34 +000021@end
22
Fariborz Jahanianc9b77152014-08-29 18:31:16 +000023@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
Ted Kremenek38882022014-02-21 19:41:39 +000024@end
25
26@interface ClassB_Good : ClassA <Protocol>
27@end
28
29@implementation ClassB_Good // no-warning
30- (void) theBestOfTimes {}
31@dynamic theWorstOfTimes;
Ted Kremenek28eace62013-11-23 01:01:34 +000032@end
33
Ted Kremenek204c3c52014-02-22 00:02:03 +000034@interface ClassB_AlsoGood : ClassA <Protocol>
Fariborz Jahanianc9b77152014-08-29 18:31:16 +000035@property (readonly) id theWorstOfTimes; // expected-warning {{auto property synthesis will not synthesize property 'theWorstOfTimes'; it will be implemented by its superclass}}
Ted Kremenek204c3c52014-02-22 00:02:03 +000036@end
37
38// Default synthesis acts as if @dynamic
39// had been written for 'theWorstOfTimes' because
40// it is declared in ClassA. This is okay, since
41// the author of ClassB_AlsoGood needs explicitly
42// write @property in the @interface.
Fariborz Jahanianc9b77152014-08-29 18:31:16 +000043@implementation ClassB_AlsoGood // expected-note {{detected while default synthesizing properties in class implementation}}
Ted Kremenek204c3c52014-02-22 00:02:03 +000044- (void) theBestOfTimes {}
45@end
46
Ted Kremenekc152c522013-12-12 06:20:42 +000047// Test that inherited protocols do not get the explicit conformance requirement.
48@protocol Inherited
49- (void) fairIsFoul;
50@end
51
52__attribute__((objc_protocol_requires_explicit_implementation))
53@protocol Derived <Inherited>
54- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}
55@end
56
57@interface ClassC <Inherited>
58@end
59
Ted Kremenek2ccf19e2013-12-13 05:58:51 +000060@interface ClassD : ClassC <Derived>
Ted Kremenekc152c522013-12-12 06:20:42 +000061@end
62
Ted Kremenek2ccf19e2013-12-13 05:58:51 +000063@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
Ted Kremenekc152c522013-12-12 06:20:42 +000064@end
65
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000066// Test that the attribute is used correctly.
67__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}}
68@protocol AnotherProtocol @end
Ted Kremenek28eace62013-11-23 01:01:34 +000069
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000070// Cannot put the attribute on classes or other non-protocol declarations.
71__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
72@interface AnotherClass @end
Ted Kremenek28eace62013-11-23 01:01:34 +000073
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000074__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
75int x;
Ted Kremenek28eace62013-11-23 01:01:34 +000076
Ted Kremenek33e430f2013-12-13 06:26:14 +000077// Test that inherited protocols with the attribute
78// are treated properly.
79__attribute__((objc_protocol_requires_explicit_implementation))
80@protocol ProtocolA
81@required
Ted Kremenek15478b32014-01-17 08:34:19 +000082- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
83- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
Ted Kremenek33e430f2013-12-13 06:26:14 +000084@end
85
86@protocol ProtocolB <ProtocolA>
87@required
88- (void)dunwich;
Ted Kremenek15478b32014-01-17 08:34:19 +000089- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}
90@end
91
92__attribute__((objc_protocol_requires_explicit_implementation))
93@protocol ProtocolB_Explicit <ProtocolA>
94@required
95- (void)dunwich;
96- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
Ted Kremenek33e430f2013-12-13 06:26:14 +000097@end
98
99@protocol ProtocolC
100@required
101- (void)rlyeh;
102- (void)innsmouth;
103- (void)dunwich;
104@end
105
Ted Kremenek15478b32014-01-17 08:34:19 +0000106@interface MyObject <ProtocolC> @end
Ted Kremenek33e430f2013-12-13 06:26:14 +0000107
Ted Kremenek15478b32014-01-17 08:34:19 +0000108// Provide two variants of a base class, one that adopts ProtocolA and
109// one that does not.
110@interface Lovecraft <ProtocolA> @end
111@interface Lovecraft_2 @end
Ted Kremenek33e430f2013-12-13 06:26:14 +0000112
Ted Kremenek15478b32014-01-17 08:34:19 +0000113// Provide two variants of a subclass that conform to ProtocolB. One
114// subclasses from a class that conforms to ProtocolA, the other that
115// does not.
116//
117// From those, provide two variants that conformat to ProtocolB_Explicit
118// instead.
119@interface Shoggoth : Lovecraft <ProtocolB> @end
120@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end
121@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end
122@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end
123
Ted Kremenek33e430f2013-12-13 06:26:14 +0000124@implementation MyObject
125- (void)innsmouth {}
126- (void)rlyeh {}
127- (void)dunwich {}
128@end
129
Ted Kremenek15478b32014-01-17 08:34:19 +0000130@implementation Lovecraft
Ted Kremenek33e430f2013-12-13 06:26:14 +0000131- (void)innsmouth {}
132- (void)rlyeh {}
133@end
134
Ted Kremenek15478b32014-01-17 08:34:19 +0000135@implementation Shoggoth
136- (void)dunwich {}
137@end
138
139@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\
140 // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
141 // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}}
142- (void)dunwich {}
143@end
144
145@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}
146- (void)dunwich {}
147@end
148
149@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\
150 // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
151 // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}}
Ted Kremenek33e430f2013-12-13 06:26:14 +0000152- (void)dunwich {}
153@end
154
Ted Kremenek294c0822014-02-27 01:28:58 +0000155// Categories adopting a protocol with explicit conformance need to implement that protocol.
156@interface Parent
157- (void) theBestOfTimes;
158@property (readonly) id theWorstOfTimes;
159@end
160
161@interface Derived : Parent
162@end
163
164@interface Derived (MyCat) <Protocol>
165@end
166
167@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
168@end
169
Ted Kremenek27cfe102014-02-21 22:49:04 +0000170__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error{{attribute 'objc_protocol_requires_explicit_implementation' can only be applied to @protocol definitions, not forward declarations}}
171@protocol NotDefined;
172
Ted Kremenek4b3c66e2014-03-05 08:13:08 +0000173// Another complete hierarchy.
174 __attribute__((objc_protocol_requires_explicit_implementation))
175@protocol Ex2FooBar
176- (void)methodA;
177@end
178
179 __attribute__((objc_protocol_requires_explicit_implementation))
180@protocol Ex2ProtocolA
Ted Kremenek760a2ac2014-03-05 23:18:22 +0000181- (void)methodB;
Ted Kremenek4b3c66e2014-03-05 08:13:08 +0000182@end
183
184 __attribute__((objc_protocol_requires_explicit_implementation))
185@protocol Ex2ProtocolB <Ex2ProtocolA>
186- (void)methodA; // expected-note {{method 'methodA' declared here}}
187@end
188
189// NOT required
190@protocol Ex2ProtocolC <Ex2ProtocolA>
191- (void)methodB;
192- (void)methodA;
193@end
194
195@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar>
196@end
197@implementation Ex2ClassA
198- (void)methodB {}
199- (void)methodA {}
200@end
201
202@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB>
203@end
204
Ted Kremenek760a2ac2014-03-05 23:18:22 +0000205@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}
Ted Kremenek4b3c66e2014-03-05 08:13:08 +0000206@end
Ted Kremenek294c0822014-02-27 01:28:58 +0000207