208 lines · plain
1// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class2 3// Mark this protocol as requiring all of its methods and properties4// to be explicitly implemented in the adopting class.5__attribute__((objc_protocol_requires_explicit_implementation))6@protocol Protocol7- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}8@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} 9@end10 11// In this example, ClassA adopts the protocol. We won't12// provide the implementation here, but this protocol will13// be adopted later by a subclass.14@interface ClassA <Protocol>15- (void) theBestOfTimes;16@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}17@end18 19// This class subclasses ClassA (which also adopts 'Protocol').20@interface ClassB : ClassA <Protocol>21@end22 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@end25 26@interface ClassB_Good : ClassA <Protocol>27@end28 29@implementation ClassB_Good // no-warning30- (void) theBestOfTimes {}31@dynamic theWorstOfTimes;32@end33 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@end37 38// Default synthesis acts as if @dynamic39// had been written for 'theWorstOfTimes' because40// it is declared in ClassA. This is okay, since41// the author of ClassB_AlsoGood needs explicitly42// write @property in the @interface.43@implementation ClassB_AlsoGood // expected-note {{detected while default synthesizing properties in class implementation}}44- (void) theBestOfTimes {}45@end46 47// Test that inherited protocols do not get the explicit conformance requirement.48@protocol Inherited49- (void) fairIsFoul;50@end51 52__attribute__((objc_protocol_requires_explicit_implementation))53@protocol Derived <Inherited>54- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}55@end56 57@interface ClassC <Inherited>58@end59 60@interface ClassD : ClassC <Derived>61@end62 63@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}64@end65 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 @end69 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 @end73 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 attribute78// are treated properly.79__attribute__((objc_protocol_requires_explicit_implementation))80@protocol ProtocolA81@required82- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}83- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}84@end85 86@protocol ProtocolB <ProtocolA>87@required88- (void)dunwich;89- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}90@end91 92__attribute__((objc_protocol_requires_explicit_implementation))93@protocol ProtocolB_Explicit <ProtocolA>94@required95- (void)dunwich;96- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}97@end98 99@protocol ProtocolC100@required101- (void)rlyeh;102- (void)innsmouth;103- (void)dunwich;104@end105 106@interface MyObject <ProtocolC> @end107 108// Provide two variants of a base class, one that adopts ProtocolA and109// one that does not.110@interface Lovecraft <ProtocolA> @end111@interface Lovecraft_2 @end112 113// Provide two variants of a subclass that conform to ProtocolB. One114// subclasses from a class that conforms to ProtocolA, the other that115// does not.116//117// From those, provide two variants that conformat to ProtocolB_Explicit118// instead.119@interface Shoggoth : Lovecraft <ProtocolB> @end120@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end121@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end122@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end123 124@implementation MyObject125- (void)innsmouth {}126- (void)rlyeh {}127- (void)dunwich {}128@end129 130@implementation Lovecraft131- (void)innsmouth {}132- (void)rlyeh {}133@end134 135@implementation Shoggoth136- (void)dunwich {}137@end138 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@end144 145@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}146- (void)dunwich {}147@end148 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@end154 155// Categories adopting a protocol with explicit conformance need to implement that protocol.156@interface Parent157- (void) theBestOfTimes;158@property (readonly) id theWorstOfTimes;159@end160 161@interface Derived : Parent162@end163 164@interface Derived (MyCat) <Protocol>165@end166 167@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}168@end169 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 Ex2FooBar176- (void)methodA;177@end178 179 __attribute__((objc_protocol_requires_explicit_implementation))180@protocol Ex2ProtocolA181- (void)methodB;182@end183 184 __attribute__((objc_protocol_requires_explicit_implementation))185@protocol Ex2ProtocolB <Ex2ProtocolA>186- (void)methodA; // expected-note {{method 'methodA' declared here}}187@end188 189// NOT required190@protocol Ex2ProtocolC <Ex2ProtocolA>191- (void)methodB;192- (void)methodA;193@end194 195@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar>196@end197@implementation Ex2ClassA198- (void)methodB {}199- (void)methodA {}200@end201 202@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB>203@end204 205@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}206@end207 208