[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