1// RUN: %clang_cc1  -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class
2
3// 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))
6@protocol Protocol
7- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
8@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
9@end
10
11// 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.
14@interface ClassA <Protocol>
15- (void) theBestOfTimes;
16@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
17@end
18
19// This class subclasses ClassA (which also adopts 'Protocol').
20@interface ClassB : ClassA <Protocol>
21@end
22
23@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
24@end
25
26@interface ClassB_Good : ClassA <Protocol>
27@end
28
29@implementation ClassB_Good // no-warning
30- (void) theBestOfTimes {}
31@dynamic theWorstOfTimes;
32@end
33
34@interface ClassB_AlsoGood : ClassA <Protocol>
35@property (readonly) id theWorstOfTimes; // expected-warning {{auto property synthesis will not synthesize property 'theWorstOfTimes'; it will be implemented by its superclass}}
36@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.
43@implementation ClassB_AlsoGood  // expected-note {{detected while default synthesizing properties in class implementation}}
44- (void) theBestOfTimes {}
45@end
46
47// 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
60@interface ClassD : ClassC <Derived>
61@end
62
63@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
64@end
65
66// 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
69
70// 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
73
74__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
75int x;
76
77// Test that inherited protocols with the attribute
78// are treated properly.
79__attribute__((objc_protocol_requires_explicit_implementation))
80@protocol ProtocolA
81@required
82- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
83- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
84@end
85
86@protocol ProtocolB <ProtocolA>
87@required
88- (void)dunwich;
89- (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}}
97@end
98
99@protocol ProtocolC
100@required
101- (void)rlyeh;
102- (void)innsmouth;
103- (void)dunwich;
104@end
105
106@interface MyObject <ProtocolC> @end
107
108// 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
112
113// 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
124@implementation MyObject
125- (void)innsmouth {}
126- (void)rlyeh {}
127- (void)dunwich {}
128@end
129
130@implementation Lovecraft
131- (void)innsmouth {}
132- (void)rlyeh {}
133@end
134
135@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}}
152- (void)dunwich {}
153@end
154
155// 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
170__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
173// 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
181- (void)methodB;
182@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
205@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}
206@end
207
208