From b27d1174673d457e2ee7906c14a92bba35242cea Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 30 Apr 2009 18:41:06 +0000 Subject: [PATCH] Hook up Sema support for attributes on Objective-C method declarations that appear between the return type and the selector. This is a separate code path from regular attribute processing, as we only want to (a) accept only a specific set of attributes in this place and (b) want to distinguish to clients the context in which an attribute was added to an ObjCMethodDecl. Currently, the attribute 'objc_ownership_returns' is the only attribute that uses this new feature. Shortly I will add a warning for 'objc_ownership_returns' to be placed at the end of a method declaration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70504 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Action.h | 1 + lib/Parse/ParseObjc.cpp | 4 ++-- lib/Sema/Sema.h | 4 ++++ lib/Sema/SemaDeclAttr.cpp | 34 +++++++++++++++++++++++++++++++++- lib/Sema/SemaDeclObjC.cpp | 4 ++++ test/Analysis/retain-release.m | 9 ++++----- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index fdd2b2abac..60cc7cf154 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1439,6 +1439,7 @@ public: Selector Sel, // a unique name for the method. ObjCArgInfo *ArgInfo, // ArgInfo: Has 'Sel.getNumArgs()' entries. llvm::SmallVectorImpl &Cdecls, // c-style args + AttributeList *ReturnAttrList, // optional AttributeList *MethodAttrList, // optional // tok::objc_not_keyword, tok::objc_optional, tok::objc_required tok::ObjCKeywordKind impKind, diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index fc24327060..2e0df826bb 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -705,7 +705,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, - 0, CargNames, + 0, CargNames, ReturnAttrs, MethodAttrs, MethodImplKind); } @@ -779,7 +779,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, &KeyIdents[0]); return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, - &ArgInfos[0], CargNames, + &ArgInfos[0], CargNames, ReturnAttrs, MethodAttrs, MethodImplKind, isVariadic); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index d04394d94f..e4746372a5 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1071,6 +1071,9 @@ public: // Decl attributes - this routine is the top level dispatcher. void ProcessDeclAttributes(Decl *D, const Declarator &PD); void ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList); + + void ProcessObjCMethDeclReturnAttributeList(ObjCMethodDecl *D, + const AttributeList *AttrList); void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, bool &IncompleteImpl); @@ -2186,6 +2189,7 @@ public: // from the Sel.getNumArgs(). ObjCArgInfo *ArgInfo, llvm::SmallVectorImpl &Cdecls, + AttributeList *ReturnAttrList, AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind, bool isVariadic = false); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index df4fd4dd43..4853028ba3 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1697,7 +1697,6 @@ void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { } } - /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in /// it, apply them to D. This is a bit tricky because PD can have attributes /// specified in many different places, and we need to find and apply them all. @@ -1719,3 +1718,36 @@ void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { ProcessDeclAttributeList(D, Attrs); } + +/// ProcessObjCMethDeclReturnAttribute - Apply the specific attribute to the +/// specified ObjCMethodDecl. This is a separate codepath because it +/// corresponds to attributes applied essentially to the return type of +/// an Objective-C method declaration (as opposed to attributes that hang off +/// the end of the method declaration). +static void ProcessObjCMethDeclReturnAttribute(Decl *D, + const AttributeList &Attr, + Sema &S) { + switch (Attr.getKind()) { + // Checker-specific. + case AttributeList::AT_objc_ownership_returns: + HandleObjCOwnershipReturnsAttr(D, Attr, S); break; + break; + default: + S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); + break; + } +} + +/// ProcessObjCMethDeclAttributeList - Apply all the decl attributes in the +/// specified attribute list to the specified ObjCMethodDecl. This is +/// a separate codepath because it corresponds to attributes applied +/// essentiallyto the return type of an Objective-C method declaration +/// (as opposed to attributes that hang off the end of the method declaration). +void Sema::ProcessObjCMethDeclReturnAttributeList(ObjCMethodDecl *D, + const AttributeList *AttrList) +{ + while (AttrList) { + ProcessObjCMethDeclReturnAttribute(D, *AttrList, *this); + AttrList = AttrList->getNext(); + } +} diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 170efec5f3..61f62cd4bf 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1509,6 +1509,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( // from the Sel.getNumArgs(). ObjCArgInfo *ArgInfo, llvm::SmallVectorImpl &Cdecls, + AttributeList *ReturnAttrList, AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind, bool isVariadic) { Decl *ClassDecl = classDecl.getAs(); @@ -1590,6 +1591,9 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( if (AttrList) ProcessDeclAttributeList(ObjCMethod, AttrList); + + if (ReturnAttrList) + ProcessObjCMethDeclReturnAttributeList(ObjCMethod, ReturnAttrList); // For implementations (which can be very "coarse grain"), we add the // method now. This allows the AST to implement lookup methods that work diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 9cf7d9dc66..8add2bb753 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -431,11 +431,10 @@ void rdar6704930(unsigned char *s, unsigned int length) { //===----------------------------------------------------------------------===// @interface TestOwnershipAttr : NSObject -- (NSString*) returnsAnOwnedString __attribute__((objc_ownership_returns)); - -// We have parsing support for the attribute before the selector, but no Sema -// support yet. -- (NSString*) __attribute__((objc_ownership_returns)) returnsAnOwnedString2; +- (NSString*) __attribute__((objc_ownership_returns)) returnsAnOwnedString; +// Soon we won't accept __attribute__((objc_ownership_returns)) at the end +// of a method decl. +- (NSString*) returnsAnOwnedString2 __attribute__((objc_ownership_returns)); - (void) myRetain:(id)__attribute__((objc_ownership_retain))obj; - (void) myCFRetain:(id)__attribute__((objc_ownership_cfretain))obj; -- 2.40.0