diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-10-22 01:21:15 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-10-22 01:21:15 +0000 |
commit | 512a4cc9674f3c64d75498a5766bd37d61bbc38c (patch) | |
tree | 967cd56c44ec4badd3304d6039a243c21ae4976a /clang | |
parent | b8da426285eafb6b55ef29ec2f8223e0004332db (diff) | |
download | bcm5719-llvm-512a4cc9674f3c64d75498a5766bd37d61bbc38c.tar.gz bcm5719-llvm-512a4cc9674f3c64d75498a5766bd37d61bbc38c.zip |
objc: private methods can have their attributes, no diagnostic is required.
None private methods if their implementation have attribute, they must exactly
match those in their declarations. // rdar://10271563
llvm-svn: 142709
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 37 | ||||
-rw-r--r-- | clang/test/SemaObjC/attr-deprecated.m | 2 | ||||
-rw-r--r-- | clang/test/SemaObjC/method-attributes.m | 5 |
3 files changed, 35 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 669ea8f32a9..69d9c1d9980 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -2318,13 +2318,32 @@ CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) { } static inline -bool containsInvalidMethodImplAttribute(const AttrVec &A) { - // The 'ibaction' attribute is allowed on method definitions because of - // how the IBAction macro is used on both method declarations and definitions. - // If the method definitions contains any other attributes, return true. - for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i) - if ((*i)->getKind() != attr::IBAction) +bool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD, + const AttrVec &A) { + // If method is only declared in implementation (private method), + // or method declared in interface has no attribute. + // No need to issue any diagnostics on method definition with attributes. + if (!IMD || !IMD->hasAttrs()) + return false; + + const AttrVec &D = IMD->getAttrs(); + if (D.size() != A.size()) + return true; + + // attributes on method declaration and definition must match exactly. + // Note that we have at most a couple of attributes on methods, so this + // n*n search is good enough. + for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i) { + bool match = false; + for (AttrVec::const_iterator i1 = D.begin(), e1 = D.end(); i1 != e1; ++i1) { + if ((*i)->getKind() == (*i1)->getKind()) { + match = true; + break; + } + } + if (!match) return true; + } return false; } @@ -2656,8 +2675,12 @@ Decl *Sema::ActOnMethodDeclaration( ImpDecl->addClassMethod(ObjCMethod); } + ObjCMethodDecl *IMD = 0; + if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface()) + IMD = IDecl->lookupMethod(ObjCMethod->getSelector(), + ObjCMethod->isInstanceMethod()); if (ObjCMethod->hasAttrs() && - containsInvalidMethodImplAttribute(ObjCMethod->getAttrs())) + containsInvalidMethodImplAttribute(IMD, ObjCMethod->getAttrs())) Diag(EndLoc, diag::warn_attribute_method_def); } else { cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod); diff --git a/clang/test/SemaObjC/attr-deprecated.m b/clang/test/SemaObjC/attr-deprecated.m index ca267599288..e90bbf94eab 100644 --- a/clang/test/SemaObjC/attr-deprecated.m +++ b/clang/test/SemaObjC/attr-deprecated.m @@ -9,7 +9,7 @@ @implementation A + (void)F __attribute__((deprecated)) -{ // expected-warning {{method attribute can only be specified on method declarations}} +{ [self F]; // no warning, since the caller is also deprecated. } diff --git a/clang/test/SemaObjC/method-attributes.m b/clang/test/SemaObjC/method-attributes.m index 9157fcfefe1..f7f647bd460 100644 --- a/clang/test/SemaObjC/method-attributes.m +++ b/clang/test/SemaObjC/method-attributes.m @@ -16,10 +16,11 @@ - (int) foo: (int)arg1; - (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)); +- (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)); @end @implementation INTF -- (int) foo: (int)arg1 __attribute__((deprecated)){ // expected-warning {{method attribute can only be specified}} +- (int) foo: (int)arg1 __attribute__((deprecated)){ return 10; } - (int) foo1: (int)arg1 { @@ -28,5 +29,7 @@ - (int) foo2: (int)arg1 __attribute__((deprecated)) { // expected-warning {{method attribute can only be specified}} return 10; } +- (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)) {return 0; } +- (void) dep __attribute__((deprecated)) { } // OK private methodn @end |