ObjectiveC migrator: Add another family of factory 
methods which can be migrated to instancetype.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187672 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index bd1f57f..706a4ec 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -42,7 +42,8 @@
   void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl,
                                  ObjCMethodDecl *OM);
   void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl,
-                            ObjCMethodDecl *OM);
+                            ObjCMethodDecl *OM,
+                            ObjCInstanceTypeFamily OIT_Family = OIT_None);
 
 public:
   std::string MigrateDir;
@@ -575,12 +576,12 @@
                                                        ObjCMethodDecl *OM) {
   ObjCInstanceTypeFamily OIT_Family =
     Selector::getInstTypeMethodFamily(OM->getSelector());
-  if (OIT_Family == OIT_None) {
-    migrateFactoryMethod(Ctx, CDecl, OM);
-    return;
-  }
+  
   std::string ClassName;
   switch (OIT_Family) {
+    case OIT_None:
+      migrateFactoryMethod(Ctx, CDecl, OM);
+      return;
     case OIT_Array:
       ClassName = "NSArray";
       break;
@@ -590,7 +591,8 @@
     case OIT_MemManage:
       ClassName = "NSObject";
       break;
-    default:
+    case OIT_Singleton:
+      migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton);
       return;
   }
   if (!OM->getResultType()->isObjCIdType())
@@ -624,7 +626,8 @@
 
 void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
                                                   ObjCContainerDecl *CDecl,
-                                                  ObjCMethodDecl *OM) {
+                                                  ObjCMethodDecl *OM,
+                                                  ObjCInstanceTypeFamily OIT_Family) {
   if (OM->isInstanceMethod() || !OM->getResultType()->isObjCIdType())
     return;
   
@@ -647,6 +650,19 @@
   
   IdentifierInfo *MethodIdName = OM->getSelector().getIdentifierInfoForSlot(0);
   std::string MethodName = MethodIdName->getName();
+  if (OIT_Family == OIT_Singleton) {
+    StringRef STRefMethodName(MethodName);
+    size_t len = 0;
+    if (STRefMethodName.startswith("standard"))
+      len = strlen("standard");
+    else if (STRefMethodName.startswith("shared"))
+      len = strlen("shared");
+    else if (STRefMethodName.startswith("default"))
+      len = strlen("default");
+    else
+      return;
+    MethodName = STRefMethodName.substr(len);
+  }
   std::string MethodNameSubStr = MethodName.substr(0, 3);
   StringRef MethodNamePrefix(MethodNameSubStr);
   std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower();
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 3572930..b1a22ee 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -467,6 +467,7 @@
       break;
     case 'd':
       if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
+      if (startsWithWord(name, "default")) return OIT_Singleton;
       break;
     case 'i':
       if (startsWithWord(name, "init")) return OIT_MemManage;
@@ -474,6 +475,10 @@
     case 'r':
       if (startsWithWord(name, "retain")) return OIT_MemManage;
       break;
+    case 's':
+      if (startsWithWord(name, "shared") ||
+          startsWithWord(name, "standard"))
+        return OIT_Singleton;
     default:
       break;
   }