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 | 76a5245d7fb558625453ebe2281ee0bc9c93c245 (patch) | |
tree | f1d84c4ae755e8b86c4b9008be6700542340ae61 /lib/ARCMigrate | |
parent | e14da79c7b1c336b72e6a4548f53b1a9534f7e0d (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158127 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate')
-rw-r--r-- | lib/ARCMigrate/TransAutoreleasePool.cpp | 2 | ||||
-rw-r--r-- | lib/ARCMigrate/TransRetainReleaseDealloc.cpp | 2 | ||||
-rw-r--r-- | lib/ARCMigrate/TransUnbridgedCasts.cpp | 21 | ||||
-rw-r--r-- | lib/ARCMigrate/TransUnusedInitDelegate.cpp | 2 | ||||
-rw-r--r-- | lib/ARCMigrate/Transforms.h | 12 |
5 files changed, 32 insertions, 7 deletions
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp index 87877242a1..f0db4d024d 100644 --- a/lib/ARCMigrate/TransAutoreleasePool.cpp +++ b/lib/ARCMigrate/TransAutoreleasePool.cpp @@ -75,7 +75,7 @@ public: &pass.Ctx.Idents.get("drain")); } - void transformBody(Stmt *body) { + void transformBody(Stmt *body, Decl *ParentD) { Body = body; TraverseStmt(body); } diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp index df3cd5858e..b8a84ec5b8 100644 --- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp @@ -49,7 +49,7 @@ public: Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); } - void transformBody(Stmt *body) { + void transformBody(Stmt *body, Decl *ParentD) { Body = body; collectRemovables(body, Removables); StmtMap.reset(new ParentMap(body)); diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp index 37cebc9e3a..72c0d8e7de 100644 --- a/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/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) { diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp index 60ed32aef4..7a825e8165 100644 --- a/lib/ARCMigrate/TransUnusedInitDelegate.cpp +++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp @@ -40,7 +40,7 @@ public: UnusedInitRewriter(MigrationPass &pass) : Body(0), Pass(pass) { } - void transformBody(Stmt *body) { + void transformBody(Stmt *body, Decl *ParentD) { Body = body; collectRemovables(body, Removables); TraverseStmt(body); diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h index 7abc0304b1..5d4ac94460 100644 --- a/lib/ARCMigrate/Transforms.h +++ b/lib/ARCMigrate/Transforms.h @@ -13,6 +13,7 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/ParentMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/Support/SaveAndRestore.h" namespace clang { class Decl; @@ -176,15 +177,22 @@ StringRef getNilString(ASTContext &Ctx); template <typename BODY_TRANS> class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > { MigrationPass &Pass; + Decl *ParentD; + typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base; public: - BodyTransform(MigrationPass &pass) : Pass(pass) { } + BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(0) { } bool TraverseStmt(Stmt *rootS) { if (rootS) - BODY_TRANS(Pass).transformBody(rootS); + BODY_TRANS(Pass).transformBody(rootS, ParentD); return true; } + + bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { + SaveAndRestore<Decl *> SetParent(ParentD, D); + return base::TraverseObjCMethodDecl(D); + } }; typedef llvm::DenseSet<Expr *> ExprSet; |