1 //===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
14 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
15 #include "clang/AST/Type.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "llvm/ADT/StringExtras.h"
20 using namespace clang
;
23 using llvm::StringRef
;
25 // The "fundamental rule" for naming conventions of methods:
26 // (url broken into two lines)
27 // http://developer.apple.com/documentation/Cocoa/Conceptual/
28 // MemoryMgmt/Tasks/MemoryManagementRules.html
30 // "You take ownership of an object if you create it using a method whose name
31 // begins with "alloc" or "new" or contains "copy" (for example, alloc,
32 // newObject, or mutableCopy), or if you send it a retain message. You are
33 // responsible for relinquishing ownership of objects you own using release
34 // or autorelease. Any other time you receive an object, you must
38 static bool isWordEnd(char ch
, char prev
, char next
) {
40 || (islower(prev
) && isupper(ch
)) // xxxC
41 || (isupper(prev
) && isupper(ch
) && islower(next
)) // XXCreate
45 static const char* parseWord(const char* s
) {
46 char ch
= *s
, prev
= '\0';
49 while (!isWordEnd(ch
, prev
, next
)) {
57 cocoa::NamingConvention
cocoa::deriveNamingConvention(Selector S
,
59 IdentifierInfo
*II
= S
.getIdentifierInfoForSlot(0);
64 const char *s
= II
->getNameStart();
67 // A method/function name may contain a prefix. We don't know it is there,
68 // however, until we encounter the first '_'.
70 // Skip '_', numbers, ':', etc.
71 if (*s
== '_' || !isalpha(*s
)) {
78 if (!ignorePrefix
&& s
!= orig
)
81 // Parse the first word, and look for specific keywords.
82 const char *wordEnd
= parseWord(s
);
84 unsigned len
= wordEnd
- s
;
90 // Methods starting with 'new' follow the create rule.
91 return (memcmp(s
, "new", 3) == 0) ? CreateRule
: NoConvention
;
93 // Methods starting with 'copy' follow the create rule.
94 if (memcmp(s
, "copy", 4) == 0)
96 // Methods starting with 'init' follow the init rule.
97 if (memcmp(s
, "init", 4) == 0)
101 return (memcmp(s
, "alloc", 5) == 0) ? CreateRule
: NoConvention
;
103 // Methods starting with 'mutableCopy' follow the create rule.
104 if (memcmp(s
, "mutable", 7) == 0) {
105 // Look at the next word to see if it is "Copy".
108 wordEnd
= parseWord(s
);
110 if (len
== 4 && memcmp(s
, "Copy", 4) == 0)
118 bool cocoa::isRefType(QualType RetTy
, llvm::StringRef Prefix
,
119 llvm::StringRef Name
) {
120 // Recursively walk the typedef stack, allowing typedefs of reference types.
121 while (const TypedefType
*TD
= dyn_cast
<TypedefType
>(RetTy
.getTypePtr())) {
122 llvm::StringRef TDName
= TD
->getDecl()->getIdentifier()->getName();
123 if (TDName
.startswith(Prefix
) && TDName
.endswith("Ref"))
126 RetTy
= TD
->getDecl()->getUnderlyingType();
132 // Is the type void*?
133 const PointerType
* PT
= RetTy
->getAs
<PointerType
>();
134 if (!(PT
->getPointeeType().getUnqualifiedType()->isVoidType()))
137 // Does the name start with the prefix?
138 return Name
.startswith(Prefix
);
141 bool cocoa::isCFObjectRef(QualType T
) {
142 return isRefType(T
, "CF") || // Core Foundation.
143 isRefType(T
, "CG") || // Core Graphics.
144 isRefType(T
, "DADisk") || // Disk Arbitration API.
145 isRefType(T
, "DADissenter") ||
146 isRefType(T
, "DASessionRef");
150 bool cocoa::isCocoaObjectRef(QualType Ty
) {
151 if (!Ty
->isObjCObjectPointerType())
154 const ObjCObjectPointerType
*PT
= Ty
->getAs
<ObjCObjectPointerType
>();
156 // Can be true for objects with the 'NSObject' attribute.
160 // We assume that id<..>, id, Class, and Class<..> all represent tracked
162 if (PT
->isObjCIdType() || PT
->isObjCQualifiedIdType() ||
163 PT
->isObjCClassType() || PT
->isObjCQualifiedClassType())
166 // Does the interface subclass NSObject?
167 // FIXME: We can memoize here if this gets too expensive.
168 const ObjCInterfaceDecl
*ID
= PT
->getInterfaceDecl();
170 // Assume that anything declared with a forward declaration and no
171 // @interface subclasses NSObject.
172 if (ID
->isForwardDecl())
175 for ( ; ID
; ID
= ID
->getSuperClass())
176 if (ID
->getIdentifier()->getName() == "NSObject")