Implement ownership attribute 'objc_ownership_make_collectable'. This allows one
to add 'CFMakeCollectable' semantics to a method.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70336 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 538f4f2..e1483d6 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1121,6 +1121,10 @@
       ScratchArgs.push_back(std::make_pair(i, DecRef));
       hasArgEffect = true;
     }
+    else if ((*I)->getAttr<ObjCOwnershipMakeCollectableAttr>()) {
+      ScratchArgs.push_back(std::make_pair(i, MakeCollectable));
+      hasArgEffect = true;
+    }    
   }
   
   if (!hasRetEffect && !hasArgEffect)
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index fc14a26..22699e5 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -476,8 +476,9 @@
     SIMPLE_ATTR(ObjCException);
     SIMPLE_ATTR(ObjCNSObject);
     SIMPLE_ATTR(ObjCOwnershipCFRelease);
-    SIMPLE_ATTR(ObjCOwnershipRelease);
     SIMPLE_ATTR(ObjCOwnershipCFRetain);
+    SIMPLE_ATTR(ObjCOwnershipMakeCollectable);
+    SIMPLE_ATTR(ObjCOwnershipRelease);
     SIMPLE_ATTR(ObjCOwnershipRetain);
     SIMPLE_ATTR(ObjCOwnershipReturns);
     SIMPLE_ATTR(Overloadable);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 04b552a..8374e09 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1545,8 +1545,9 @@
     case Attr::ObjCException:
     case Attr::ObjCNSObject:
     case Attr::ObjCOwnershipCFRelease:
-    case Attr::ObjCOwnershipRelease:
     case Attr::ObjCOwnershipCFRetain:
+    case Attr::ObjCOwnershipMakeCollectable:
+    case Attr::ObjCOwnershipRelease:
     case Attr::ObjCOwnershipRetain:
     case Attr::ObjCOwnershipReturns:
     case Attr::Overloadable:
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
index cbc0031..cbd230c 100644
--- a/lib/Parse/AttributeList.cpp
+++ b/lib/Parse/AttributeList.cpp
@@ -152,6 +152,10 @@
   case 24:
     if (!memcmp(Str, "objc_ownership_cfrelease", 24))
       return AT_objc_ownership_cfrelease;
+    break;      
+  case 31:
+    if (!memcmp(Str, "objc_ownership_make_collectable", 31))
+      return AT_objc_ownership_make_collectable;
     break;
   }  
   return UnknownAttribute;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 09c627e..9e550ba 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1539,14 +1539,16 @@
       default:
         assert(0 && "invalid ownership attribute");
         return;
-      case AttributeList::AT_objc_ownership_release:
-        name = "objc_ownership_release"; break;
       case AttributeList::AT_objc_ownership_cfrelease:
-        name = "objc_ownership_cfrelease"; break;        
-      case AttributeList::AT_objc_ownership_retain:
-        name = "objc_ownership_retain"; break;
+        name = "objc_ownership_cfrelease"; break;
       case AttributeList::AT_objc_ownership_cfretain:
         name = "objc_ownership_cfretain"; break;
+      case AttributeList::AT_objc_ownership_make_collectable:
+        name = "objc_ownership_make_collectable"; break;
+      case AttributeList::AT_objc_ownership_release:
+        name = "objc_ownership_release"; break;
+      case AttributeList::AT_objc_ownership_retain:
+        name = "objc_ownership_retain"; break;
     };
 
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << name
@@ -1558,14 +1560,16 @@
     default:
       assert(0 && "invalid ownership attribute");
       return;
-    case AttributeList::AT_objc_ownership_release:
-      d->addAttr(::new (S.Context) ObjCOwnershipReleaseAttr());   return;
     case AttributeList::AT_objc_ownership_cfrelease:
       d->addAttr(::new (S.Context) ObjCOwnershipCFReleaseAttr()); return;      
-    case AttributeList::AT_objc_ownership_retain:
-      d->addAttr(::new (S.Context) ObjCOwnershipRetainAttr());   return;
     case AttributeList::AT_objc_ownership_cfretain:
       d->addAttr(::new (S.Context) ObjCOwnershipCFRetainAttr()); return;
+    case AttributeList::AT_objc_ownership_make_collectable:
+      d->addAttr(::new (S.Context) ObjCOwnershipMakeCollectableAttr()); return;
+    case AttributeList::AT_objc_ownership_release:
+      d->addAttr(::new (S.Context) ObjCOwnershipReleaseAttr());   return;
+    case AttributeList::AT_objc_ownership_retain:
+      d->addAttr(::new (S.Context) ObjCOwnershipRetainAttr());   return;
   }
 }
 
@@ -1607,10 +1611,11 @@
   case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
 
   // Checker-specific.
-  case AttributeList::AT_objc_ownership_release:
-  case AttributeList::AT_objc_ownership_cfrelease:
-  case AttributeList::AT_objc_ownership_retain:
+  case AttributeList::AT_objc_ownership_cfrelease:     
   case AttributeList::AT_objc_ownership_cfretain:
+  case AttributeList::AT_objc_ownership_make_collectable:
+  case AttributeList::AT_objc_ownership_release:
+  case AttributeList::AT_objc_ownership_retain:
     HandleObjCOwnershipParmAttr(D, Attr, S); break;
   case AttributeList::AT_objc_ownership_returns:
     HandleObjCOwnershipReturnsAttr(D, Attr, S); break;