]> granicus.if.org Git - clang/commitdiff
Move more naming conventions logic out of the retain/release checker to CocoaConventi...
authorTed Kremenek <kremenek@apple.com>
Wed, 27 Jan 2010 18:00:17 +0000 (18:00 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 27 Jan 2010 18:00:17 +0000 (18:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94682 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Checker/DomainSpecific/CocoaConventions.h
lib/Checker/CFRefCount.cpp
lib/Checker/CocoaConventions.cpp

index e9b613349dd441f3362bed3c1595c2d10942db99..b50b9922244ff92af156040e137d6211a023d881 100644 (file)
 #define LLVM_CLANG_CHECKER_DS_COCOA
 
 #include "clang/Basic/IdentifierTable.h"
+#include "clang/AST/Type.h"
 
 namespace clang {
 namespace cocoa {
  
-enum NamingConvention { NoConvention, CreateRule, InitRule };
+  enum NamingConvention { NoConvention, CreateRule, InitRule };
 
-NamingConvention deriveNamingConvention(Selector S);
+  NamingConvention deriveNamingConvention(Selector S);
 
-static inline bool followsFundamentalRule(Selector S) {
-  return deriveNamingConvention(S) == CreateRule;
-}
+  static inline bool followsFundamentalRule(Selector S) {
+    return deriveNamingConvention(S) == CreateRule;
+  }
+  
+  bool isRefType(QualType RetTy, const char* prefix,
+                 const char* name = 0);
+  
+  bool isCFObjectRef(QualType T);
+  
+  bool isCocoaObjectRef(QualType T);
 
 }}
 
index cb59b5f93b8ff66613826bc3c63900c7888ffb89..6577219a4d8902cc70b759cc6c4df650f24df3cb 100644 (file)
@@ -73,34 +73,6 @@ public:
 };
 } // end anonymous namespace
 
-//===----------------------------------------------------------------------===//
-// Type querying functions.
-//===----------------------------------------------------------------------===//
-
-static bool isRefType(QualType RetTy, const char* prefix,
-                      const char* name = 0) {
-
-  // Recursively walk the typedef stack, allowing typedefs of reference types.
-  while (TypedefType* TD = dyn_cast<TypedefType>(RetTy.getTypePtr())) {
-    llvm::StringRef TDName = TD->getDecl()->getIdentifier()->getName();
-    if (TDName.startswith(prefix) && TDName.endswith("Ref"))
-      return true;
-
-    RetTy = TD->getDecl()->getUnderlyingType();
-  }
-
-  if (!name)
-    return false;
-
-  // Is the type void*?
-  const PointerType* PT = RetTy->getAs<PointerType>();
-  if (!(PT->getPointeeType().getUnqualifiedType()->isVoidType()))
-    return false;
-
-  // Does the name start with the prefix?
-  return llvm::StringRef(name).startswith(prefix);
-}
-
 //===----------------------------------------------------------------------===//
 // Primitives used for constructing summaries for function/method calls.
 //===----------------------------------------------------------------------===//
@@ -760,10 +732,6 @@ public:
 
   void InitializeClassMethodSummaries();
   void InitializeMethodSummaries();
-
-  bool isTrackedObjCObjectType(QualType T);
-  bool isTrackedCFObjectType(QualType T);
-
 private:
 
   void addClsMethSummary(IdentifierInfo* ClsII, Selector S,
@@ -951,51 +919,6 @@ RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff,
   return Summ;
 }
 
-//===----------------------------------------------------------------------===//
-// Predicates.
-//===----------------------------------------------------------------------===//
-
-bool RetainSummaryManager::isTrackedObjCObjectType(QualType Ty) {
-  if (!Ty->isObjCObjectPointerType())
-    return false;
-
-  const ObjCObjectPointerType *PT = Ty->getAs<ObjCObjectPointerType>();
-
-  // Can be true for objects with the 'NSObject' attribute.
-  if (!PT)
-    return true;
-
-  // We assume that id<..>, id, and "Class" all represent tracked objects.
-  if (PT->isObjCIdType() || PT->isObjCQualifiedIdType() ||
-      PT->isObjCClassType())
-    return true;
-
-  // Does the interface subclass NSObject?
-  // FIXME: We can memoize here if this gets too expensive.
-  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
-
-  // Assume that anything declared with a forward declaration and no
-  // @interface subclasses NSObject.
-  if (ID->isForwardDecl())
-    return true;
-
-  IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
-
-  for ( ; ID ; ID = ID->getSuperClass())
-    if (ID->getIdentifier() == NSObjectII)
-      return true;
-
-  return false;
-}
-
-bool RetainSummaryManager::isTrackedCFObjectType(QualType T) {
-  return isRefType(T, "CF") || // Core Foundation.
-         isRefType(T, "CG") || // Core Graphics.
-         isRefType(T, "DADisk") || // Disk Arbitration API.
-         isRefType(T, "DADissenter") ||
-         isRefType(T, "DASessionRef");
-}
-
 //===----------------------------------------------------------------------===//
 // Summary creation for functions (largely uses of Core Foundation).
 //===----------------------------------------------------------------------===//
