TransUnbridgedCasts.cpp revision 651f13cea278ec967336033dd032faef0e9fc2ec
1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===// 27196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 37196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 47196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 57196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 67196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 77196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 87196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 97196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// rewriteUnbridgedCasts: 117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// A cast of non-objc pointer to an objc one is checked. If the non-objc pointer 137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// is from a file-level variable, __bridge cast is used to convert it. 147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// For the result of a function call that we know is +1/+0, 15684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis// __bridge/CFBridgingRelease is used. 167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// NSString *str = (NSString *)kUTTypePlainText; 187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// str = b ? kUTTypeRTF : kUTTypePlainText; 197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, 207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// _uuid); 217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// ----> 227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// NSString *str = (__bridge NSString *)kUTTypePlainText; 237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); 24684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis// NSString *_uuidString = (NSString *) 25684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis// CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); 267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// For a C pointer to ObjC, for casting 'self', __bridge is used. 287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// CFStringRef str = (CFStringRef)self; 307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// ----> 317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// CFStringRef str = (__bridge CFStringRef)self; 327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 335d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// Uses of Block_copy/Block_release macros are rewritten: 345d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// 355d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// c = Block_copy(b); 365d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// Block_release(c); 375d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// ----> 385d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// c = [b copy]; 395d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// <removed> 405d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis// 417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Transforms.h" 447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Internals.h" 45471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 462fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h" 4718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis#include "clang/AST/ParentMap.h" 482fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/Analysis/DomainSpecific/CocoaConventions.h" 497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 50471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Lex/Lexer.h" 51471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Sema/SemaDiagnostic.h" 528fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace clang; 557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace arcmt; 567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace { 597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{ 617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis MigrationPass &Pass; 627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis IdentifierInfo *SelfII; 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ParentMap> StmtMap; 6476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis Decl *ParentD; 655d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Stmt *Body; 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mutable std::unique_ptr<ExprSet> Removables; 6718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 695d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0), Body(0) { 707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SelfII = &Pass.Ctx.Idents.get("self"); 717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 7376a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis void transformBody(Stmt *body, Decl *ParentD) { 7476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis this->ParentD = ParentD; 755d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Body = body; 7618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis StmtMap.reset(new ParentMap(body)); 7718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis TraverseStmt(body); 7818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 7918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 8024016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis bool TraverseBlockDecl(BlockDecl *D) { 8124016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis // ParentMap does not enter into a BlockDecl to record its stmts, so use a 8224016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis // new UnbridgedCastRewriter to handle the block. 8324016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis UnbridgedCastRewriter(Pass).transformBody(D->getBody(), D); 8424016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis return true; 8524016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis } 8624016765c905a02c9df94ef0b8a50c5e74fff5c2Argyrios Kyrtzidis 877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitCastExpr(CastExpr *E) { 885d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (E->getCastKind() != CK_CPointerToObjCPointerCast && 895d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis E->getCastKind() != CK_BitCast && 905d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis E->getCastKind() != CK_AnyPointerToBlockPointerCast) 917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis QualType castType = E->getType(); 947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *castExpr = E->getSubExpr(); 957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis QualType castExprType = castExpr->getType(); 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 975d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (castType->isObjCRetainableType() == castExprType->isObjCRetainableType()) 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool exprRetainable = castExprType->isObjCIndirectLifetimeType(); 1017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool castRetainable = castType->isObjCIndirectLifetimeType(); 1027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (exprRetainable == castRetainable) return true; 1037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (castExpr->isNullPointerConstant(Pass.Ctx, 1057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr::NPC_ValueDependentIsNull)) 1067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation loc = castExpr->getExprLoc(); 1097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc)) 1107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1125d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (castType->isObjCRetainableType()) 1137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis transformNonObjCToObjCCast(E); 1147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis else 1157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis transformObjCToNonObjCCast(E); 1167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisprivate: 1217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void transformNonObjCToObjCCast(CastExpr *E) { 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!E) return; 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Global vars are assumed that are cast as unretained. 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (isGlobalVar(E)) 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (E->getSubExpr()->getType()->isPointerType()) { 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // If the cast is directly over the result of a Core Foundation function 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // try to figure out whether it should be cast as retained or unretained. 1337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *inner = E->IgnoreParenCasts(); 1347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (CallExpr *callE = dyn_cast<CallExpr>(inner)) { 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (FunctionDecl *FD = callE->getDirectCallee()) { 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FD->hasAttr<CFReturnsRetainedAttr>()) { 1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/true); 1387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FD->hasAttr<CFReturnsNotRetainedAttr>()) { 1417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 1427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (FD->isGlobal() && 1457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis FD->getIdentifier() && 1467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF", 1477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis FD->getIdentifier()->getName())) { 1487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis StringRef fname = FD->getIdentifier()->getName(); 1497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (fname.endswith("Retain") || 1507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis fname.find("Create") != StringRef::npos || 1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis fname.find("Copy") != StringRef::npos) { 1522908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian // Do not migrate to couple of bridge transfer casts which 1532908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian // cancel each other out. Leave it unchanged so error gets user 1542908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian // attention instead. 1552908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian if (FD->getName() == "CFRetain" && 1562908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian FD->getNumParams() == 1 && 1572908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian FD->getParent()->isTranslationUnit() && 158181e3ecc0907ae0103586a9f4db52241995a8267Rafael Espindola FD->isExternallyVisible()) { 1592908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian Expr *Arg = callE->getArg(0); 1609c7aed308aa701e0ba573c04ebe8d17a4c1486c4Fariborz Jahanian if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { 1612908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian const Expr *sub = ICE->getSubExpr(); 1622908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian QualType T = sub->getType(); 1632908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian if (T->isObjCObjectPointerType()) 1642908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian return; 1652908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian } 1662908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian } 1677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/true); 1687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (fname.find("Get") != StringRef::npos) { 1727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 1737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 17876a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis 17976a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis // If returning an ivar or a member of an ivar from a +0 method, use 18076a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis // a __bridge cast. 18176a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis Expr *base = inner->IgnoreParenImpCasts(); 18276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis while (isa<MemberExpr>(base)) 18376a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis base = cast<MemberExpr>(base)->getBase()->IgnoreParenImpCasts(); 18476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis if (isa<ObjCIvarRefExpr>(base) && 18576a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis isa<ReturnStmt>(StmtMap->getParentIgnoreParenCasts(E))) { 18676a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis if (ObjCMethodDecl *method = dyn_cast_or_null<ObjCMethodDecl>(ParentD)) { 18776a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis if (!method->hasAttr<NSReturnsRetainedAttr>()) { 18876a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 18976a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis return; 19076a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis } 19176a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis } 19276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis } 1937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void castToObjCObject(CastExpr *E, bool retained) { 1967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge); 1977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) { 20018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Transaction Trans(Pass.TA); 20118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis rewriteToBridgedCast(E, Kind, Trans); 20218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 20318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 20418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind, 20518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Transaction &Trans) { 2067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TransformActions &TA = Pass.TA; 2077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // We will remove the compiler diagnostic. 2097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast, 2107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis diag::err_arc_cast_requires_bridge, 21118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis E->getLocStart())) { 21218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Trans.abort(); 2137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 21418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 2157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis StringRef bridge; 2177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis switch(Kind) { 2187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis case OBC_Bridge: 2197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bridge = "__bridge "; break; 2207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis case OBC_BridgeTransfer: 2217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bridge = "__bridge_transfer "; break; 2227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis case OBC_BridgeRetained: 2237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bridge = "__bridge_retained "; break; 2247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TA.clearDiagnostic(diag::err_arc_mismatched_cast, 2277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis diag::err_arc_cast_requires_bridge, 2287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E->getLocStart()); 229684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) { 230684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) { 231684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insertAfterToken(CCE->getLParenLoc(), bridge); 2327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } else { 233684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis SourceLocation insertLoc = E->getSubExpr()->getLocStart(); 234684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis SmallString<128> newCast; 2357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis newCast += '('; 236684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += bridge; 237684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); 238684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += ')'; 239684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis 240684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (isa<ParenExpr>(E->getSubExpr())) { 241684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insert(insertLoc, newCast.str()); 242684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } else { 243684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += '('; 244684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insert(insertLoc, newCast.str()); 245684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insertAfterToken(E->getLocEnd(), ")"); 246684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } 247684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } 248684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } else { 249684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained); 250d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose SmallString<32> BridgeCall; 251d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose 252d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose Expr *WrapE = E->getSubExpr(); 253d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose SourceLocation InsertLoc = WrapE->getLocStart(); 254d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose 255d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose SourceManager &SM = Pass.Ctx.getSourceManager(); 256d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1)); 257d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose if (Lexer::isIdentifierBodyChar(PrevChar, Pass.Ctx.getLangOpts())) 258d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += ' '; 259d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose 260684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (Kind == OBC_BridgeTransfer) 261d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += "CFBridgingRelease"; 262684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis else 263d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += "CFBridgingRetain"; 264684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis 265684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (isa<ParenExpr>(WrapE)) { 266d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose TA.insert(InsertLoc, BridgeCall); 267684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } else { 268d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += '('; 269d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose TA.insert(InsertLoc, BridgeCall); 270684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insertAfterToken(WrapE->getLocEnd(), ")"); 2717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 27518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) { 27618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Transaction Trans(Pass.TA); 27718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange()); 27818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans); 27918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 28018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 2815d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) { 2825d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 2835d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceLocation Loc = E->getExprLoc(); 2845d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis assert(Loc.isMacroID()); 2855d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceLocation MacroBegin, MacroEnd; 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc); 2875d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange(); 2885d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin()); 2895d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd()); 2905d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 2915d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Outer = SourceRange(MacroBegin, MacroEnd); 2925d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Inner = SourceRange(InnerBegin, InnerEnd); 2935d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 2945d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 2955d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis void rewriteBlockCopyMacro(CastExpr *E) { 2965d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceRange OuterRange, InnerRange; 2975d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis getBlockMacroRanges(E, OuterRange, InnerRange); 2985d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 2995d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Transaction Trans(Pass.TA); 3005d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.replace(OuterRange, InnerRange); 3015d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.insert(InnerRange.getBegin(), "["); 3025d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]"); 3035d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, 3045d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis diag::err_arc_cast_requires_bridge, 3055d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis OuterRange); 3065d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3075d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3085d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis void removeBlockReleaseMacro(CastExpr *E) { 3095d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceRange OuterRange, InnerRange; 3105d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis getBlockMacroRanges(E, OuterRange, InnerRange); 3115d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3125d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Transaction Trans(Pass.TA); 3135d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, 3145d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis diag::err_arc_cast_requires_bridge, 3155d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis OuterRange); 3165d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (!hasSideEffects(E, Pass.Ctx)) { 3175d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (tryRemoving(cast<Expr>(StmtMap->getParentIgnoreParenCasts(E)))) 3185d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis return; 3195d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3205d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.replace(OuterRange, InnerRange); 3215d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3225d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3235d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis bool tryRemoving(Expr *E) const { 3245d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (!Removables) { 3255d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Removables.reset(new ExprSet); 3265d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis collectRemovables(Body, *Removables); 3275d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3285d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3295d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (Removables->count(E)) { 3305d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.TA.removeStmt(E); 3315d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis return true; 3325d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3335d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3345d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis return false; 3355d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3365d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void transformObjCToNonObjCCast(CastExpr *E) { 3385d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis SourceLocation CastLoc = E->getExprLoc(); 3395d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (CastLoc.isMacroID()) { 3405d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis StringRef MacroName = Lexer::getImmediateMacroName(CastLoc, 3415d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.Ctx.getSourceManager(), 3425d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis Pass.Ctx.getLangOpts()); 3435d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (MacroName == "Block_copy") { 3445d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis rewriteBlockCopyMacro(E); 3455d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis return; 3465d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3475d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis if (MacroName == "Block_release") { 3485d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis removeBlockReleaseMacro(E); 3495d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis return; 3505d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3515d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis } 3525d2faa41bc63a2a29535ae3dbbc99daabf14ea2fArgyrios Kyrtzidis 3537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (isSelf(E->getSubExpr())) 3547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_Bridge); 35518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 35618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis CallExpr *callE; 35718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (isPassedToCFRetain(E, callE)) 35818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteCastForCFRetain(E, callE); 35918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 36018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr()); 36118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (family == OMF_retain) 36218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_BridgeRetained); 36318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 36418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (family == OMF_autorelease || family == OMF_release) { 36518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis std::string err = "it is not safe to cast to '"; 36630c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); 36718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis err += "' the result of '"; 36818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis err += family == OMF_autorelease ? "autorelease" : "release"; 36918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis err += "' message; a __bridge cast may result in a pointer to a " 37018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis "destroyed object and a __bridge_retained may leak the object"; 37118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.reportError(err, E->getLocStart(), 37218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis E->getSubExpr()->getSourceRange()); 37318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Stmt *parent = E; 37418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis do { 37518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis parent = StmtMap->getParentIgnoreParenImpCasts(parent); 37618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } while (parent && isa<ExprWithCleanups>(parent)); 37718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 37818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) { 37918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis std::string note = "remove the cast and change return type of function " 38018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis "to '"; 38130c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy()); 38218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis note += "' to have the object automatically autoreleased"; 38318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.reportNote(note, retS->getLocStart()); 38418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 38518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 38618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 3874b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *subExpr = E->getSubExpr(); 3884b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3894b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Look through pseudo-object expressions. 3904b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(subExpr)) { 3914b9c2d235fb9449e249d74f48ecfec601650de93John McCall subExpr = pseudo->getResultExpr(); 3924b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(subExpr && "no result for pseudo-object of non-void type?"); 3934b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 3944b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3954b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(subExpr)) { 39633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE->getCastKind() == CK_ARCConsumeObject) 39718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_BridgeRetained); 39833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE->getCastKind() == CK_ARCReclaimReturnedObject) 39918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_Bridge); 40018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 4014532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis 4024532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis bool isConsumed = false; 4034532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (isPassedToCParamWithKnownOwnership(E, isConsumed)) 4044532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained 4054532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis : OBC_Bridge); 40618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 40718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 40818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis static ObjCMethodFamily getFamilyOfMessage(Expr *E) { 40918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis E = E->IgnoreParenCasts(); 41018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) 41118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return ME->getMethodFamily(); 41218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 41318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return OMF_None; 41418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 41518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 41618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const { 41718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if ((callE = dyn_cast_or_null<CallExpr>( 41818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis StmtMap->getParentIgnoreParenImpCasts(E)))) 41918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (FunctionDecl * 42018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) 42118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 && 42218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis FD->getParent()->isTranslationUnit() && 423181e3ecc0907ae0103586a9f4db52241995a8267Rafael Espindola FD->isExternallyVisible()) 42418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 42518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 42618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 4277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4294532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const { 4304532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (CallExpr *callE = dyn_cast_or_null<CallExpr>( 4314532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis StmtMap->getParentIgnoreParenImpCasts(E))) 4324532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (FunctionDecl * 4334532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) { 4344532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis unsigned i = 0; 4354532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis for (unsigned e = callE->getNumArgs(); i != e; ++i) { 4364532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis Expr *arg = callE->getArg(i); 4374532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (arg == E || arg->IgnoreParenImpCasts() == E) 4384532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis break; 4394532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 44033ace0669393acb84c24a7ff7a80e8759777b3e8Argyrios Kyrtzidis if (i < callE->getNumArgs() && i < FD->getNumParams()) { 4414532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis ParmVarDecl *PD = FD->getParamDecl(i); 442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PD->hasAttr<CFConsumedAttr>()) { 4434532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis isConsumed = true; 4444532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis return true; 4454532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 4464532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 4474532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 4484532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis 4494532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis return false; 4504532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 4514532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis 45218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool isSelf(Expr *E) const { 4537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = E->IgnoreParenLValueCasts(); 4547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 45518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) 45618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (IPD->getIdentifier() == SelfII) 45718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 45818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 4597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 4607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 4627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end anonymous namespace 4647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::rewriteUnbridgedCasts(MigrationPass &pass) { 46618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis BodyTransform<UnbridgedCastRewriter> trans(pass); 4677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 4687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 469