bool trans::hasSideEffects(Expr *E, ASTContext &Ctx) { if (!E || !E->HasSideEffects(Ctx)) return false; E = E->IgnoreParenCasts(); ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E); if (!ME) return true; switch (ME->getMethodFamily()) { case OMF_autorelease: case OMF_dealloc: case OMF_release: case OMF_retain: switch (ME->getReceiverKind()) { case ObjCMessageExpr::SuperInstance: return false; case ObjCMessageExpr::Instance: return hasSideEffects(ME->getInstanceReceiver(), Ctx); default: break; } break; default: break; } return true; }
// match expr against [_x delegate] or [self.x delegate] static bool matchObjCMessageExprForInterestingDelegate(const ObjCMessageExpr &expr, const ObjCImplFacts &facts, const ObjCIvarDecl **foundIvar, const ObjCPropertyDecl **foundProperty) { // want an instance message to a non-null receiver const Expr *receiver = expr.getInstanceReceiver(); if (!receiver) { return false; } const ObjCIvarDecl *ivarDecl = matchIvarLValueExpression(*receiver); if (!ivarDecl) { return false; } if (facts._ivarFactsMap.find(ivarDecl) == facts._ivarFactsMap.end()) { // not an interesting ivar (no entry) return false; } // is this a getter to an assign property? const ObjCPropertyDecl *propDecl = matchObjCMessageWithPropertyGetter(expr); if (propDecl) { if (propDecl->getSetterKind() != ObjCPropertyDecl::Assign) { return false; } // here we go! *foundIvar = ivarDecl; *foundProperty = propDecl; return true; } return false; }