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