summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2013-12-13 06:26:14 +0000
committerTed Kremenek <kremenek@apple.com>2013-12-13 06:26:14 +0000
commit33e430fc58b2ae588cb9865e61efa317f78753bf (patch)
tree1527c87f60d09253e1d47ebfdf01f295c51c842f
parent285ee85b17fe10acf206898a3c9ec74a327f88e4 (diff)
downloadbcm5719-llvm-33e430fc58b2ae588cb9865e61efa317f78753bf.tar.gz
bcm5719-llvm-33e430fc58b2ae588cb9865e61efa317f78753bf.zip
Refine 'objc_protocol_requires_explicit_implementation' attribute to better handle indirect protocols.
llvm-svn: 197209
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp7
-rw-r--r--clang/test/SemaObjC/protocols-suppress-conformance.m46
2 files changed, 50 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 1aa36ca678c..9f50a207c1a 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -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
diff --git a/clang/test/SemaObjC/protocols-suppress-conformance.m b/clang/test/SemaObjC/protocols-suppress-conformance.m
index f62b2851755..e5fe1036bfb 100644
--- a/clang/test/SemaObjC/protocols-suppress-conformance.m
+++ b/clang/test/SemaObjC/protocols-suppress-conformance.m
@@ -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
+
OpenPOWER on IntegriCloud