Reapply r95546, no intended change in performance or functionality.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95552 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Checker/DomainSpecific/CocoaConventions.h b/include/clang/Checker/DomainSpecific/CocoaConventions.h
index b50b992..ee3d648 100644
--- a/include/clang/Checker/DomainSpecific/CocoaConventions.h
+++ b/include/clang/Checker/DomainSpecific/CocoaConventions.h
@@ -28,8 +28,8 @@
return deriveNamingConvention(S) == CreateRule;
}
- bool isRefType(QualType RetTy, const char* prefix,
- const char* name = 0);
+ bool isRefType(QualType RetTy, llvm::StringRef Prefix,
+ llvm::StringRef Name = llvm::StringRef());
bool isCFObjectRef(QualType T);
diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp
index 85d9dbd..324916a 100644
--- a/lib/Checker/CFRefCount.cpp
+++ b/lib/Checker/CFRefCount.cpp
@@ -705,7 +705,7 @@
RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
- RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, const char* FName);
+ RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, StringRef FName);
RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
ArgEffect ReceiverEff = DoNothing,
@@ -923,14 +923,12 @@
// Summary creation for functions (largely uses of Core Foundation).
//===----------------------------------------------------------------------===//
-static bool isRetain(FunctionDecl* FD, const char* FName) {
- const char* loc = strstr(FName, "Retain");
- return loc && loc[sizeof("Retain")-1] == '\0';
+static bool isRetain(FunctionDecl* FD, StringRef FName) {
+ return FName.endswith("Retain");
}
-static bool isRelease(FunctionDecl* FD, const char* FName) {
- const char* loc = strstr(FName, "Release");
- return loc && loc[sizeof("Release")-1] == '\0';
+static bool isRelease(FunctionDecl* FD, StringRef FName) {
+ return FName.endswith("Release");
}
RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
@@ -955,12 +953,12 @@
const IdentifierInfo *II = FD->getIdentifier();
if (!II)
break;
-
- const char* FName = II->getNameStart();
+
+ StringRef FName = II->getName();
// Strip away preceding '_'. Doing this here will effect all the checks
// down below.
- while (*FName == '_') ++FName;
+ FName = FName.substr(FName.find_first_not_of('_'));
// Inspect the result type.
QualType RetTy = FT->getResultType();
@@ -968,133 +966,63 @@
// FIXME: This should all be refactored into a chain of "summary lookup"
// filters.
assert(ScratchArgs.isEmpty());
-
- switch (strlen(FName)) {
- default: break;
- case 14:
- if (!memcmp(FName, "pthread_create", 14)) {
- // Part of: <rdar://problem/7299394>. This will be addressed
- // better with IPA.
- S = getPersistentStopSummary();
- }
- break;
- case 17:
- // Handle: id NSMakeCollectable(CFTypeRef)
- if (!memcmp(FName, "NSMakeCollectable", 17)) {
- S = (RetTy->isObjCIdType())
- ? getUnarySummary(FT, cfmakecollectable)
- : getPersistentStopSummary();
- }
- else if (!memcmp(FName, "IOBSDNameMatching", 17) ||
- !memcmp(FName, "IOServiceMatching", 17)) {
- // Part of <rdar://problem/6961230>. (IOKit)
- // This should be addressed using a API table.
- S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
- DoNothing, DoNothing);
- }
- break;
-
- case 21:
- if (!memcmp(FName, "IOServiceNameMatching", 21)) {
- // Part of <rdar://problem/6961230>. (IOKit)
- // This should be addressed using a API table.
- S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
- DoNothing, DoNothing);
- }
- break;
-
- case 24:
- if (!memcmp(FName, "IOServiceAddNotification", 24)) {
- // Part of <rdar://problem/6961230>. (IOKit)
- // This should be addressed using a API table.
- ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,DoNothing);
- }
- break;
-
- case 25:
- if (!memcmp(FName, "IORegistryEntryIDMatching", 25)) {
- // Part of <rdar://problem/6961230>. (IOKit)
- // This should be addressed using a API table.
- S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
- DoNothing, DoNothing);
- }
- break;
-
- case 26:
- if (!memcmp(FName, "IOOpenFirmwarePathMatching", 26)) {
- // Part of <rdar://problem/6961230>. (IOKit)
- // This should be addressed using a API table.
- S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
- DoNothing, DoNothing);
- }
- break;
-
- case 27:
- if (!memcmp(FName, "IOServiceGetMatchingService", 27)) {
- // Part of <rdar://problem/6961230>.
- // This should be addressed using a API table.
- ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
- }
- break;
-
- case 28:
- if (!memcmp(FName, "IOServiceGetMatchingServices", 28)) {
- // FIXES: <rdar://problem/6326900>
- // This should be addressed using a API table. This strcmp is also
- // a little gross, but there is no need to super optimize here.
- ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
- DoNothing);
- }
- else if (!memcmp(FName, "CVPixelBufferCreateWithBytes", 28)) {
- // FIXES: <rdar://problem/7283567>
- // Eventually this can be improved by recognizing that the pixel
- // buffer passed to CVPixelBufferCreateWithBytes is released via
- // a callback and doing full IPA to make sure this is done correctly.
- // FIXME: This function has an out parameter that returns an
- // allocated object.
- ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
- DoNothing);
- }
- break;
-
- case 29:
- if (!memcmp(FName, "CGBitmapContextCreateWithData", 29)) {
- // FIXES: <rdar://problem/7358899>
- // Eventually this can be improved by recognizing that 'releaseInfo'
- // passed to CGBitmapContextCreateWithData is released via
- // a callback and doing full IPA to make sure this is done correctly.
- ScratchArgs = AF.Add(ScratchArgs, 8, StopTracking);
- S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
- DoNothing,DoNothing);
- }
- break;
-
- case 32:
- if (!memcmp(FName, "IOServiceAddMatchingNotification", 32)) {
- // Part of <rdar://problem/6961230>.
- // This should be addressed using a API table.
- ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
- }
- break;
-
- case 34:
- if (!memcmp(FName, "CVPixelBufferCreateWithPlanarBytes", 34)) {
- // FIXES: <rdar://problem/7283567>
- // Eventually this can be improved by recognizing that the pixel
- // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
- // via a callback and doing full IPA to make sure this is done
- // correctly.
- ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
- DoNothing);
- }
- break;
+ if (FName == "pthread_create") {
+ // Part of: <rdar://problem/7299394>. This will be addressed
+ // better with IPA.
+ S = getPersistentStopSummary();
+ } else if (FName == "NSMakeCollectable") {
+ // Handle: id NSMakeCollectable(CFTypeRef)
+ S = (RetTy->isObjCIdType())
+ ? getUnarySummary(FT, cfmakecollectable)
+ : getPersistentStopSummary();
+ } else if (FName == "IOBSDNameMatching" ||
+ FName == "IOServiceMatching" ||
+ FName == "IOServiceNameMatching" ||
+ FName == "IORegistryEntryIDMatching" ||
+ FName == "IOOpenFirmwarePathMatching") {
+ // Part of <rdar://problem/6961230>. (IOKit)
+ // This should be addressed using a API table.
+ S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
+ DoNothing, DoNothing);
+ } else if (FName == "IOServiceGetMatchingService" ||
+ FName == "IOServiceGetMatchingServices") {
+ // FIXES: <rdar://problem/6326900>
+ // This should be addressed using a API table. This strcmp is also
+ // a little gross, but there is no need to super optimize here.
+ ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ } else if (FName == "IOServiceAddNotification" ||
+ FName == "IOServiceAddMatchingNotification") {
+ // Part of <rdar://problem/6961230>. (IOKit)
+ // This should be addressed using a API table.
+ ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ } else if (FName == "CVPixelBufferCreateWithBytes") {
+ // FIXES: <rdar://problem/7283567>
+ // Eventually this can be improved by recognizing that the pixel
+ // buffer passed to CVPixelBufferCreateWithBytes is released via
+ // a callback and doing full IPA to make sure this is done correctly.
+ // FIXME: This function has an out parameter that returns an
+ // allocated object.
+ ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ } else if (FName == "CGBitmapContextCreateWithData") {
+ // FIXES: <rdar://problem/7358899>
+ // Eventually this can be improved by recognizing that 'releaseInfo'
+ // passed to CGBitmapContextCreateWithData is released via
+ // a callback and doing full IPA to make sure this is done correctly.
+ ScratchArgs = AF.Add(ScratchArgs, 8, StopTracking);
+ S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
+ DoNothing, DoNothing);
+ } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
+ // FIXES: <rdar://problem/7283567>
+ // Eventually this can be improved by recognizing that the pixel
+ // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
+ // via a callback and doing full IPA to make sure this is done
+ // correctly.
+ ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
}
// Did we get a summary?
@@ -1118,7 +1046,7 @@
if (cocoa::isRefType(RetTy, "CF", FName)) {
if (isRetain(FD, FName))
S = getUnarySummary(FT, cfretain);
- else if (strstr(FName, "MakeCollectable"))
+ else if (FName.find("MakeCollectable") != StringRef::npos)
S = getUnarySummary(FT, cfmakecollectable);
else
S = getCFCreateGetRuleSummary(FD, FName);
@@ -1151,10 +1079,7 @@
// about that don't return a pointer type.
if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) {
// Test for 'CGCF'.
- if (FName[1] == 'G' && FName[2] == 'C' && FName[3] == 'F')
- FName += 4;
- else
- FName += 2;
+ FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
if (isRelease(FD, FName))
S = getUnarySummary(FT, cfrelease);
@@ -1201,12 +1126,13 @@
RetainSummary*
RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
- const char* FName) {
+ StringRef FName) {
- if (strstr(FName, "Create") || strstr(FName, "Copy"))
+ if (FName.find("Create") != StringRef::npos ||
+ FName.find("Copy") != StringRef::npos)
return getCFSummaryCreateRule(FD);
- if (strstr(FName, "Get"))
+ if (FName.find("Get") != StringRef::npos)
return getCFSummaryGetRule(FD);
return getDefaultSummary();
diff --git a/lib/Checker/CocoaConventions.cpp b/lib/Checker/CocoaConventions.cpp
index ff3a0c9..3ba887c 100644
--- a/lib/Checker/CocoaConventions.cpp
+++ b/lib/Checker/CocoaConventions.cpp
@@ -131,19 +131,18 @@
return C;
}
-bool cocoa::isRefType(QualType RetTy, const char* prefix,
- const char* name) {
-
+bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix,
+ llvm::StringRef 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"))
+ if (TDName.startswith(Prefix) && TDName.endswith("Ref"))
return true;
RetTy = TD->getDecl()->getUnderlyingType();
}
- if (!name)
+ if (Name.empty())
return false;
// Is the type void*?
@@ -152,7 +151,7 @@
return false;
// Does the name start with the prefix?
- return llvm::StringRef(name).startswith(prefix);
+ return Name.startswith(Prefix);
}
bool cocoa::isCFObjectRef(QualType T) {