Move some of the logic about classifying Objective-C methods into
conventional categories into Basic and AST.  Update the self-init checker
to use this logic;  CFRefCountChecker is complicated enough that I didn't
want to touch it.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126817 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 45f5188..3a7c2a6 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -398,6 +398,48 @@
   return this;
 }
 
+ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
+  ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
+  if (family != InvalidObjCMethodFamily)
+    return family;
+
+  family = getSelector().getMethodFamily();
+  switch (family) {
+  case OMF_None: break;
+
+  // init only has a conventional meaning for an instance method, and
+  // it has to return an object.
+  case OMF_init:
+    if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
+      family = OMF_None;
+    break;
+
+  // alloc/copy/new have a conventional meaning for both class and
+  // instance methods, but they require an object return.
+  case OMF_alloc:
+  case OMF_copy:
+  case OMF_mutableCopy:
+  case OMF_new:
+    if (!getResultType()->isObjCObjectPointerType())
+      family = OMF_None;
+    break;
+
+  // These selectors have a conventional meaning only for instance methods.
+  case OMF_dealloc:
+  case OMF_retain:
+  case OMF_release:
+  case OMF_autorelease:
+  case OMF_retainCount:
+    if (!isInstanceMethod())
+      family = OMF_None;
+    break;
+  }
+
+  // Cache the result.
+  Family = static_cast<unsigned>(family);
+  return family;
+}
+
 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
                                           const ObjCInterfaceDecl *OID) {
   QualType selfTy;