Home | History | Annotate | Download | only in SemaObjC
      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}}
     75 int 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