diff options
Diffstat (limited to 'lib/Analysis/CocoaConventions.cpp')
-rw-r--r-- | lib/Analysis/CocoaConventions.cpp | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/lib/Analysis/CocoaConventions.cpp b/lib/Analysis/CocoaConventions.cpp index 946c38c..90f7092 100644 --- a/lib/Analysis/CocoaConventions.cpp +++ b/lib/Analysis/CocoaConventions.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines +// This file implements cocoa naming convention analysis. // //===----------------------------------------------------------------------===// @@ -36,8 +36,10 @@ using llvm::StringRef; // not release it." // -cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) { - switch (S.getMethodFamily()) { +cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S, + const ObjCMethodDecl *MD) { + switch (MD && MD->hasAttr<ObjCMethodFamilyAttr>()? MD->getMethodFamily() + : S.getMethodFamily()) { case OMF_None: case OMF_autorelease: case OMF_dealloc: @@ -45,6 +47,7 @@ cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) { case OMF_retain: case OMF_retainCount: case OMF_self: + case OMF_performSelector: return NoConvention; case OMF_init: @@ -83,12 +86,12 @@ bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix, return 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 coreFoundation::isCFObjectRef(QualType T) { + return cocoa::isRefType(T, "CF") || // Core Foundation. + cocoa::isRefType(T, "CG") || // Core Graphics. + cocoa::isRefType(T, "DADisk") || // Disk Arbitration API. + cocoa::isRefType(T, "DADissenter") || + cocoa::isRefType(T, "DASessionRef"); } @@ -123,3 +126,47 @@ bool cocoa::isCocoaObjectRef(QualType Ty) { return false; } + +bool coreFoundation::followsCreateRule(llvm::StringRef functionName) { + llvm::StringRef::iterator it = functionName.begin(); + llvm::StringRef::iterator start = it; + llvm::StringRef::iterator endI = functionName.end(); + + while (true) { + // Scan for the start of 'create' or 'copy'. + for ( ; it != endI ; ++it) { + // Search for the first character. It can either be 'C' or 'c'. + char ch = *it; + if (ch == 'C' || ch == 'c') { + ++it; + break; + } + } + + // Did we hit the end of the string? If so, we didn't find a match. + if (it == endI) + return false; + + // Scan for *lowercase* 'reate' or 'opy', followed by no lowercase + // character. + llvm::StringRef suffix = functionName.substr(it - start); + if (suffix.startswith("reate")) { + it += 5; + } + else if (suffix.startswith("opy")) { + it += 3; + } + else { + // Keep scanning. + continue; + } + + if (it == endI || !islower(*it)) + return true; + + // If we matched a lowercase character, it isn't the end of the + // word. Keep scanning. + } + + return false; +} |