aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/CocoaConventions.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-01-27 18:00:17 +0000
committerTed Kremenek <kremenek@apple.com>2010-01-27 18:00:17 +0000
commit78acdbfb522f62b6e8899e078e48fea44fda287d (patch)
tree347d821b1539719cde594fcafc01d5023394c165 /lib/Checker/CocoaConventions.cpp
parent8b752f10c394b140f9ef89e049cbad1a7676fc25 (diff)
Move more naming conventions logic out of the retain/release checker to CocoaConventions.h.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/CocoaConventions.cpp')
-rw-r--r--lib/Checker/CocoaConventions.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/Checker/CocoaConventions.cpp b/lib/Checker/CocoaConventions.cpp
index 456b536d2d..ff3a0c97b4 100644
--- a/lib/Checker/CocoaConventions.cpp
+++ b/lib/Checker/CocoaConventions.cpp
@@ -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;
+}