blob: 460b78fff37bba9a7b73bcd2e13d8b51f93df446 [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 Kremenek294c0822014-02-27 01:28:58 +00007- (void) theBestOfTimes; // expected-note 2 {{method 'theBestOfTimes' declared here}}
Ted Kremenek38882022014-02-21 19:41:39 +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;
Ted Kremenek28eace62013-11-23 01:01:34 +000016@property (readonly) id theWorstOfTimes;
17@end
18
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000019// This class subclasses ClassA (which adopts 'Protocol'),
20// but does not provide the needed implementation.
Ted Kremenek2ccf19e2013-12-13 05:58:51 +000021@interface ClassB : ClassA <Protocol>
Ted Kremenek28eace62013-11-23 01:01:34 +000022@end
23
Ted Kremenek38882022014-02-21 19:41:39 +000024@implementation ClassB // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}} expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
25@end
26
27@interface ClassB_Good : ClassA <Protocol>
28@end
29
30@implementation ClassB_Good // no-warning
31- (void) theBestOfTimes {}
32@dynamic theWorstOfTimes;
Ted Kremenek28eace62013-11-23 01:01:34 +000033@end
34
Ted Kremenek204c3c52014-02-22 00:02:03 +000035@interface ClassB_AlsoGood : ClassA <Protocol>
36@property (readonly) id theWorstOfTimes;
37@end
38
39// Default synthesis acts as if @dynamic
40// had been written for 'theWorstOfTimes' because
41// it is declared in ClassA. This is okay, since
42// the author of ClassB_AlsoGood needs explicitly
43// write @property in the @interface.
44@implementation ClassB_AlsoGood // no-warning
45- (void) theBestOfTimes {}
46@end
47
Ted Kremenekc152c522013-12-12 06:20:42 +000048// Test that inherited protocols do not get the explicit conformance requirement.
49@protocol Inherited
50- (void) fairIsFoul;
51@end
52
53__attribute__((objc_protocol_requires_explicit_implementation))
54@protocol Derived <Inherited>
55- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}
56@end
57
58@interface ClassC <Inherited>
59@end
60
Ted Kremenek2ccf19e2013-12-13 05:58:51 +000061@interface ClassD : ClassC <Derived>
Ted Kremenekc152c522013-12-12 06:20:42 +000062@end
63
Ted Kremenek2ccf19e2013-12-13 05:58:51 +000064@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
Ted Kremenekc152c522013-12-12 06:20:42 +000065@end
66
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000067// Test that the attribute is used correctly.
68__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}}
69@protocol AnotherProtocol @end
Ted Kremenek28eace62013-11-23 01:01:34 +000070
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000071// Cannot put the attribute on classes or other non-protocol declarations.
72__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
73@interface AnotherClass @end
Ted Kremenek28eace62013-11-23 01:01:34 +000074
Ted Kremenekf41cf7f12013-12-10 19:43:48 +000075__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
76int x;
Ted Kremenek28eace62013-11-23 01:01:34 +000077
Ted Kremenek33e430f2013-12-13 06:26:14 +000078// Test that inherited protocols with the attribute
79// are treated properly.
80__attribute__((objc_protocol_requires_explicit_implementation))
81@protocol ProtocolA
82@required
Ted Kremenek15478b32014-01-17 08:34:19 +000083- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
84- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
Ted Kremenek33e430f2013-12-13 06:26:14 +000085@end
86
87@protocol ProtocolB <ProtocolA>
88@required
89- (void)dunwich;
Ted Kremenek15478b32014-01-17 08:34:19 +000090- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}
91@end
92
93__attribute__((objc_protocol_requires_explicit_implementation))
94@protocol ProtocolB_Explicit <ProtocolA>
95@required
96- (void)dunwich;
97- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
Ted Kremenek33e430f2013-12-13 06:26:14 +000098@end
99
100@protocol ProtocolC
101@required
102- (void)rlyeh;
103- (void)innsmouth;
104- (void)dunwich;
105@end
106
Ted Kremenek15478b32014-01-17 08:34:19 +0000107@interface MyObject <ProtocolC> @end
Ted Kremenek33e430f2013-12-13 06:26:14 +0000108
Ted Kremenek15478b32014-01-17 08:34:19 +0000109// Provide two variants of a base class, one that adopts ProtocolA and
110// one that does not.
111@interface Lovecraft <ProtocolA> @end
112@interface Lovecraft_2 @end
Ted Kremenek33e430f2013-12-13 06:26:14 +0000113
Ted Kremenek15478b32014-01-17 08:34:19 +0000114// Provide two variants of a subclass that conform to ProtocolB. One
115// subclasses from a class that conforms to ProtocolA, the other that
116// does not.
117//
118// From those, provide two variants that conformat to ProtocolB_Explicit
119// instead.
120@interface Shoggoth : Lovecraft <ProtocolB> @end
121@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end
122@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end
123@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end
124
Ted Kremenek33e430f2013-12-13 06:26:14 +0000125@implementation MyObject
126- (void)innsmouth {}
127- (void)rlyeh {}
128- (void)dunwich {}
129@end
130
Ted Kremenek15478b32014-01-17 08:34:19 +0000131@implementation Lovecraft
Ted Kremenek33e430f2013-12-13 06:26:14 +0000132- (void)innsmouth {}
133- (void)rlyeh {}
134@end
135
Ted Kremenek15478b32014-01-17 08:34:19 +0000136@implementation Shoggoth
137- (void)dunwich {}
138@end
139
140@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\
141 // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
142 // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}}
143- (void)dunwich {}
144@end
145
146@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}
147- (void)dunwich {}
148@end
149
150@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\
151 // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
152 // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}}
Ted Kremenek33e430f2013-12-13 06:26:14 +0000153- (void)dunwich {}
154@end
155
Ted Kremenek294c0822014-02-27 01:28:58 +0000156// Categories adopting a protocol with explicit conformance need to implement that protocol.
157@interface Parent
158- (void) theBestOfTimes;
159@property (readonly) id theWorstOfTimes;
160@end
161
162@interface Derived : Parent
163@end
164
165@interface Derived (MyCat) <Protocol>
166@end
167
168@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
169@end
170
Ted Kremenek27cfe102014-02-21 22:49:04 +0000171__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error{{attribute 'objc_protocol_requires_explicit_implementation' can only be applied to @protocol definitions, not forward declarations}}
172@protocol NotDefined;
173
Ted Kremenek294c0822014-02-27 01:28:58 +0000174