[cfe-commits] r94662 - in /cfe/trunk: include/clang/Checker/DomainSpecific/ include/clang/Checker/DomainSpecific/CocoaConventions.h include/clang/Checker/PathSensitive/SummaryManager.h lib/Checker/CFRefCount.cpp lib/Checker/CocoaConventions.cpp
Ted Kremenek
kremenek at apple.com
Tue Jan 26 22:13:49 PST 2010
Author: kremenek
Date: Wed Jan 27 00:13:48 2010
New Revision: 94662
URL: http://llvm.org/viewvc/llvm-project?rev=94662&view=rev
Log:
Start pulling out pieces of the monolithic retain/release checker into
reusable and modular API pieces.
Start by pulling the logic for deriving the Cocoa naming convention
into a separate API, header, and source file.
Added:
cfe/trunk/include/clang/Checker/DomainSpecific/
cfe/trunk/include/clang/Checker/DomainSpecific/CocoaConventions.h
cfe/trunk/include/clang/Checker/PathSensitive/SummaryManager.h
cfe/trunk/lib/Checker/CocoaConventions.cpp
Modified:
cfe/trunk/lib/Checker/CFRefCount.cpp
Added: cfe/trunk/include/clang/Checker/DomainSpecific/CocoaConventions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/DomainSpecific/CocoaConventions.h?rev=94662&view=auto
==============================================================================
--- cfe/trunk/include/clang/Checker/DomainSpecific/CocoaConventions.h (added)
+++ cfe/trunk/include/clang/Checker/DomainSpecific/CocoaConventions.h Wed Jan 27 00:13:48 2010
@@ -0,0 +1,32 @@
+//===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_DS_COCOA
+#define LLVM_CLANG_CHECKER_DS_COCOA
+
+#include "clang/Basic/IdentifierTable.h"
+
+namespace clang {
+namespace cocoa {
+
+enum NamingConvention { NoConvention, CreateRule, InitRule };
+
+NamingConvention deriveNamingConvention(Selector S);
+
+static inline bool followsFundamentalRule(Selector S) {
+ return deriveNamingConvention(S) == CreateRule;
+}
+
+}}
+
+#endif
Added: cfe/trunk/include/clang/Checker/PathSensitive/SummaryManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/SummaryManager.h?rev=94662&view=auto
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/SummaryManager.h (added)
+++ cfe/trunk/include/clang/Checker/PathSensitive/SummaryManager.h Wed Jan 27 00:13:48 2010
@@ -0,0 +1,57 @@
+//== SummaryManager.h - Generic handling of function summaries --*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines SummaryManager and related classes, which provides
+// a generic mechanism for managing function summaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_SUMMARY
+#define LLVM_CLANG_CHECKER_SUMMARY
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+namespace summMgr {
+
+
+/* Key kinds:
+
+ - C functions
+ - C++ functions (name + parameter types)
+ - ObjC methods:
+ - Class, selector (class method)
+ - Class, selector (instance method)
+ - Category, selector (instance method)
+ - Protocol, selector (instance method)
+ - C++ methods
+ - Class, function name + parameter types + const
+ */
+
+class SummaryKey {
+
+};
+
+} // end namespace clang::summMgr
+
+class SummaryManagerImpl {
+
+};
+
+
+template <typename T>
+class SummaryManager : SummaryManagerImpl {
+
+};
+
+} // end clang namespace
+
+#endif
Modified: cfe/trunk/lib/Checker/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CFRefCount.cpp?rev=94662&r1=94661&r2=94662&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Checker/CFRefCount.cpp Wed Jan 27 00:13:48 2010
@@ -23,6 +23,7 @@
#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/DomainSpecific/CocoaConventions.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "llvm/ADT/DenseMap.h"
@@ -34,129 +35,8 @@
#include <stdarg.h>
using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Utility functions.
-//===----------------------------------------------------------------------===//
-
-// The "fundamental rule" for naming conventions of methods:
-// (url broken into two lines)
-// http://developer.apple.com/documentation/Cocoa/Conceptual/
-// MemoryMgmt/Tasks/MemoryManagementRules.html
-//
-// "You take ownership of an object if you create it using a method whose name
-// begins with "alloc" or "new" or contains "copy" (for example, alloc,
-// newObject, or mutableCopy), or if you send it a retain message. You are
-// responsible for relinquishing ownership of objects you own using release
-// or autorelease. Any other time you receive an object, you must
-// not release it."
-//
-
-using llvm::StrInStrNoCase;
using llvm::StringRef;
-
-enum NamingConvention { NoConvention, CreateRule, InitRule };
-
-static inline bool isWordEnd(char ch, char prev, char next) {
- return ch == '\0'
- || (islower(prev) && isupper(ch)) // xxxC
- || (isupper(prev) && isupper(ch) && islower(next)) // XXCreate
- || !isalpha(ch);
-}
-
-static inline const char* parseWord(const char* s) {
- char ch = *s, prev = '\0';
- assert(ch != '\0');
- char next = *(s+1);
- while (!isWordEnd(ch, prev, next)) {
- prev = ch;
- ch = next;
- next = *((++s)+1);
- }
- return s;
-}
-
-static NamingConvention deriveNamingConvention(Selector S) {
- IdentifierInfo *II = S.getIdentifierInfoForSlot(0);
-
- if (!II)
- return NoConvention;
-
- const char *s = II->getNameStart();
-
- // A method/function name may contain a prefix. We don't know it is there,
- // however, until we encounter the first '_'.
- bool InPossiblePrefix = true;
- bool AtBeginning = true;
- NamingConvention C = NoConvention;
-
- while (*s != '\0') {
- // Skip '_'.
- if (*s == '_') {
- if (InPossiblePrefix) {
- // If we already have a convention, return it. Otherwise, skip
- // the prefix as if it wasn't there.
- if (C != NoConvention)
- break;
-
- InPossiblePrefix = false;
- AtBeginning = true;
- assert(C == NoConvention);
- }
- ++s;
- continue;
- }
-
- // Skip numbers, ':', etc.
- if (!isalpha(*s)) {
- ++s;
- continue;
- }
-
- const char *wordEnd = parseWord(s);
- assert(wordEnd > s);
- unsigned len = wordEnd - s;
-
- switch (len) {
- default:
- break;
- case 3:
- // Methods starting with 'new' follow the create rule.
- if (AtBeginning && StringRef(s, len).equals_lower("new"))
- C = CreateRule;
- break;
- case 4:
- // Methods starting with 'alloc' or contain 'copy' follow the
- // create rule
- if (C == NoConvention && StringRef(s, len).equals_lower("copy"))
- C = CreateRule;
- else // Methods starting with 'init' follow the init rule.
- if (AtBeginning && StringRef(s, len).equals_lower("init"))
- C = InitRule;
- break;
- case 5:
- if (AtBeginning && StringRef(s, len).equals_lower("alloc"))
- C = CreateRule;
- break;
- }
-
- // If we aren't in the prefix and have a derived convention then just
- // return it now.
- if (!InPossiblePrefix && C != NoConvention)
- return C;
-
- AtBeginning = false;
- s = wordEnd;
- }
-
- // We will get here if there wasn't more than one word
- // after the prefix.
- return C;
-}
-
-static bool followsFundamentalRule(Selector S) {
- return deriveNamingConvention(S) == CreateRule;
-}
+using llvm::StrInStrNoCase;
static const ObjCMethodDecl*
ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
@@ -1563,7 +1443,7 @@
if (isTrackedObjCObjectType(RetTy)) {
// EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
// by instance methods.
- RetEffect E = followsFundamentalRule(S)
+ RetEffect E = cocoa::followsFundamentalRule(S)
? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC);
return getPersistentSummary(E, ReceiverEff, MayEscape);
@@ -1571,7 +1451,7 @@
// Look for methods that return an owned core foundation object.
if (isTrackedCFObjectType(RetTy)) {
- RetEffect E = followsFundamentalRule(S)
+ RetEffect E = cocoa::followsFundamentalRule(S)
? RetEffect::MakeOwned(RetEffect::CF, true)
: RetEffect::MakeNotOwned(RetEffect::CF);
@@ -1653,7 +1533,7 @@
assert(ScratchArgs.isEmpty());
// "initXXX": pass-through for receiver.
- if (deriveNamingConvention(S) == InitRule)
+ if (cocoa::deriveNamingConvention(S) == cocoa::InitRule)
Summ = getInitMethodSummary(RetTy);
else
Summ = getCommonMethodSummary(MD, S, RetTy);
Added: cfe/trunk/lib/Checker/CocoaConventions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CocoaConventions.cpp?rev=94662&view=auto
==============================================================================
--- cfe/trunk/lib/Checker/CocoaConventions.cpp (added)
+++ cfe/trunk/lib/Checker/CocoaConventions.cpp Wed Jan 27 00:13:48 2010
@@ -0,0 +1,129 @@
+//===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/DomainSpecific/CocoaConventions.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace clang;
+
+using llvm::StringRef;
+
+// The "fundamental rule" for naming conventions of methods:
+// (url broken into two lines)
+// http://developer.apple.com/documentation/Cocoa/Conceptual/
+// MemoryMgmt/Tasks/MemoryManagementRules.html
+//
+// "You take ownership of an object if you create it using a method whose name
+// begins with "alloc" or "new" or contains "copy" (for example, alloc,
+// newObject, or mutableCopy), or if you send it a retain message. You are
+// responsible for relinquishing ownership of objects you own using release
+// or autorelease. Any other time you receive an object, you must
+// not release it."
+//
+
+static bool isWordEnd(char ch, char prev, char next) {
+ return ch == '\0'
+ || (islower(prev) && isupper(ch)) // xxxC
+ || (isupper(prev) && isupper(ch) && islower(next)) // XXCreate
+ || !isalpha(ch);
+}
+
+static const char* parseWord(const char* s) {
+ char ch = *s, prev = '\0';
+ assert(ch != '\0');
+ char next = *(s+1);
+ while (!isWordEnd(ch, prev, next)) {
+ prev = ch;
+ ch = next;
+ next = *((++s)+1);
+ }
+ return s;
+}
+
+cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) {
+ IdentifierInfo *II = S.getIdentifierInfoForSlot(0);
+
+ if (!II)
+ return NoConvention;
+
+ const char *s = II->getNameStart();
+
+ // A method/function name may contain a prefix. We don't know it is there,
+ // however, until we encounter the first '_'.
+ bool InPossiblePrefix = true;
+ bool AtBeginning = true;
+ NamingConvention C = NoConvention;
+
+ while (*s != '\0') {
+ // Skip '_'.
+ if (*s == '_') {
+ if (InPossiblePrefix) {
+ // If we already have a convention, return it. Otherwise, skip
+ // the prefix as if it wasn't there.
+ if (C != NoConvention)
+ break;
+
+ InPossiblePrefix = false;
+ AtBeginning = true;
+ assert(C == NoConvention);
+ }
+ ++s;
+ continue;
+ }
+
+ // Skip numbers, ':', etc.
+ if (!isalpha(*s)) {
+ ++s;
+ continue;
+ }
+
+ const char *wordEnd = parseWord(s);
+ assert(wordEnd > s);
+ unsigned len = wordEnd - s;
+
+ switch (len) {
+ default:
+ break;
+ case 3:
+ // Methods starting with 'new' follow the create rule.
+ if (AtBeginning && StringRef(s, len).equals_lower("new"))
+ C = CreateRule;
+ break;
+ case 4:
+ // Methods starting with 'alloc' or contain 'copy' follow the
+ // create rule
+ if (C == NoConvention && StringRef(s, len).equals_lower("copy"))
+ C = CreateRule;
+ else // Methods starting with 'init' follow the init rule.
+ if (AtBeginning && StringRef(s, len).equals_lower("init"))
+ C = InitRule;
+ break;
+ case 5:
+ if (AtBeginning && StringRef(s, len).equals_lower("alloc"))
+ C = CreateRule;
+ break;
+ }
+
+ // If we aren't in the prefix and have a derived convention then just
+ // return it now.
+ if (!InPossiblePrefix && C != NoConvention)
+ return C;
+
+ AtBeginning = false;
+ s = wordEnd;
+ }
+
+ // We will get here if there wasn't more than one word
+ // after the prefix.
+ return C;
+}
More information about the cfe-commits
mailing list