summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-15 16:50:12 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-15 16:50:12 +0000
commitfa89e2f09c6185d7a4bb7dae89922966c07aaf88 (patch)
tree8b0df0f8855096fe16bece96f40855e08d08498c /clang/lib/Analysis/CFRefCount.cpp
parent9d1f497a28c5e86c7753ff914e1a0b463296188f (diff)
downloadbcm5719-llvm-fa89e2f09c6185d7a4bb7dae89922966c07aaf88.tar.gz
bcm5719-llvm-fa89e2f09c6185d7a4bb7dae89922966c07aaf88.zip
Support retain/release tracking for CoreGraphics (CGxxxRef) objects.
llvm-svn: 53617
Diffstat (limited to 'clang/lib/Analysis/CFRefCount.cpp')
-rw-r--r--clang/lib/Analysis/CFRefCount.cpp95
1 files changed, 83 insertions, 12 deletions
diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
index 4de91daa1b8..1777071c699 100644
--- a/clang/lib/Analysis/CFRefCount.cpp
+++ b/clang/lib/Analysis/CFRefCount.cpp
@@ -73,6 +73,29 @@ static bool isCFRefType(QualType T) {
return true;
}
+static bool isCGRefType(QualType T) {
+
+ if (!T->isPointerType())
+ return false;
+
+ // Check the typedef for the name "CG" and the substring "Ref".
+ TypedefType* TD = dyn_cast<TypedefType>(T.getTypePtr());
+
+ if (!TD)
+ return false;
+
+ const char* TDName = TD->getDecl()->getIdentifier()->getName();
+ assert (TDName);
+
+ if (TDName[0] != 'C' || TDName[1] != 'G')
+ return false;
+
+ if (strstr(TDName, "Ref") == 0)
+ return false;
+
+ return true;
+}
+
static bool isNSType(QualType T) {
if (!T->isPointerType())
@@ -468,9 +491,11 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
RetainSummary* getNSSummary(FunctionDecl* FD, const char* FName);
RetainSummary* getCFSummary(FunctionDecl* FD, const char* FName);
+ RetainSummary* getCGSummary(FunctionDecl* FD, const char* FName);
RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
+ RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, const char* FName);
RetainSummary* getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
ArgEffect ReceiverEff = DoNothing,
@@ -630,13 +655,29 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
RetainSummary *S = 0;
FunctionType* FT = dyn_cast<FunctionType>(FD->getType());
-
- if (FT && isCFRefType(FT->getResultType()))
- S = getCFSummary(FD, FName);
- else if (FName[0] == 'C' && FName[1] == 'F')
- S = getCFSummary(FD, FName);
- else if (FName[0] == 'N' && FName[1] == 'S')
- S = getNSSummary(FD, FName);
+
+ do {
+ if (FT) {
+
+ QualType T = FT->getResultType();
+
+ if (isCFRefType(T)) {
+ S = getCFSummary(FD, FName);
+ break;
+ }
+
+ if (isCGRefType(T)) {
+ S = getCGSummary(FD, FName );
+ break;
+ }
+ }
+
+ if (FName[0] == 'C' && FName[1] == 'F')
+ S = getCFSummary(FD, FName);
+ else if (FName[0] == 'N' && FName[1] == 'S')
+ S = getNSSummary(FD, FName);
+ }
+ while (0);
FuncSummaries[FD] = S;
return S;
@@ -651,25 +692,55 @@ RetainSummary* RetainSummaryManager::getNSSummary(FunctionDecl* FD,
return 0;
}
-
+
+static bool isRetain(FunctionDecl* FD, const char* FName) {
+ return (strstr(FName, "Retain") != 0);
+}
+
+static bool isRelease(FunctionDecl* FD, const char* FName) {
+ return (strstr(FName, "Release") != 0);
+}
+
RetainSummary* RetainSummaryManager::getCFSummary(FunctionDecl* FD,
const char* FName) {
if (FName[0] == 'C' && FName[1] == 'F')
FName += 2;
- if (strcmp(FName, "Retain") == 0)
+ if (isRetain(FD, FName))
return getUnarySummary(FD, cfretain);
- if (strcmp(FName, "Release") == 0)
+ if (isRelease(FD, FName))
return getUnarySummary(FD, cfrelease);
if (strcmp(FName, "MakeCollectable") == 0)
return getUnarySummary(FD, cfmakecollectable);
-
+
+ return getCFCreateGetRuleSummary(FD, FName);
+}
+
+RetainSummary* RetainSummaryManager::getCGSummary(FunctionDecl* FD,
+ const char* FName) {
+
+ if (FName[0] == 'C' && FName[1] == 'G')
+ FName += 2;
+
+ if (isRelease(FD, FName))
+ return getUnarySummary(FD, cfrelease);
+
+ if (isRetain(FD, FName))
+ return getUnarySummary(FD, cfretain);
+
+ return getCFCreateGetRuleSummary(FD, FName);
+}
+
+RetainSummary*
+RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
+ const char* FName) {
+
if (strstr(FName, "Create") || strstr(FName, "Copy"))
return getCFSummaryCreateRule(FD);
-
+
if (strstr(FName, "Get"))
return getCFSummaryGetRule(FD);
OpenPOWER on IntegriCloud