1*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class 2*67e74705SXin Li 3*67e74705SXin Li// Mark this protocol as requiring all of its methods and properties 4*67e74705SXin Li// to be explicitly implemented in the adopting class. 5*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) 6*67e74705SXin Li@protocol Protocol 7*67e74705SXin Li- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}} 8*67e74705SXin Li@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} 9*67e74705SXin Li@end 10*67e74705SXin Li 11*67e74705SXin Li// In this example, ClassA adopts the protocol. We won't 12*67e74705SXin Li// provide the implementation here, but this protocol will 13*67e74705SXin Li// be adopted later by a subclass. 14*67e74705SXin Li@interface ClassA <Protocol> 15*67e74705SXin Li- (void) theBestOfTimes; 16*67e74705SXin Li@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} 17*67e74705SXin Li@end 18*67e74705SXin Li 19*67e74705SXin Li// This class subclasses ClassA (which also adopts 'Protocol'). 20*67e74705SXin Li@interface ClassB : ClassA <Protocol> 21*67e74705SXin Li@end 22*67e74705SXin Li 23*67e74705SXin Li@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*67e74705SXin Li@end 25*67e74705SXin Li 26*67e74705SXin Li@interface ClassB_Good : ClassA <Protocol> 27*67e74705SXin Li@end 28*67e74705SXin Li 29*67e74705SXin Li@implementation ClassB_Good // no-warning 30*67e74705SXin Li- (void) theBestOfTimes {} 31*67e74705SXin Li@dynamic theWorstOfTimes; 32*67e74705SXin Li@end 33*67e74705SXin Li 34*67e74705SXin Li@interface ClassB_AlsoGood : ClassA <Protocol> 35*67e74705SXin Li@property (readonly) id theWorstOfTimes; // expected-warning {{auto property synthesis will not synthesize property 'theWorstOfTimes'; it will be implemented by its superclass}} 36*67e74705SXin Li@end 37*67e74705SXin Li 38*67e74705SXin Li// Default synthesis acts as if @dynamic 39*67e74705SXin Li// had been written for 'theWorstOfTimes' because 40*67e74705SXin Li// it is declared in ClassA. This is okay, since 41*67e74705SXin Li// the author of ClassB_AlsoGood needs explicitly 42*67e74705SXin Li// write @property in the @interface. 43*67e74705SXin Li@implementation ClassB_AlsoGood // expected-note {{detected while default synthesizing properties in class implementation}} 44*67e74705SXin Li- (void) theBestOfTimes {} 45*67e74705SXin Li@end 46*67e74705SXin Li 47*67e74705SXin Li// Test that inherited protocols do not get the explicit conformance requirement. 48*67e74705SXin Li@protocol Inherited 49*67e74705SXin Li- (void) fairIsFoul; 50*67e74705SXin Li@end 51*67e74705SXin Li 52*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) 53*67e74705SXin Li@protocol Derived <Inherited> 54*67e74705SXin Li- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}} 55*67e74705SXin Li@end 56*67e74705SXin Li 57*67e74705SXin Li@interface ClassC <Inherited> 58*67e74705SXin Li@end 59*67e74705SXin Li 60*67e74705SXin Li@interface ClassD : ClassC <Derived> 61*67e74705SXin Li@end 62*67e74705SXin Li 63*67e74705SXin Li@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}} 64*67e74705SXin Li@end 65*67e74705SXin Li 66*67e74705SXin Li// Test that the attribute is used correctly. 67*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}} 68*67e74705SXin Li@protocol AnotherProtocol @end 69*67e74705SXin Li 70*67e74705SXin Li// Cannot put the attribute on classes or other non-protocol declarations. 71*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}} 72*67e74705SXin Li@interface AnotherClass @end 73*67e74705SXin Li 74*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}} 75*67e74705SXin Liint x; 76*67e74705SXin Li 77*67e74705SXin Li// Test that inherited protocols with the attribute 78*67e74705SXin Li// are treated properly. 79*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) 80*67e74705SXin Li@protocol ProtocolA 81*67e74705SXin Li@required 82*67e74705SXin Li- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}} 83*67e74705SXin Li- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}} 84*67e74705SXin Li@end 85*67e74705SXin Li 86*67e74705SXin Li@protocol ProtocolB <ProtocolA> 87*67e74705SXin Li@required 88*67e74705SXin Li- (void)dunwich; 89*67e74705SXin Li- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}} 90*67e74705SXin Li@end 91*67e74705SXin Li 92*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) 93*67e74705SXin Li@protocol ProtocolB_Explicit <ProtocolA> 94*67e74705SXin Li@required 95*67e74705SXin Li- (void)dunwich; 96*67e74705SXin Li- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}} 97*67e74705SXin Li@end 98*67e74705SXin Li 99*67e74705SXin Li@protocol ProtocolC 100*67e74705SXin Li@required 101*67e74705SXin Li- (void)rlyeh; 102*67e74705SXin Li- (void)innsmouth; 103*67e74705SXin Li- (void)dunwich; 104*67e74705SXin Li@end 105*67e74705SXin Li 106*67e74705SXin Li@interface MyObject <ProtocolC> @end 107*67e74705SXin Li 108*67e74705SXin Li// Provide two variants of a base class, one that adopts ProtocolA and 109*67e74705SXin Li// one that does not. 110*67e74705SXin Li@interface Lovecraft <ProtocolA> @end 111*67e74705SXin Li@interface Lovecraft_2 @end 112*67e74705SXin Li 113*67e74705SXin Li// Provide two variants of a subclass that conform to ProtocolB. One 114*67e74705SXin Li// subclasses from a class that conforms to ProtocolA, the other that 115*67e74705SXin Li// does not. 116*67e74705SXin Li// 117*67e74705SXin Li// From those, provide two variants that conformat to ProtocolB_Explicit 118*67e74705SXin Li// instead. 119*67e74705SXin Li@interface Shoggoth : Lovecraft <ProtocolB> @end 120*67e74705SXin Li@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end 121*67e74705SXin Li@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end 122*67e74705SXin Li@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end 123*67e74705SXin Li 124*67e74705SXin Li@implementation MyObject 125*67e74705SXin Li- (void)innsmouth {} 126*67e74705SXin Li- (void)rlyeh {} 127*67e74705SXin Li- (void)dunwich {} 128*67e74705SXin Li@end 129*67e74705SXin Li 130*67e74705SXin Li@implementation Lovecraft 131*67e74705SXin Li- (void)innsmouth {} 132*67e74705SXin Li- (void)rlyeh {} 133*67e74705SXin Li@end 134*67e74705SXin Li 135*67e74705SXin Li@implementation Shoggoth 136*67e74705SXin Li- (void)dunwich {} 137*67e74705SXin Li@end 138*67e74705SXin Li 139*67e74705SXin Li@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\ 140*67e74705SXin Li // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\ 141*67e74705SXin Li // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}} 142*67e74705SXin Li- (void)dunwich {} 143*67e74705SXin Li@end 144*67e74705SXin Li 145*67e74705SXin Li@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}} 146*67e74705SXin Li- (void)dunwich {} 147*67e74705SXin Li@end 148*67e74705SXin Li 149*67e74705SXin Li@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\ 150*67e74705SXin Li // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\ 151*67e74705SXin Li // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}} 152*67e74705SXin Li- (void)dunwich {} 153*67e74705SXin Li@end 154*67e74705SXin Li 155*67e74705SXin Li// Categories adopting a protocol with explicit conformance need to implement that protocol. 156*67e74705SXin Li@interface Parent 157*67e74705SXin Li- (void) theBestOfTimes; 158*67e74705SXin Li@property (readonly) id theWorstOfTimes; 159*67e74705SXin Li@end 160*67e74705SXin Li 161*67e74705SXin Li@interface Derived : Parent 162*67e74705SXin Li@end 163*67e74705SXin Li 164*67e74705SXin Li@interface Derived (MyCat) <Protocol> 165*67e74705SXin Li@end 166*67e74705SXin Li 167*67e74705SXin Li@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}} 168*67e74705SXin Li@end 169*67e74705SXin Li 170*67e74705SXin Li__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*67e74705SXin Li@protocol NotDefined; 172*67e74705SXin Li 173*67e74705SXin Li// Another complete hierarchy. 174*67e74705SXin Li __attribute__((objc_protocol_requires_explicit_implementation)) 175*67e74705SXin Li@protocol Ex2FooBar 176*67e74705SXin Li- (void)methodA; 177*67e74705SXin Li@end 178*67e74705SXin Li 179*67e74705SXin Li __attribute__((objc_protocol_requires_explicit_implementation)) 180*67e74705SXin Li@protocol Ex2ProtocolA 181*67e74705SXin Li- (void)methodB; 182*67e74705SXin Li@end 183*67e74705SXin Li 184*67e74705SXin Li __attribute__((objc_protocol_requires_explicit_implementation)) 185*67e74705SXin Li@protocol Ex2ProtocolB <Ex2ProtocolA> 186*67e74705SXin Li- (void)methodA; // expected-note {{method 'methodA' declared here}} 187*67e74705SXin Li@end 188*67e74705SXin Li 189*67e74705SXin Li// NOT required 190*67e74705SXin Li@protocol Ex2ProtocolC <Ex2ProtocolA> 191*67e74705SXin Li- (void)methodB; 192*67e74705SXin Li- (void)methodA; 193*67e74705SXin Li@end 194*67e74705SXin Li 195*67e74705SXin Li@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar> 196*67e74705SXin Li@end 197*67e74705SXin Li@implementation Ex2ClassA 198*67e74705SXin Li- (void)methodB {} 199*67e74705SXin Li- (void)methodA {} 200*67e74705SXin Li@end 201*67e74705SXin Li 202*67e74705SXin Li@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB> 203*67e74705SXin Li@end 204*67e74705SXin Li 205*67e74705SXin Li@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}} 206*67e74705SXin Li@end 207*67e74705SXin Li 208