reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
// RUN: %clang_cc1  -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class

// Mark this protocol as requiring all of its methods and properties
// to be explicitly implemented in the adopting class.
__attribute__((objc_protocol_requires_explicit_implementation))
@protocol Protocol
- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} 
@end

// In this example, ClassA adopts the protocol.  We won't
// provide the implementation here, but this protocol will
// be adopted later by a subclass.
@interface ClassA <Protocol>
- (void) theBestOfTimes;
@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
@end

// This class subclasses ClassA (which also adopts 'Protocol').
@interface ClassB : ClassA <Protocol>
@end

@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}} 
@end

@interface ClassB_Good : ClassA <Protocol>
@end

@implementation ClassB_Good // no-warning
- (void) theBestOfTimes {}
@dynamic theWorstOfTimes;
@end

@interface ClassB_AlsoGood : ClassA <Protocol>
@property (readonly) id theWorstOfTimes; // expected-warning {{auto property synthesis will not synthesize property 'theWorstOfTimes'; it will be implemented by its superclass}}
@end

// Default synthesis acts as if @dynamic
// had been written for 'theWorstOfTimes' because
// it is declared in ClassA.  This is okay, since
// the author of ClassB_AlsoGood needs explicitly
// write @property in the @interface.
@implementation ClassB_AlsoGood  // expected-note {{detected while default synthesizing properties in class implementation}}
- (void) theBestOfTimes {}
@end

// Test that inherited protocols do not get the explicit conformance requirement.
@protocol Inherited
- (void) fairIsFoul;
@end

__attribute__((objc_protocol_requires_explicit_implementation))
@protocol Derived <Inherited>
- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}
@end

@interface ClassC <Inherited>
@end

@interface ClassD : ClassC <Derived>
@end

@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
@end

// Test that the attribute is used correctly.
__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}}
@protocol AnotherProtocol @end

// Cannot put the attribute on classes or other non-protocol declarations.
__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
@interface AnotherClass @end

__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
int x;

// Test that inherited protocols with the attribute
// are treated properly.
__attribute__((objc_protocol_requires_explicit_implementation))
@protocol ProtocolA
@required
- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
@end

@protocol ProtocolB <ProtocolA>
@required
- (void)dunwich;
- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}
@end

__attribute__((objc_protocol_requires_explicit_implementation))
@protocol ProtocolB_Explicit <ProtocolA>
@required
- (void)dunwich;
- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
@end

@protocol ProtocolC
@required
- (void)rlyeh;
- (void)innsmouth;
- (void)dunwich;
@end

@interface MyObject <ProtocolC> @end

// Provide two variants of a base class, one that adopts ProtocolA and
// one that does not.
@interface Lovecraft <ProtocolA> @end
@interface Lovecraft_2 @end

// Provide two variants of a subclass that conform to ProtocolB.  One
// subclasses from a class that conforms to ProtocolA, the other that
// does not.
//
// From those, provide two variants that conformat to ProtocolB_Explicit
// instead.
@interface Shoggoth : Lovecraft <ProtocolB> @end
@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end
@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end
@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end

@implementation MyObject
- (void)innsmouth {}
- (void)rlyeh {}
- (void)dunwich {}
@end

@implementation Lovecraft
- (void)innsmouth {}
- (void)rlyeh {}
@end

@implementation Shoggoth
- (void)dunwich {}
@end

@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\
                           // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
                           // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}} 
- (void)dunwich {}
@end

@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}
- (void)dunwich {}
@end

@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\
                                    // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
                                    // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}}
- (void)dunwich {}
@end

// Categories adopting a protocol with explicit conformance need to implement that protocol.
@interface Parent
- (void) theBestOfTimes;
@property (readonly) id theWorstOfTimes;
@end

@interface Derived : Parent
@end

@interface Derived (MyCat) <Protocol>
@end

@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
@end

__attribute__((objc_protocol_requires_explicit_implementation))  // expected-error{{attribute 'objc_protocol_requires_explicit_implementation' can only be applied to @protocol definitions, not forward declarations}}
@protocol NotDefined;

// Another complete hierarchy.
 __attribute__((objc_protocol_requires_explicit_implementation))
@protocol Ex2FooBar
- (void)methodA;
@end

 __attribute__((objc_protocol_requires_explicit_implementation))
@protocol Ex2ProtocolA
- (void)methodB;
@end

 __attribute__((objc_protocol_requires_explicit_implementation))
@protocol Ex2ProtocolB <Ex2ProtocolA>
- (void)methodA; // expected-note {{method 'methodA' declared here}}
@end

// NOT required
@protocol Ex2ProtocolC <Ex2ProtocolA>
- (void)methodB;
- (void)methodA;
@end

@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar>
@end
@implementation Ex2ClassA
- (void)methodB {}
- (void)methodA {}
@end

@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB>
@end

@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}
@end