]> granicus.if.org Git - clang/commitdiff
Hook up Sema support for attributes on Objective-C method declarations that
authorTed Kremenek <kremenek@apple.com>
Thu, 30 Apr 2009 18:41:06 +0000 (18:41 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 30 Apr 2009 18:41:06 +0000 (18:41 +0000)
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
lib/Parse/ParseObjc.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaDeclObjC.cpp
test/Analysis/retain-release.m

index fdd2b2abacf1a3c50a209b89240c3ebc945c396e..60cc7cf1548cffb91198288c6dbb7afafe33d43a 100644 (file)
@@ -1439,6 +1439,7 @@ public:
     Selector Sel,              // a unique name for the method.
     ObjCArgInfo *ArgInfo,      // ArgInfo: Has 'Sel.getNumArgs()' entries.
     llvm::SmallVectorImpl<Declarator> &Cdecls, // c-style args
+    AttributeList *ReturnAttrList, // optional
     AttributeList *MethodAttrList, // optional
     // tok::objc_not_keyword, tok::objc_optional, tok::objc_required    
     tok::ObjCKeywordKind impKind,
index fc243270604b030b723eecb1b149e85a53420967..2e0df826bb25d421d8c85499283ebfccc8157f76 100644 (file)
@@ -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);
 }
index d04394d94fd4c22454ccbc5c240285ac23a1a20b..e4746372a51aa525ba761d19f129c6257333db67 100644 (file)
@@ -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<Declarator> &Cdecls,
+    AttributeList *ReturnAttrList,
     AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
     bool isVariadic = false);
 
index df4fd4dd430909fa3adb87b9536d2e73e1c926af..4853028ba3693225dd11048426382b2f2d1c5e31 100644 (file)
@@ -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();
+  }
+}
index 170efec5f37f412dbc253a8b63fe7334579eaea6..61f62cd4bf772d2f7862e598665b50920f7d3e41 100644 (file)
@@ -1509,6 +1509,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
     // from the Sel.getNumArgs().
     ObjCArgInfo *ArgInfo,
     llvm::SmallVectorImpl<Declarator> &Cdecls,
+    AttributeList *ReturnAttrList,                                             
     AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
     bool isVariadic) {
   Decl *ClassDecl = classDecl.getAs<Decl>();
@@ -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 
index 9cf7d9dc66b87ec5525a62d3d1b688505bb6cadd..8add2bb75330e0b78a81add5c1f2d6362250b6eb 100644 (file)
@@ -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;