On Tue, Dec 10, 2013 at 2:43 PM, Ted Kremenek <[email protected]> wrote: > Author: kremenek > Date: Tue Dec 10 13:43:48 2013 > New Revision: 196955 > > URL: http://llvm.org/viewvc/llvm-project?rev=196955&view=rev > Log: > Rename attribute 'objc_suppress_protocol_methods' to > 'objc_protocol_requires_explicit_implementation'. > > That's a mouthful, and not necessarily the final name. This also > reflects a semantic change where this attribute is now on the > protocol itself instead of a class. This attribute will require > that a protocol, when adopted by a class, is explicitly implemented > by the class itself (instead of walking the super class chain). > > Note that this attribute is not "done". This should be considered > a WIP. > > Modified: > cfe/trunk/include/clang/AST/DeclObjC.h > cfe/trunk/include/clang/Basic/Attr.td > cfe/trunk/lib/AST/DeclObjC.cpp > cfe/trunk/lib/Sema/SemaDeclAttr.cpp > cfe/trunk/lib/Sema/SemaDeclObjC.cpp > cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m > > Modified: cfe/trunk/include/clang/AST/DeclObjC.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=196955&r1=196954&r2=196955&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclObjC.h (original) > +++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Dec 10 13:43:48 2013 > @@ -984,10 +984,6 @@ public: > : superCls; > } > > - /// \brief Returns true if this class is marked to suppress being > - /// used to determine if a subclass conforms to a protocol. > - bool shouldSuppressProtocol(const ObjCProtocolDecl *P) const; > - > /// \brief Iterator that walks over the list of categories, filtering out > /// those that do not meet specific criteria. > /// > @@ -1206,8 +1202,7 @@ public: > ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, > bool shallowCategoryLookup = false, > bool followSuper = true, > - const ObjCCategoryDecl *C = 0, > - const ObjCProtocolDecl *P = 0) const; > + const ObjCCategoryDecl *C = 0) const; > > /// Lookup an instance method for a given selector. > ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { > > Modified: cfe/trunk/include/clang/Basic/Attr.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=196955&r1=196954&r2=196955&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/Attr.td (original) > +++ cfe/trunk/include/clang/Basic/Attr.td Tue Dec 10 13:43:48 2013 > @@ -695,10 +695,9 @@ def ObjCRootClass : InheritableAttr { > let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; > } > > -def ObjCSuppressProtocol : InheritableAttr { > - let Spellings = [GNU<"objc_suppress_protocol_methods">]; > - let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; > - let Args = [IdentifierArgument<"Protocol">]; > +def ObjCExplicitProtocolImpl : InheritableAttr { > + let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">]; > + let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>; > } > > def ObjCDesignatedInitializer : Attr { > > Modified: cfe/trunk/lib/AST/DeclObjC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=196955&r1=196954&r2=196955&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclObjC.cpp (original) > +++ cfe/trunk/lib/AST/DeclObjC.cpp Tue Dec 10 13:43:48 2013 > @@ -256,18 +256,6 @@ ObjCContainerDecl::FindPropertyDeclarati > > void ObjCInterfaceDecl::anchor() { } > > -bool ObjCInterfaceDecl::shouldSuppressProtocol(const ObjCProtocolDecl *P) > const{ > - if (!hasAttrs()) > - return false; > - const IdentifierInfo *PI = P->getIdentifier(); > - for (specific_attr_iterator<ObjCSuppressProtocolAttr> > - I = specific_attr_begin<ObjCSuppressProtocolAttr>(), > - E = specific_attr_end<ObjCSuppressProtocolAttr>(); I != E; ++I) > - if ((*I)->getProtocol() == PI) > - return true; > - return false; > -} > - > /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property > /// with name 'PropertyId' in the primary class; including those in protocols > /// (direct or indirect) used by the primary class. > @@ -555,8 +543,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::looku > bool isInstance, > bool shallowCategoryLookup, > bool followSuper, > - const ObjCCategoryDecl *C, > - const ObjCProtocolDecl *P) > const > + const ObjCCategoryDecl *C) > const > { > // FIXME: Should make sure no callers ever do this. > if (!hasDefinition()) > @@ -569,12 +556,6 @@ ObjCMethodDecl *ObjCInterfaceDecl::looku > LoadExternalDefinition(); > > while (ClassDecl) { > - // If we are looking for a method that is part of protocol conformance, > - // check if the superclass has been marked to suppress conformance > - // of that protocol. > - if (P && ClassDecl->shouldSuppressProtocol(P)) > - return 0; > - > if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) > return MethodDecl; > > > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=196955&r1=196954&r2=196955&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Dec 10 13:43:48 2013 > @@ -1740,16 +1740,9 @@ static void handleAttrWithMessage(Sema & > > static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D, > const AttributeList &Attr) { > - IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0; > - > - if (!Parm) { > - S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() > << 1; > - return; > - } > - > D->addAttr(::new (S.Context) > - ObjCSuppressProtocolAttr(Attr.getRange(), S.Context, > Parm->Ident, > - Attr.getAttributeSpellingListIndex())); > + ObjCExplicitProtocolImplAttr(Attr.getRange(), S.Context, > + > Attr.getAttributeSpellingListIndex()));
If you aren't adding further semantic checks, you could remove this handler entirely and instead use the handleSimpleAttribute templatized handler. > } > > static bool checkAvailabilityAttr(Sema &S, SourceRange Range, > @@ -4032,7 +4025,7 @@ static void ProcessDeclAttribute(Sema &S > handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, Attr); break; > case AttributeList::AT_ObjCRootClass: > handleSimpleAttribute<ObjCRootClassAttr>(S, D, Attr); break; > - case AttributeList::AT_ObjCSuppressProtocol: > + case AttributeList::AT_ObjCExplicitProtocolImpl: > handleObjCSuppresProtocolAttr(S, D, Attr); > break; > case AttributeList::AT_ObjCRequiresPropertyDefs: > > Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=196955&r1=196954&r2=196955&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Dec 10 13:43:48 2013 > @@ -1666,6 +1666,8 @@ void Sema::CheckProtocolMethodDefs(Sourc > // the method was implemented by a base class or an inherited > // protocol. This lookup is slow, but occurs rarely in correct code > // and otherwise would terminate in a warning. > + if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) > + Super = NULL; > > // check unimplemented instance methods. > if (!NSIDecl) > @@ -1679,8 +1681,7 @@ void Sema::CheckProtocolMethodDefs(Sourc > true /* instance */, > false /* shallowCategory */, > true /* followsSuper */, > - NULL /* category */, > - PDecl /* protocol */))) { > + NULL /* category */))) { > // 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. > @@ -1717,8 +1718,7 @@ void Sema::CheckProtocolMethodDefs(Sourc > false /* class method */, > false /* shallowCategoryLookup */, > true /* followSuper */, > - NULL /* category */, > - PDecl /* protocol */))) { > + NULL /* category */))) { > // See above comment for instance method lookups. > if (C && IDecl->lookupMethod(method->getSelector(), > false /* class */, > > Modified: cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m?rev=196955&r1=196954&r2=196955&view=diff > ============================================================================== > --- cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m (original) > +++ cfe/trunk/test/SemaObjC/protocols-suppress-conformance.m Tue Dec 10 > 13:43:48 2013 > @@ -1,79 +1,37 @@ > // 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}} > +@property (readonly) id theWorstOfTimes; > @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. > -// > - > +// 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; > -@end > - > -__attribute__((objc_suppress_protocol_methods(Protocol))) @interface ClassB > : ClassA @end > - > -@interface ClassC : ClassB <Protocol> @end // expected-note {{required for > direct or indirect protocol 'Protocol'}} > - > -@interface ClassD : ClassB <Protocol> > -- (void) theBestOfTimes; > @property (readonly) id theWorstOfTimes; > @end > > -@implementation ClassA // expected-warning {{auto property synthesis will > not synthesize property declared in a protocol}} > -- (void) theBestOfTimes {} > +// This class subclasses ClassA (which adopts 'Protocol'), > +// but does not provide the needed implementation. > +@interface ClassB : ClassA <Protocol> // expected-note {{required for direct > or indirect protocol 'Protocol'}} > @end > > -@implementation ClassC @end // expected-warning {{method 'theBestOfTimes' in > protocol not implemented}} > - > -@implementation ClassD // no-warning > -- (void) theBestOfTimes {} > +@implementation ClassB // expected-warning {{method 'theBestOfTimes' in > protocol not implemented}} > @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))) > -@interface AdoptsAndConforms <Protocol> > -- (void) theBestOfTimes; > -@property (readonly) id theWorstOfTimes; > -@end > - > -@implementation AdoptsAndConforms // no-warning > -- (void) theBestOfTimes {} > -@end > - > -// This attribute cannot be added to a class extension or category. > -@interface ClassE > --(void) theBestOfTimes; > -@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 > > -__attribute__((objc_supress_protocol(Protocol))) > -@interface ClassE () @end // expected-error {{attributes may not be > specified on a category}} > +// 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_supress_protocol(Protocol))) > -@interface ClassE (MyCat) @end // expected-error {{attributes may not be > specified on a category}} > +__attribute__((objc_protocol_requires_explicit_implementation)) // > expected-error {{attribute only applies to Objective-C protocols}} > +int x; > > -// The attribute requires one or more identifiers. > -__attribute__((objc_suppress_protocol_methods())) // expected-error > {{'objc_suppress_protocol_methods' attribute takes one argument}} > -@interface ClassF @end > - > -// The attribute requires one or more identifiers. > -__attribute__((objc_suppress_protocol_methods(ProtoA, ProtoB))) // > expected-error {{use of undeclared identifier 'ProtoB'}} > -@interface ClassG @end > -__attribute__((objc_suppress_protocol_methods(1+2))) > -@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 Should probably add the newline at the end of the test file. ~Aaron _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
