1 // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class
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))
7 - (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
8 @property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
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}}
19 // This class subclasses ClassA (which also adopts 'Protocol').
20 @interface ClassB : ClassA <Protocol>
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}}
26 @interface ClassB_Good : ClassA <Protocol>
29 @implementation ClassB_Good // no-warning
30 - (void) theBestOfTimes {}
31 @dynamic theWorstOfTimes;
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}}
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 {}
47 // Test that inherited protocols do not get the explicit conformance requirement.
52 __attribute__((objc_protocol_requires_explicit_implementation))
53 @protocol Derived <Inherited>
54 - (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}
57 @interface ClassC <Inherited>
60 @interface ClassD : ClassC <Derived>
63 @implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
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
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
74 __attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
77 // Test that inherited protocols with the attribute
78 // are treated properly.
79 __attribute__((objc_protocol_requires_explicit_implementation))
82 - (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
83 - (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
86 @protocol ProtocolB <ProtocolA>
89 - (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}
92 __attribute__((objc_protocol_requires_explicit_implementation))
93 @protocol ProtocolB_Explicit <ProtocolA>
96 - (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
106 @interface MyObject <ProtocolC> @end
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
113 // Provide two variants of a subclass that conform to ProtocolB. One
114 // subclasses from a class that conforms to ProtocolA, the other that
117 // From those, provide two variants that conformat to ProtocolB_Explicit
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
124 @implementation MyObject
130 @implementation Lovecraft
135 @implementation Shoggoth
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}}
145 @implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}
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}}
155 // Categories adopting a protocol with explicit conformance need to implement that protocol.
157 - (void) theBestOfTimes;
158 @property (readonly) id theWorstOfTimes;
161 @interface Derived : Parent
164 @interface Derived (MyCat) <Protocol>
167 @implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
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;
173 // Another complete hierarchy.
174 __attribute__((objc_protocol_requires_explicit_implementation))
179 __attribute__((objc_protocol_requires_explicit_implementation))
180 @protocol Ex2ProtocolA
184 __attribute__((objc_protocol_requires_explicit_implementation))
185 @protocol Ex2ProtocolB <Ex2ProtocolA>
186 - (void)methodA; // expected-note {{method 'methodA' declared here}}
190 @protocol Ex2ProtocolC <Ex2ProtocolA>
195 @interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar>
197 @implementation Ex2ClassA
202 @interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB>
205 @implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}