summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclObjC.h7
-rw-r--r--clang/include/clang/Basic/Attr.td7
-rw-r--r--clang/lib/AST/DeclObjC.cpp21
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp13
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp8
-rw-r--r--clang/test/SemaObjC/protocols-suppress-conformance.m80
6 files changed, 31 insertions, 105 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index b37a64fa019..dc8f31b32ae 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -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 {
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 96d71c747f1..5a8739b3939 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -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 {
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index fb4b9dbd1f4..3db1acf0039 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -256,18 +256,6 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
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::lookupMethod(Selector Sel,
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::lookupMethod(Selector Sel,
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;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 6d7bc034658..0edef9e52a4 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1740,16 +1740,9 @@ static void handleAttrWithMessage(Sema &S, Decl *D,
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, Scope *scope, Decl *D,
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:
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 421b797c794..babfafe656d 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -1666,6 +1666,8 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
// 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(SourceLocation ImpLoc,
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(SourceLocation ImpLoc,
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 */,
diff --git a/clang/test/SemaObjC/protocols-suppress-conformance.m b/clang/test/SemaObjC/protocols-suppress-conformance.m
index 880819e407e..3d6537015c8 100644
--- a/clang/test/SemaObjC/protocols-suppress-conformance.m
+++ b/clang/test/SemaObjC/protocols-suppress-conformance.m
@@ -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}}
-@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.
-//
-
-@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 {}
-@end
-
-@implementation ClassC @end // expected-warning {{method 'theBestOfTimes' in protocol not implemented}}
-
-@implementation ClassD // no-warning
-- (void) theBestOfTimes {}
-@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>
+// 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
-@implementation AdoptsAndConforms // no-warning
-- (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
-// This attribute cannot be added to a class extension or category.
-@interface ClassE
--(void) theBestOfTimes;
+@implementation ClassB // expected-warning {{method 'theBestOfTimes' in protocol not implemented}}
@end
-__attribute__((objc_supress_protocol(Protocol)))
-@interface ClassE () @end // expected-error {{attributes may not be specified on a category}}
+// 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 (MyCat) @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
-// 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
+__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(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
OpenPOWER on IntegriCloud