void StmtDumper::VisitObjCImplicitSetterGetterRefExpr( ObjCImplicitSetterGetterRefExpr *Node) { DumpExpr(Node); ObjCMethodDecl *Getter = Node->getGetterMethod(); ObjCMethodDecl *Setter = Node->getSetterMethod(); OS << " Kind=MethodRef Getter=\"" << Getter->getSelector().getAsString() << "\" Setter=\""; if (Setter) OS << Setter->getSelector().getAsString(); else OS << "(null)"; OS << "\""; }
void ento::CheckObjCInstMethSignature(const ObjCImplementationDecl* ID, BugReporter& BR) { const ObjCInterfaceDecl* D = ID->getClassInterface(); const ObjCInterfaceDecl* C = D->getSuperClass(); if (!C) return; ASTContext& Ctx = BR.getContext(); // Build a DenseMap of the methods for quick querying. typedef llvm::DenseMap<Selector,ObjCMethodDecl*> MapTy; MapTy IMeths; unsigned NumMethods = 0; for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(), E=ID->instmeth_end(); I!=E; ++I) { ObjCMethodDecl* M = *I; IMeths[M->getSelector()] = M; ++NumMethods; } // Now recurse the class hierarchy chain looking for methods with the // same signatures. while (C && NumMethods) { for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(), E=C->instmeth_end(); I!=E; ++I) { ObjCMethodDecl* M = *I; Selector S = M->getSelector(); MapTy::iterator MI = IMeths.find(S); if (MI == IMeths.end() || MI->second == 0) continue; --NumMethods; ObjCMethodDecl* MethDerived = MI->second; MI->second = 0; CompareReturnTypes(MethDerived, M, BR, Ctx, ID); } C = C->getSuperClass(); } }
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() || Method->param_size() != 0) continue; // Is this method candidate to be a getter? 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(); QualType ArgType = argDecl->getType(); if (!Ctx.hasSameType(ArgType, GRT)) continue; edit::Commit commit(*Editor); edit::rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit); Editor->commit(commit); } } }
static void cleanupDeallocOrFinalize(MigrationPass &pass) { ASTContext &Ctx = pass.Ctx; TransformActions &TA = pass.TA; DeclContext *DC = Ctx.getTranslationUnitDecl(); Selector FinalizeSel = Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> impl_iterator; for (impl_iterator I = impl_iterator(DC->decls_begin()), E = impl_iterator(DC->decls_end()); I != E; ++I) { ObjCMethodDecl *DeallocM = 0; ObjCMethodDecl *FinalizeM = 0; for (ObjCImplementationDecl::instmeth_iterator MI = I->instmeth_begin(), ME = I->instmeth_end(); MI != ME; ++MI) { ObjCMethodDecl *MD = *MI; if (!MD->hasBody()) continue; if (MD->getMethodFamily() == OMF_dealloc) { DeallocM = MD; } else if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { FinalizeM = MD; } } if (DeallocM) { if (isBodyEmpty(DeallocM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { Transaction Trans(TA); TA.remove(DeallocM->getSourceRange()); } if (FinalizeM) { Transaction Trans(TA); TA.remove(FinalizeM->getSourceRange()); } } else if (FinalizeM) { if (isBodyEmpty(FinalizeM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { Transaction Trans(TA); TA.remove(FinalizeM->getSourceRange()); } else { Transaction Trans(TA); TA.replaceText(FinalizeM->getSelectorStartLoc(), "finalize", "dealloc"); } } } }
static void GCRewriteFinalize(MigrationPass &pass) { ASTContext &Ctx = pass.Ctx; TransformActions &TA = pass.TA; DeclContext *DC = Ctx.getTranslationUnitDecl(); Selector FinalizeSel = Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> impl_iterator; for (impl_iterator I = impl_iterator(DC->decls_begin()), E = impl_iterator(DC->decls_end()); I != E; ++I) { for (ObjCImplementationDecl::instmeth_iterator MI = I->instmeth_begin(), ME = I->instmeth_end(); MI != ME; ++MI) { ObjCMethodDecl *MD = *MI; if (!MD->hasBody()) continue; if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { ObjCMethodDecl *FinalizeM = MD; Transaction Trans(TA); TA.insert(FinalizeM->getSourceRange().getBegin(), "#if !__has_feature(objc_arc)\n"); CharSourceRange::getTokenRange(FinalizeM->getSourceRange()); const SourceManager &SM = pass.Ctx.getSourceManager(); const LangOptions &LangOpts = pass.Ctx.getLangOpts(); bool Invalid; std::string str = "\n#endif\n"; str += Lexer::getSourceText( CharSourceRange::getTokenRange(FinalizeM->getSourceRange()), SM, LangOpts, &Invalid); TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str); break; } } } }