diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 7 | ||||
| -rw-r--r-- | clang/include/clang/Basic/Attr.td | 7 | ||||
| -rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 21 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 8 | ||||
| -rw-r--r-- | clang/test/SemaObjC/protocols-suppress-conformance.m | 80 |
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 |

