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