r195533 - Add back experimental attribute objc_suppress_protocol_methods (slightly renamed).

Ted Kremenek kremenek at apple.com
Tue Nov 26 23:02:17 PST 2013


On Nov 24, 2013, at 8:00 AM, Aaron Ballman <aaron at aaronballman.com> wrote:

> I thought id was something more special than just "any identifier?"  Eg)
> 
> int i;
> __attribute__((objc_suppress_protocol_methods(i)))
> @interface foo
> @end
> 
> There would be no error fired here, but based on the error text, it
> seems like there should be one.

This is valid.  Objective-C protocols are in their own namespace, and this attribute is meant to work regardless of whether or not the protocol is visible within the translation unit.  Thus this case is valid.  The ‘i’ here for the attribute parameter has nothing to do with ‘int i’.

> 
>> 
>> +    return;
>> +  }
>> +
>> +  D->addAttr(::new (S.Context)
>> +             ObjCSuppressProtocolAttr(Attr.getRange(), S.Context,
>> Parm->Ident,
>> +
>> Attr.getAttributeSpellingListIndex()));
>> +}
>> +
>> +
>> static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
>>                                               const AttributeList &Attr) {
>>  if (!isa<ObjCInterfaceDecl>(D)) {
>> @@ -4713,7 +4735,10 @@ static void ProcessDeclAttribute(Sema &S
>>  case AttributeList::AT_ObjCRootClass:
>>    handleObjCRootClassAttr(S, D, Attr);
>>    break;
>> -  case AttributeList::AT_ObjCRequiresPropertyDefs:
>> +  case AttributeList::AT_ObjCSuppressProtocol:
>> +    handleObjCSuppresProtocolAttr(S, D, Attr);
>> +    break;
>> +  case AttributeList::AT_ObjCRequiresPropertyDefs:
>>    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
>>    break;
>>  case AttributeList::AT_Unused:      handleUnusedAttr      (S, D, Attr);
>> break;
>> 
>> Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=195533&r1=195532&r2=195533&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Nov 22 19:01:34 2013
>> @@ -1667,7 +1667,9 @@ void Sema::CheckProtocolMethodDefs(Sourc
>>          (!Super || !Super->lookupMethod(method->getSelector(),
>>                                          true /* instance */,
>>                                          false /* shallowCategory */,
>> -                                          true /* followsSuper */))) {
>> +                                          true /* followsSuper */,
>> +                                          NULL /* category */,
>> +                                          PDecl /* protocol */))) {
>>            // If a method is not implemented in the category implementation
>> but
>>            // has been declared in its primary class, superclass,
>>            // or in one of their protocols, no need to issue the warning.
>> @@ -1703,7 +1705,9 @@ void Sema::CheckProtocolMethodDefs(Sourc
>>        (!Super || !Super->lookupMethod(method->getSelector(),
>>                                        false /* class method */,
>>                                        false /* shallowCategoryLookup */,
>> -                                        true  /* followSuper */))) {
>> +                                        true  /* followSuper */,
>> +                                        NULL /* category */,
>> +                                        PDecl /* protocol */))) {
>>      // See above comment for instance method lookups.
>>      if (C && IDecl->lookupMethod(method->getSelector(),
>>                                   false /* class */,
>> 
>> Added: cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m?rev=195533&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m (added)
>> +++ cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m Fri Nov 22
>> 19:01:34 2013
>> @@ -0,0 +1,79 @@
>> +// RUN: %clang_cc1  -triple x86_64-apple-darwin11 -fsyntax-only -verify %s
>> -Wno-objc-root-class
>> +
>> + at protocol Protocol
>> +- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes'
>> declared here}}
>> + at property (readonly) id theWorstOfTimes; // expected-note {{property
>> declared here}}
>> + at end
>> +
>> +// In this example, the root class provides all the methods for
>> +// a protocol, and the immediate subclass adopts the attribute.
>> +//
>> +// The further subclasses should not have access to the root class's
>> +// methods for checking protocol conformance.
>> +//
>> +// ClassC states protocol conformance, but does not redeclare the method.
>> +// For this case we get a warning.
>> +//
>> +// ClassD states protocol conformance, but does redeclare the method.
>> +// For this case we do not get a warning.
>> +//
>> +
>> + at interface ClassA <Protocol>
>> +- (void) theBestOfTimes;
>> +//@property (readonly) id theWorstOfTimes;
>> + at end
>> +
>> +__attribute__((objc_suppress_protocol_methods(Protocol))) @interface ClassB
>> : ClassA @end
>> +
>> + at interface ClassC : ClassB <Protocol> @end // expected-note {{required for
>> direct or indirect protocol 'Protocol'}}
>> +
>> + at interface ClassD : ClassB <Protocol>
>> +- (void) theBestOfTimes;
>> + at property (readonly) id theWorstOfTimes;
>> + at end
>> +
>> + at implementation ClassA // expected-warning {{auto property synthesis will
>> not synthesize property declared in a protocol}}
>> +- (void) theBestOfTimes {}
>> + at end
>> +
>> + at implementation ClassC @end // expected-warning {{method 'theBestOfTimes'
>> in protocol not implemented}}
>> +
>> + at implementation ClassD // no-warning
>> +- (void) theBestOfTimes {}
>> + at end
>> +
>> +// In this example, the class both conforms to the protocl and adopts
>> +// the attribute.  This illustrates that the attribute does not
>> +// interfere with the protocol conformance checking for the class
>> +// itself.
>> +__attribute__((objc_suppress_protocol_methods(Protocol)))
>> + at interface AdoptsAndConforms <Protocol>
>> +- (void) theBestOfTimes;
>> + at property (readonly) id theWorstOfTimes;
>> + at end
>> +
>> + at implementation AdoptsAndConforms // no-warning
>> +- (void) theBestOfTimes {}
>> + at end
>> +
>> +// This attribute cannot be added to a class extension or category.
>> + at interface ClassE
>> +-(void) theBestOfTimes;
>> + at end
>> +
>> +__attribute__((objc_supress_protocol(Protocol)))
>> + at interface ClassE () @end // expected-error {{attributes may not be
>> specified on a category}}
>> +
>> +__attribute__((objc_supress_protocol(Protocol)))
>> + at interface ClassE (MyCat) @end // expected-error {{attributes may not be
>> specified on a category}}
>> +
>> +// The attribute requires one or more identifiers.
>> +__attribute__((objc_suppress_protocol_methods()))
>> + at interface ClassF @end // expected-error {{parameter of
>> 'objc_suppress_protocol_methods' attribute must be a single name of an
>> Objective-C protocol}}
>> 
>> 
>> This test will be improved once you remove the optional bit from Attr.td
>> 
>> 
>> Indeed, thanks.
>> 
>> 
>> +
>> +// The attribute requires one or more identifiers.
>> +__attribute__((objc_suppress_protocol_methods(ProtoA, ProtoB))) //
>> expected-error {{use of undeclared identifier 'ProtoB'}}
>> 
>> 
>> This test should be complaining about the second argument not that it
>> doesn't know what second arg is.
>> 
>> 
>> Is there a way to get this checking automatic via changes in Attr.td?
> 
> Once the optional bit is removed from Attr.td, this will happen automatically.

This is what I have in Attr.td:

def ObjCSuppressProtocol : InheritableAttr {
  let Spellings = [GNU<"objc_suppress_protocol_methods">];
  let Subjects = [ObjCInterface];
  let Args = [IdentifierArgument<"Protocol">];
}

and this is what we have in the test case:

  __attribute__((objc_suppress_protocol_methods(ProtoA, ProtoB))) // expected-error {{use of undeclared identifier 'ProtoB'}}

Am I missing something?  From what I can tell the optional bit has been removed, and yet the error remains as it is.  For this test case, it is intentional that ProtoB is not declared; that’s perfectly fine.  The problem is that the attribute takes one argument.

> 
>> 
>> 
>> + at interface ClassG @end
>> +__attribute__((objc_suppress_protocol_methods(1+2)))
>> + at interface ClassH @end // expected-error {{parameter of
>> 'objc_suppress_protocol_methods' attribute must be a single name of an
>> Objective-C protocol}}
>> +
>> \ No newline at end of file
>> 
>> 
>> Missing a newline here
>> 
>> ~Aaron
>> 
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131126/e9eca8cc/attachment.html>


More information about the cfe-commits mailing list