r196955 - Rename attribute 'objc_suppress_protocol_methods' to 'objc_protocol_requires_explicit_implementation'.

Ted Kremenek kremenek at apple.com
Tue Dec 10 11:43:48 PST 2013


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()));
 }
 
 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}}
- at property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
+ at 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;
- 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;
 @property (readonly) id theWorstOfTimes;
 @end
 
- at 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.
+ at interface ClassB : ClassA <Protocol> // expected-note {{required for direct or indirect protocol 'Protocol'}}
 @end
 
- at implementation ClassC @end // expected-warning {{method 'theBestOfTimes' in protocol not implemented}}
-
- at implementation ClassD // no-warning
-- (void) theBestOfTimes {}
+ at 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)))
- 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
+// Test that the attribute is used correctly.
+__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}}
+ at protocol AnotherProtocol @end
 
-__attribute__((objc_supress_protocol(Protocol)))
- at 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}}
+ at interface AnotherClass @end
 
-__attribute__((objc_supress_protocol(Protocol)))
- at 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}}
- at interface ClassF @end
-
-// The attribute requires one or more identifiers.
-__attribute__((objc_suppress_protocol_methods(ProtoA, ProtoB))) // expected-error {{use of undeclared identifier 'ProtoB'}}
- 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





More information about the cfe-commits mailing list