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