Hook up __attribute__((objc_ownership_returns)) to the retain/release checker.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70002 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 4961ef4..9080e66 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -722,6 +722,7 @@
   RetainSummary* getMethodSummary(ObjCMessageExpr* ME, ObjCInterfaceDecl* ID);
   RetainSummary* getClassMethodSummary(ObjCMessageExpr *ME);
   RetainSummary* getCommonMethodSummary(ObjCMessageExpr *ME, Selector S);
+  RetainSummary* getMethodSummaryFromAnnotations(ObjCMethodDecl *MD);
   
   bool isGCEnabled() const { return GCEnabled; }
 };
@@ -1072,6 +1073,33 @@
   return Summ;
 }
 
+RetainSummary*
+RetainSummaryManager::getMethodSummaryFromAnnotations(ObjCMethodDecl *MD) {
+  if (!MD)
+    return 0;
+  
+  assert(ScratchArgs.empty());
+  
+  // Determine if there is a special return effect for this method.
+  bool hasRetEffect = false;
+  RetEffect RE = RetEffect::MakeNoRet();
+  
+  if (isTrackedObjectType(MD->getResultType())) {
+    if (MD->getAttr<ObjCOwnershipReturnsAttr>()) {
+      RE = RetEffect::MakeOwned(RetEffect::ObjC, true);
+      hasRetEffect = true;
+    }
+    else {
+      // Default to 'not owned'.
+      RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
+    }
+  }
+  
+  if (!hasRetEffect)
+    return 0;
+
+  return getPersistentSummary(RE);
+}
 
 RetainSummary*
 RetainSummaryManager::getCommonMethodSummary(ObjCMessageExpr* ME, Selector S) {
@@ -1137,14 +1165,21 @@
   if (I != ObjCMethodSummaries.end())
     return I->second;
 
-  // "initXXX": pass-through for receiver.
   assert(ScratchArgs.empty());
+
+  // Annotations take precedence over all other ways to derive
+  // summaries.
+  RetainSummary *Summ = getMethodSummaryFromAnnotations(ME->getMethodDecl());
   
-  if (deriveNamingConvention(S.getIdentifierInfoForSlot(0)->getName()) 
-      == InitRule)
-    return getInitMethodSummary(ME);
+  if (!Summ) {      
+    // "initXXX": pass-through for receiver.
+    if (deriveNamingConvention(S.getIdentifierInfoForSlot(0)->getName()) 
+        == InitRule)
+      return getInitMethodSummary(ME);
   
-  RetainSummary *Summ = getCommonMethodSummary(ME, S);
+    Summ = getCommonMethodSummary(ME, S);
+  }
+
   ObjCMethodSummaries[ME] = Summ;
   return Summ;
 }
@@ -1153,7 +1188,7 @@
 RetainSummaryManager::getClassMethodSummary(ObjCMessageExpr *ME) {
 
   Selector S = ME->getSelector();
-  ObjCMethodSummariesTy::iterator I;
+  ObjCMethodSummariesTy::iterator I;  
   
   if (ObjCInterfaceDecl *ID = ME->getClassInfo().first) {
     // Lookup the method using the decl for the class @interface.
@@ -1170,7 +1205,13 @@
   if (I != ObjCClassMethodSummaries.end())
     return I->second;
   
-  RetainSummary* Summ = getCommonMethodSummary(ME, S);
+  // Annotations take precedence over all other ways to derive
+  // summaries.
+  RetainSummary *Summ = getMethodSummaryFromAnnotations(ME->getMethodDecl());
+  
+  if (!Summ)
+    Summ = getCommonMethodSummary(ME, S);
+  
   ObjCClassMethodSummaries[ObjCSummaryKey(ME->getClassName(), S)] = Summ;
   return Summ;
 }