diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-06-07 00:44:06 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-06-07 00:44:06 +0000 |
commit | b03cc793a9274d89866d9477755aa1fbac9a8e1c (patch) | |
tree | 24bf6add8af4e92726789c67f05cc1b4eb0925ad /clang/lib/ARCMigrate/TransUnbridgedCasts.cpp | |
parent | ae02c5a93e43dc740979db0fc16290c0bcbe8316 (diff) | |
download | bcm5719-llvm-b03cc793a9274d89866d9477755aa1fbac9a8e1c.tar.gz bcm5719-llvm-b03cc793a9274d89866d9477755aa1fbac9a8e1c.zip |
[arcmt] At an unbridged cast error, if we're returning a load-of-ivar from a +0 method,
automatically insert a __bridge cast.
radar://11560638
llvm-svn: 158127
Diffstat (limited to 'clang/lib/ARCMigrate/TransUnbridgedCasts.cpp')
-rw-r--r-- | clang/lib/ARCMigrate/TransUnbridgedCasts.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp index 37cebc9e3ad..72c0d8e7de3 100644 --- a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -50,13 +50,15 @@ class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{ MigrationPass &Pass; IdentifierInfo *SelfII; OwningPtr<ParentMap> StmtMap; + Decl *ParentD; public: - UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass) { + UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0) { SelfII = &Pass.Ctx.Idents.get("self"); } - void transformBody(Stmt *body) { + void transformBody(Stmt *body, Decl *ParentD) { + this->ParentD = ParentD; StmtMap.reset(new ParentMap(body)); TraverseStmt(body); } @@ -155,6 +157,21 @@ private: } } } + + // If returning an ivar or a member of an ivar from a +0 method, use + // a __bridge cast. + Expr *base = inner->IgnoreParenImpCasts(); + while (isa<MemberExpr>(base)) + base = cast<MemberExpr>(base)->getBase()->IgnoreParenImpCasts(); + if (isa<ObjCIvarRefExpr>(base) && + isa<ReturnStmt>(StmtMap->getParentIgnoreParenCasts(E))) { + if (ObjCMethodDecl *method = dyn_cast_or_null<ObjCMethodDecl>(ParentD)) { + if (!method->hasAttr<NSReturnsRetainedAttr>()) { + castToObjCObject(E, /*retained=*/false); + return; + } + } + } } void castToObjCObject(CastExpr *E, bool retained) { |