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; 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; 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 // no-warning 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}} 75 int 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