diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-01-27 18:00:17 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-01-27 18:00:17 +0000 |
commit | 78acdbfb522f62b6e8899e078e48fea44fda287d (patch) | |
tree | 347d821b1539719cde594fcafc01d5023394c165 /lib/Checker/CocoaConventions.cpp | |
parent | 8b752f10c394b140f9ef89e049cbad1a7676fc25 (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.cpp | 67 |
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; +} |