/// ObjCGetTypeForMethodDefinition - Builds the type for a method definition /// declarator QualType Sema::ObjCGetTypeForMethodDefinition(DeclPtrTy D) { ObjCMethodDecl *MDecl = cast<ObjCMethodDecl>(D.getAs<Decl>()); QualType T = MDecl->getResultType(); llvm::SmallVector<QualType, 16> ArgTys; // Add the first two invisible argument types for self and _cmd. if (MDecl->isInstanceMethod()) { QualType selfTy = Context.getObjCInterfaceType(MDecl->getClassInterface()); selfTy = Context.getPointerType(selfTy); ArgTys.push_back(selfTy); } else ArgTys.push_back(Context.getObjCIdType()); ArgTys.push_back(Context.getObjCSelType()); for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(), E = MDecl->param_end(); PI != E; ++PI) { QualType ArgTy = (*PI)->getType(); assert(!ArgTy.isNull() && "Couldn't parse type?"); ArgTy = adjustParameterType(ArgTy); ArgTys.push_back(ArgTy); } T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(), MDecl->isVariadic(), 0); return T; }
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"); } } } }
ExprResult Sema::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, SourceLocation SelectorLoc, SourceLocation RBracLoc, MultiExprArg Args) { // Determine whether we are inside a method or not. ObjCMethodDecl *Method = tryCaptureObjCSelf(); if (!Method) { Diag(SuperLoc, diag::err_invalid_receiver_to_message_super); return ExprError(); } ObjCInterfaceDecl *Class = Method->getClassInterface(); if (!Class) { Diag(SuperLoc, diag::error_no_super_class_message) << Method->getDeclName(); return ExprError(); } ObjCInterfaceDecl *Super = Class->getSuperClass(); if (!Super) { // The current class does not have a superclass. Diag(SuperLoc, diag::error_root_class_cannot_use_super) << Class->getIdentifier(); return ExprError(); } // We are in a method whose class has a superclass, so 'super' // is acting as a keyword. if (Method->isInstanceMethod()) { // Since we are in an instance method, this is an instance // message to the superclass instance. QualType SuperTy = Context.getObjCInterfaceType(Super); SuperTy = Context.getObjCObjectPointerType(SuperTy); return BuildInstanceMessage(0, SuperTy, SuperLoc, Sel, /*Method=*/0, LBracLoc, SelectorLoc, RBracLoc, move(Args)); } // Since we are in a class method, this is a class message to // the superclass. return BuildClassMessage(/*ReceiverTypeInfo=*/0, Context.getObjCInterfaceType(Super), SuperLoc, Sel, /*Method=*/0, LBracLoc, SelectorLoc, RBracLoc, move(Args)); }
// Get the local instance/class method declared in this interface. ObjCMethodDecl * ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const { // Since instance & class methods can have the same name, the loop below // ensures we get the correct method. // // @interface Whatever // - (int) class_method; // + (float) class_method; // @end // lookup_const_iterator Meth, MethEnd; for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) { ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth); if (MD && MD->isInstanceMethod() == isInstance) return MD; } return 0; }
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; } } } }