From: Ted Kremenek Date: Thu, 21 Nov 2013 07:57:53 +0000 (+0000) Subject: Revert "Add new attribute 'objc_suppress_protocol' to suppress protocol conformance... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a8fba738b5ec4e92d526d2c9354ab924e628923;p=clang Revert "Add new attribute 'objc_suppress_protocol' to suppress protocol conformance for a class." After implementing this patch, a few concerns about the language feature itself emerged in my head that I had previously not considered. I want to resolve those design concerns first before having a half-designed language feature in the tree. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195328 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 10e5dc11ee..2e760d658e 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1142,17 +1142,14 @@ public: // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup= false, - const ObjCCategoryDecl *C = 0, - const ObjCProtocolDecl *P = 0) const; + const ObjCCategoryDecl *C= 0) const; ObjCMethodDecl *lookupInstanceMethod(Selector Sel, - bool shallowCategoryLookup = false, - ObjCProtocolDecl *P = 0) const { - return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup, 0, P); + bool shallowCategoryLookup = false) const { + return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); } ObjCMethodDecl *lookupClassMethod(Selector Sel, - bool shallowCategoryLookup = false, - ObjCProtocolDecl *P = 0) const { - return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup, 0, P); + bool shallowCategoryLookup = false) const { + return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); } ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index a6be491c5a..bcca1d25ef 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -613,12 +613,6 @@ def ObjCRootClass : InheritableAttr { let Subjects = [ObjCInterface]; } -def ObjCSuppressProtocol : InheritableAttr { - let Spellings = [GNU<"objc_suppress_protocol">]; - let Subjects = [ObjCInterface]; - let Args = [IdentifierArgument<"Protocol", 1>]; -} - def Overloadable : Attr { let Spellings = [GNU<"overloadable">]; } diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index d759c0795b..b2b5b70197 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -457,11 +457,9 @@ ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) { /// When argument category "C" is specified, any implicit method found /// in this category is ignored. ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, - bool isInstance, - bool shallowCategoryLookup, - const ObjCCategoryDecl *C, - const ObjCProtocolDecl *P) const -{ + bool isInstance, + bool shallowCategoryLookup, + const ObjCCategoryDecl *C) const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return 0; @@ -472,23 +470,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, if (data().ExternallyCompleted) LoadExternalDefinition(); - while (ClassDecl) { - // If we are looking for a method that is part of protocol conformance, - // check if the class has been marked to suppress conformance - // of that protocol. - if (P && ClassDecl->hasAttrs()) { - const AttrVec &V = ClassDecl->getAttrs(); - const IdentifierInfo *PI = P->getIdentifier(); - for (AttrVec::const_iterator I = V.begin(), E = V.end(); I != E; ++I) { - if (const ObjCSuppressProtocolAttr *A = - dyn_cast(*I)){ - if (A->getProtocol() == PI) { - return 0; - } - } - } - } - + while (ClassDecl != NULL) { if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) return MethodDecl; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 0c025b7849..38bffa2f99 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2134,30 +2134,6 @@ static void handleObjCRootClassAttr(Sema &S, Decl *D, Attr.getAttributeSpellingListIndex())); } -static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D, - const AttributeList &Attr) { - if (!isa(D)) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) - << Attr.getName() << ExpectedObjectiveCInterface; - return; - } - - IdentifierLoc *Parm = NULL; - if (Attr.getNumArgs() == 1) { - 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())); -} - - static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (!isa(D)) { @@ -4714,10 +4690,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ObjCRootClass: handleObjCRootClassAttr(S, D, Attr); break; - case AttributeList::AT_ObjCSuppressProtocol: - handleObjCSuppresProtocolAttr(S, D, Attr); - break; - case AttributeList::AT_ObjCRequiresPropertyDefs: + case AttributeList::AT_ObjCRequiresPropertyDefs: handleObjCRequiresPropertyDefsAttr (S, D, Attr); break; case AttributeList::AT_Unused: handleUnusedAttr (S, D, Attr); break; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 2a781b5bd7..f44fb32511 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1664,8 +1664,7 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, if (method->getImplementationControl() != ObjCMethodDecl::Optional && !method->isPropertyAccessor() && !InsMap.count(method->getSelector()) && - (!Super || !Super->lookupInstanceMethod(method->getSelector(), - false, PDecl))) { + (!Super || !Super->lookupInstanceMethod(method->getSelector()))) { // 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. @@ -1677,8 +1676,7 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, // uses the protocol. if (ObjCMethodDecl *MethodInClass = IDecl->lookupInstanceMethod(method->getSelector(), - true /*shallowCategoryLookup*/, - PDecl)) + true /*shallowCategoryLookup*/)) if (C || MethodInClass->isPropertyAccessor()) continue; unsigned DIAG = diag::warn_unimplemented_protocol_method; @@ -1697,13 +1695,10 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, ObjCMethodDecl *method = *I; if (method->getImplementationControl() != ObjCMethodDecl::Optional && !ClsMap.count(method->getSelector()) && - (!Super || !Super->lookupClassMethod(method->getSelector(), - /* shallowCategoryLookup */ false, - PDecl))) { + (!Super || !Super->lookupClassMethod(method->getSelector()))) { // See above comment for instance method lookups. if (C && IDecl->lookupClassMethod(method->getSelector(), - true /*shallowCategoryLookup*/, - PDecl)) + true /*shallowCategoryLookup*/)) continue; unsigned DIAG = diag::warn_unimplemented_protocol_method; if (Diags.getDiagnosticLevel(DIAG, ImpLoc) != diff --git a/test/SemaObjC/protocols-suppress-conformance.m b/test/SemaObjC/protocols-suppress-conformance.m deleted file mode 100644 index 77c7e254c2..0000000000 --- a/test/SemaObjC/protocols-suppress-conformance.m +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-objc-root-class - -@protocol FooProto -- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}} -@end - -__attribute__((objc_suppress_protocol(FooProto))) -@interface Bar -- (void) theBestOfTimes; -@end - -@interface Bar2 : Bar -@end - -@interface Baz : Bar2 // expected-note {{required for direct or indirect protocol 'FooProto'}} -@end - -@interface Baz2 : Bar2 -- (void) theBestOfTimes; -@end - -@implementation Baz // expected-warning {{method 'theBestOfTimes' in protocol not implemented}} -@end - -@implementation Baz2 // no-warning -- (void) theBestOfTimes {} -@end \ No newline at end of file