summaryrefslogtreecommitdiffstats
path: root/clang/lib/ARCMigrate/ObjCMT.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/ARCMigrate/ObjCMT.cpp')
-rw-r--r--clang/lib/ARCMigrate/ObjCMT.cpp46
1 files changed, 44 insertions, 2 deletions
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp
index 01531668603..18919faa9a4 100644
--- a/clang/lib/ARCMigrate/ObjCMT.cpp
+++ b/clang/lib/ARCMigrate/ObjCMT.cpp
@@ -238,8 +238,50 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
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::migrateProtocolConformance(ASTContext &Ctx,
// 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]);
}
OpenPOWER on IntegriCloud