]> granicus.if.org Git - clang/commitdiff
Refine 'objc_protocol_requires_explicit_implementation' attribute to better handle...
authorTed Kremenek <kremenek@apple.com>
Fri, 13 Dec 2013 06:26:14 +0000 (06:26 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 13 Dec 2013 06:26:14 +0000 (06:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197209 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/protocols-suppress-conformance.m

index 1aa36ca678ce0f07fa07aa7bb11675532f9eb7e5..9f50a207c1a8aa09880c0ac281e51f2a82655780 100644 (file)
@@ -1641,7 +1641,8 @@ static void CheckProtocolMethodDefs(Sema &S,
                                     bool& IncompleteImpl,
                                     const Sema::SelectorSet &InsMap,
                                     const Sema::SelectorSet &ClsMap,
-                                    ObjCContainerDecl *CDecl) {
+                                    ObjCContainerDecl *CDecl,
+                                    bool isExplicitProtocol = true) {
   ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
   ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() 
                                : dyn_cast<ObjCInterfaceDecl>(CDecl);
@@ -1674,7 +1675,7 @@ static void CheckProtocolMethodDefs(Sema &S,
   // 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>())
+  if (isExplicitProtocol && PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
     Super = NULL;
 
   // check unimplemented instance methods.
@@ -1744,7 +1745,7 @@ static void CheckProtocolMethodDefs(Sema &S,
   for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
        E = PDecl->protocol_end(); PI != E; ++PI)
     CheckProtocolMethodDefs(S, ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap,
-                            CDecl);
+                            CDecl, /* isExplicitProtocl */ false);
 }
 
 /// MatchAllMethodDeclarations - Check methods declared in interface
index f62b2851755893c06c702e57d7b12d589c6ca477..e5fe1036bfb3b6e2bb65386588044c4dda2c5198 100644 (file)
@@ -54,3 +54,49 @@ __attribute__((objc_protocol_requires_explicit_implementation)) // expected-erro
 __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;
+- (void)innsmouth;
+@end
+
+@protocol ProtocolB <ProtocolA>
+@required
+- (void)dunwich;
+- (id)innsmouth;
+@end
+
+@protocol ProtocolC
+@required
+- (void)rlyeh;
+- (void)innsmouth;
+- (void)dunwich;
+@end
+
+@interface MyObject <ProtocolC>
+@end
+
+@interface MyLovecraft <ProtocolA>
+@end
+
+@interface MyShoggoth : MyLovecraft <ProtocolB>
+@end
+
+@implementation MyObject
+- (void)innsmouth {}
+- (void)rlyeh {}
+- (void)dunwich {}
+@end
+
+@implementation MyLovecraft
+- (void)innsmouth {}
+- (void)rlyeh {}
+@end
+
+@implementation MyShoggoth
+- (void)dunwich {}
+@end
+