r186349 - ObjC migrator: finding conforming protocol

Fariborz Jahanian fjahanian at apple.com
Mon Jul 15 14:22:08 PDT 2013


Author: fjahanian
Date: Mon Jul 15 16:22:08 2013
New Revision: 186349

URL: http://llvm.org/viewvc/llvm-project?rev=186349&view=rev
Log:
ObjC migrator: finding conforming protocol
candidates for each class. wip.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
    cfe/trunk/lib/AST/ASTContext.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=186349&r1=186348&r2=186349&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jul 15 16:22:08 2013
@@ -1717,6 +1717,9 @@ public:
            getCanonicalType(T2).getTypePtr();
   }
 
+  bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
+                           const ObjCMethodDecl *MethodImp);
+  
   bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
   
   /// \brief Retrieves the "canonical" nested name specifier for a

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=186349&r1=186348&r2=186349&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Mon Jul 15 16:22:08 2013
@@ -238,8 +238,50 @@ void ObjCMigrateASTConsumer::migrateObjC
 static bool 
 ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
                                       const ObjCImplementationDecl *ImpDecl,
+                                       const ObjCInterfaceDecl *IDecl,
                                       ObjCProtocolDecl *Protocol) {
-  return false;
+  // In auto-synthesis, protocol properties are not synthesized. So,
+  // a conforming protocol must have its required properties declared
+  // in class interface.
+  if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition())
+    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+         E = PDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Property = *P;
+      if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional)
+        continue;
+      DeclContext::lookup_const_result R = IDecl->lookup(Property->getDeclName());
+      for (unsigned I = 0, N = R.size(); I != N; ++I) {
+        if (ObjCPropertyDecl *ClassProperty = dyn_cast<ObjCPropertyDecl>(R[0])) {
+          if (ClassProperty->getPropertyAttributes()
+              != Property->getPropertyAttributes())
+            return false;
+          if (!Ctx.hasSameType(ClassProperty->getType(), Property->getType()))
+            return false;
+        }
+      }
+    }
+  // At this point, all required properties in this protocol conform to those
+  // declared in the class.
+  // Check that class implements the required methods of the protocol too.
+  if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition())
+    for (ObjCContainerDecl::method_iterator M = PDecl->meth_begin(),
+         MEnd = PDecl->meth_end(); M != MEnd; ++M) {
+      ObjCMethodDecl *MD = (*M);
+      if (MD->getImplementationControl() == ObjCMethodDecl::Optional)
+        continue;
+      bool match = false;
+      DeclContext::lookup_const_result R = ImpDecl->lookup(MD->getDeclName());
+      for (unsigned I = 0, N = R.size(); I != N; ++I)
+        if (ObjCMethodDecl *ImpMD = dyn_cast<ObjCMethodDecl>(R[0]))
+          if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) {
+            match = true;
+            break;
+          }
+      if (!match)
+        return false;
+    }
+
+  return true;
 }
 
 void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,
@@ -267,7 +309,7 @@ void ObjCMigrateASTConsumer::migrateProt
   // methods and properties, then this class conforms to this protocol.
   llvm::SmallVector<ObjCProtocolDecl*, 8> ConformingProtocols;
   for (unsigned i = 0, e = PotentialImplicitProtocols.size(); i != e; i++)
-    if (ClassImplementsAllMethodsAndProperties(Ctx, ImpDecl, 
+    if (ClassImplementsAllMethodsAndProperties(Ctx, ImpDecl, IDecl,
                                               PotentialImplicitProtocols[i]))
       ConformingProtocols.push_back(PotentialImplicitProtocols[i]);
 }

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=186349&r1=186348&r2=186349&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jul 15 16:22:08 2013
@@ -8129,3 +8129,35 @@ ASTContext::getParents(const ast_type_tr
   }
   return I->second;
 }
+
+bool
+ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
+                                const ObjCMethodDecl *MethodImpl) {
+  // No point trying to match an unavailable/deprecated mothod.
+  if (MethodDecl->hasAttr<UnavailableAttr>()
+      || MethodDecl->hasAttr<DeprecatedAttr>())
+    return false;
+  if (MethodDecl->getObjCDeclQualifier() !=
+      MethodImpl->getObjCDeclQualifier())
+    return false;
+  if (!hasSameType(MethodDecl->getResultType(),
+                   MethodImpl->getResultType()))
+    return false;
+  
+  if (MethodDecl->param_size() != MethodImpl->param_size())
+    return false;
+  
+  for (ObjCMethodDecl::param_const_iterator IM = MethodImpl->param_begin(),
+       IF = MethodDecl->param_begin(), EM = MethodImpl->param_end(),
+       EF = MethodDecl->param_end();
+       IM != EM && IF != EF; ++IM, ++IF) {
+    const ParmVarDecl *DeclVar = (*IF);
+    const ParmVarDecl *ImplVar = (*IM);
+    if (ImplVar->getObjCDeclQualifier() != DeclVar->getObjCDeclQualifier())
+      return false;
+    if (!hasSameType(DeclVar->getType(), ImplVar->getType()))
+      return false;
+  }
+  return (MethodDecl->isVariadic() == MethodImpl->isVariadic());
+  
+}





More information about the cfe-commits mailing list