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