@@ -1192,7 +1115,7 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
 
     if (RetTy->isPointerType()) {
       // For CoreFoundation ('CF') types.
-      if (isRefType(RetTy, "CF", FName)) {
+      if (cocoa::isRefType(RetTy, "CF", FName)) {
         if (isRetain(FD, FName))
           S = getUnarySummary(FT, cfretain);
         else if (strstr(FName, "MakeCollectable"))
@@ -1204,7 +1127,7 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
       }
 
       // For CoreGraphics ('CG') types.
-      if (isRefType(RetTy, "CG", FName)) {
+      if (cocoa::isRefType(RetTy, "CG", FName)) {
         if (isRetain(FD, FName))
           S = getUnarySummary(FT, cfretain);
         else
@@ -1214,9 +1137,9 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
       }
 
       // For the Disk Arbitration API (DiskArbitration/DADisk.h)
-      if (isRefType(RetTy, "DADisk") ||
-          isRefType(RetTy, "DADissenter") ||
-          isRefType(RetTy, "DASessionRef")) {
+      if (cocoa::isRefType(RetTy, "DADisk") ||
+          cocoa::isRefType(RetTy, "DADissenter") ||
+          cocoa::isRefType(RetTy, "DASessionRef")) {
         S = getCFCreateGetRuleSummary(FD, FName);
         break;
       }
@@ -1351,7 +1274,7 @@ RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
   assert(ScratchArgs.isEmpty());
   // 'init' methods conceptually return a newly allocated object and claim
   // the receiver.
-  if (isTrackedObjCObjectType(RetTy) || isTrackedCFObjectType(RetTy))
+  if (cocoa::isCocoaObjectRef(RetTy) || cocoa::isCFObjectRef(RetTy))
     return getPersistentSummary(ObjCInitRetE, DecRefMsg);
 
   return getDefaultSummary();
@@ -1366,7 +1289,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
   QualType RetTy = FD->getResultType();
 
   // Determine if there is a special return effect for this method.
-  if (isTrackedObjCObjectType(RetTy)) {
+  if (cocoa::isCocoaObjectRef(RetTy)) {
     if (FD->getAttr<NSReturnsRetainedAttr>()) {
       Summ.setRetEffect(ObjCAllocRetE);
     }
@@ -1390,7 +1313,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
   bool isTrackedLoc = false;
 
   // Determine if there is a special return effect for this method.
-  if (isTrackedObjCObjectType(MD->getResultType())) {
+  if (cocoa::isCocoaObjectRef(MD->getResultType())) {
     if (MD->getAttr<NSReturnsRetainedAttr>()) {
       Summ.setRetEffect(ObjCAllocRetE);
       return;
@@ -1440,7 +1363,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
   }
 
   // Look for methods that return an owned object.
-  if (isTrackedObjCObjectType(RetTy)) {
+  if (cocoa::isCocoaObjectRef(RetTy)) {
     // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
     //  by instance methods.
     RetEffect E = cocoa::followsFundamentalRule(S)
@@ -1450,7 +1373,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
   }
 
   // Look for methods that return an owned core foundation object.
-  if (isTrackedCFObjectType(RetTy)) {
+  if (cocoa::isCFObjectRef(RetTy)) {
     RetEffect E = cocoa::followsFundamentalRule(S)
       ? RetEffect::MakeOwned(RetEffect::CF, true)
       : RetEffect::MakeNotOwned(RetEffect::CF);
index 456b536d2dac7959df1006e6c324a2df23bd800a..ff3a0c97b419a7fd2c3fbc4283287a1156fbcad8 100644 (file)
@@ -12,6 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Checker/DomainSpecific/CocoaConventions.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/StringExtras.h"
 
 using namespace clang;
@@ -127,3 +130,67 @@ cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) {
   // after the prefix.
   return C;
 }
+
+bool cocoa::isRefType(QualType RetTy, const char* prefix,
+                      const char* name) {
+  
+  // Recursively walk the typedef stack, allowing typedefs of reference types.
+  while (TypedefType* TD = dyn_cast<TypedefType>(RetTy.getTypePtr())) {
+    llvm::StringRef TDName = TD->getDecl()->getIdentifier()->getName();
+    if (TDName.startswith(prefix) && TDName.endswith("Ref"))
+      return true;
+    
+    RetTy = TD->getDecl()->getUnderlyingType();
+  }
+  
+  if (!name)
+    return false;
+  
+  // Is the type void*?
+  const PointerType* PT = RetTy->getAs<PointerType>();
+  if (!(PT->getPointeeType().getUnqualifiedType()->isVoidType()))
+    return false;
+  
+  // Does the name start with the prefix?
+  return llvm::StringRef(name).startswith(prefix);
+}
+
+bool cocoa::isCFObjectRef(QualType T) {
+  return isRefType(T, "CF") || // Core Foundation.
+         isRefType(T, "CG") || // Core Graphics.
+         isRefType(T, "DADisk") || // Disk Arbitration API.
+         isRefType(T, "DADissenter") ||
+         isRefType(T, "DASessionRef");
+}
+
+
+bool cocoa::isCocoaObjectRef(QualType Ty) {
+  if (!Ty->isObjCObjectPointerType())
+    return false;
+  
+  const ObjCObjectPointerType *PT = Ty->getAs<ObjCObjectPointerType>();
+  
+  // Can be true for objects with the 'NSObject' attribute.
+  if (!PT)
+    return true;
+  
+  // We assume that id<..>, id, and "Class" all represent tracked objects.
+  if (PT->isObjCIdType() || PT->isObjCQualifiedIdType() ||
+      PT->isObjCClassType())
+    return true;
+  
+  // Does the interface subclass NSObject?
+  // FIXME: We can memoize here if this gets too expensive.
+  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
+  
+  // Assume that anything declared with a forward declaration and no
+  // @interface subclasses NSObject.
+  if (ID->isForwardDecl())
+    return true;
+  
+  for ( ; ID ; ID = ID->getSuperClass())
+    if (ID->getIdentifier()->getName() == "NSObject")
+      return true;
+  
+  return false;
+}