From a7437f02279194a2c2800df3777a8843f0485ba9 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 3 Jul 2013 23:05:00 +0000 Subject: [PATCH] [ObjectiveC Migration]: Provide knobs for migrating setter/getter methods to an eventual property declaraiton. This is wip. // rdar://14345082 llvm-svn: 185591 --- clang/lib/ARCMigrate/ObjCMT.cpp | 51 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 57fac03..8f56648 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -32,6 +32,7 @@ namespace { class ObjCMigrateASTConsumer : public ASTConsumer { void migrateDecl(Decl *D); + void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCInterfaceDecl *D); public: std::string MigrateDir; @@ -42,6 +43,7 @@ public: FileRemapper &Remapper; FileManager &FileMgr; const PPConditionalDirectiveRecord *PPRec; + Preprocessor &PP; bool IsOutputFile; ObjCMigrateASTConsumer(StringRef migrateDir, @@ -50,11 +52,12 @@ public: FileRemapper &remapper, FileManager &fileMgr, const PPConditionalDirectiveRecord *PPRec, + Preprocessor &PP, bool isOutputFile = false) : MigrateDir(migrateDir), MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting), - Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), + Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), IsOutputFile(isOutputFile) { } protected: @@ -105,7 +108,8 @@ ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, MigrateSubscripting, Remapper, CompInst->getFileManager(), - PPRec); + PPRec, + CompInst->getPreprocessor()); ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer }; return new MultiplexConsumer(Consumers); } @@ -184,6 +188,40 @@ void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { BodyMigrator(*this).TraverseDecl(D); } +void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, + ObjCInterfaceDecl *D) { + for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end(); + M != MEnd; ++M) { + ObjCMethodDecl *Method = (*M); + if (Method->isPropertyAccessor()) + continue; + // Is this method candidate to be a getter? + if (Method->param_size() == 0) { + QualType GRT = Method->getResultType(); + if (GRT->isVoidType()) + continue; + Selector GetterSelector = Method->getSelector(); + IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0); + Selector SetterSelector = + SelectorTable::constructSetterSelector(PP.getIdentifierTable(), + PP.getSelectorTable(), + getterName); + if (ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true)) { + // Is this a valid setter, matching the target getter? + QualType SRT = SetterMethod->getResultType(); + if (!SRT->isVoidType()) + continue; + const ParmVarDecl *argDecl = *SetterMethod->param_begin(); + // FIXME. Can relax rule for matching getter/setter type further. + if (!Ctx.hasSameType(argDecl->getType(), GRT)) + continue; + // we have a matching setter/getter pair. + // TODO. synthesize a suitable property declaration here. + } + } + } +} + namespace { class RewritesReceiver : public edit::EditsReceiver { @@ -203,6 +241,14 @@ public: } void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { + + TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl(); + for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); + D != DEnd; ++D) { + if (ObjCInterfaceDecl *CDecl = dyn_cast(*D)) + migrateObjCInterfaceDecl(Ctx, CDecl); + } + Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); RewritesReceiver Rec(rewriter); Editor->applyRewrites(Rec); @@ -247,5 +293,6 @@ ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, Remapper, CI.getFileManager(), PPRec, + CI.getPreprocessor(), /*isOutputFile=*/true); } -- 2.7.4