17196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===--- TransUnbridgedCasts.cpp - Tranformations 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// 337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Transforms.h" 367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Internals.h" 377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Analysis/DomainSpecific/CocoaConventions.h" 38471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 3918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis#include "clang/AST/ParentMap.h" 407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 41471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Lex/Lexer.h" 42471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Sema/SemaDiagnostic.h" 438fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace clang; 467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace arcmt; 477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace { 507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{ 527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis MigrationPass &Pass; 537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis IdentifierInfo *SelfII; 546f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ParentMap> StmtMap; 5576a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis Decl *ParentD; 5618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 5876a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0) { 597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SelfII = &Pass.Ctx.Idents.get("self"); 607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 6276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis void transformBody(Stmt *body, Decl *ParentD) { 6376a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis this->ParentD = ParentD; 6418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis StmtMap.reset(new ParentMap(body)); 6518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis TraverseStmt(body); 6618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 6718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitCastExpr(CastExpr *E) { 691d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall if (E->getCastKind() != CK_CPointerToObjCPointerCast 707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis && E->getCastKind() != CK_BitCast) 717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis QualType castType = E->getType(); 747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *castExpr = E->getSubExpr(); 757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis QualType castExprType = castExpr->getType(); 767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (castType->isObjCObjectPointerType() && 787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castExprType->isObjCObjectPointerType()) 797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!castType->isObjCObjectPointerType() && 817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis !castExprType->isObjCObjectPointerType()) 827196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool exprRetainable = castExprType->isObjCIndirectLifetimeType(); 857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool castRetainable = castType->isObjCIndirectLifetimeType(); 867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (exprRetainable == castRetainable) return true; 877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (castExpr->isNullPointerConstant(Pass.Ctx, 897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr::NPC_ValueDependentIsNull)) 907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation loc = castExpr->getExprLoc(); 937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc)) 947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (castType->isObjCObjectPointerType()) 977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis transformNonObjCToObjCCast(E); 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis else 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis transformObjCToNonObjCCast(E); 1007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisprivate: 1057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void transformNonObjCToObjCCast(CastExpr *E) { 1067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!E) return; 1077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Global vars are assumed that are cast as unretained. 1097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (isGlobalVar(E)) 1107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (E->getSubExpr()->getType()->isPointerType()) { 1117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 1127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // If the cast is directly over the result of a Core Foundation function 1167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // try to figure out whether it should be cast as retained or unretained. 1177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *inner = E->IgnoreParenCasts(); 1187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (CallExpr *callE = dyn_cast<CallExpr>(inner)) { 1197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (FunctionDecl *FD = callE->getDirectCallee()) { 1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (FD->getAttr<CFReturnsRetainedAttr>()) { 1217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/true); 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (FD->getAttr<CFReturnsNotRetainedAttr>()) { 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (FD->isGlobal() && 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis FD->getIdentifier() && 1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF", 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis FD->getIdentifier()->getName())) { 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis StringRef fname = FD->getIdentifier()->getName(); 1337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (fname.endswith("Retain") || 1347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis fname.find("Create") != StringRef::npos || 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis fname.find("Copy") != StringRef::npos) { 1362908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian // Do not migrate to couple of bridge transfer casts which 1372908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian // cancel each other out. Leave it unchanged so error gets user 1382908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian // attention instead. 1392908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian if (FD->getName() == "CFRetain" && 1402908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian FD->getNumParams() == 1 && 1412908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian FD->getParent()->isTranslationUnit() && 1422908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian FD->getLinkage() == ExternalLinkage) { 1432908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian Expr *Arg = callE->getArg(0); 1449c7aed308aa701e0ba573c04ebe8d17a4c1486c4Fariborz Jahanian if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { 1452908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian const Expr *sub = ICE->getSubExpr(); 1462908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian QualType T = sub->getType(); 1472908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian if (T->isObjCObjectPointerType()) 1482908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian return; 1492908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian } 1502908ffbc5f54323f150405fa2b06f50788ae55c7Fariborz Jahanian } 1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/true); 1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (fname.find("Get") != StringRef::npos) { 1567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 1577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 1587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 16276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis 16376a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis // If returning an ivar or a member of an ivar from a +0 method, use 16476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis // a __bridge cast. 16576a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis Expr *base = inner->IgnoreParenImpCasts(); 16676a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis while (isa<MemberExpr>(base)) 16776a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis base = cast<MemberExpr>(base)->getBase()->IgnoreParenImpCasts(); 16876a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis if (isa<ObjCIvarRefExpr>(base) && 16976a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis isa<ReturnStmt>(StmtMap->getParentIgnoreParenCasts(E))) { 17076a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis if (ObjCMethodDecl *method = dyn_cast_or_null<ObjCMethodDecl>(ParentD)) { 17176a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis if (!method->hasAttr<NSReturnsRetainedAttr>()) { 17276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis castToObjCObject(E, /*retained=*/false); 17376a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis return; 17476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis } 17576a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis } 17676a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis } 1777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void castToObjCObject(CastExpr *E, bool retained) { 1807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge); 1817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1827196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) { 18418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Transaction Trans(Pass.TA); 18518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis rewriteToBridgedCast(E, Kind, Trans); 18618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 18718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 18818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind, 18918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Transaction &Trans) { 1907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TransformActions &TA = Pass.TA; 1917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // We will remove the compiler diagnostic. 1937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast, 1947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis diag::err_arc_cast_requires_bridge, 19518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis E->getLocStart())) { 19618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Trans.abort(); 1977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return; 19818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 1997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis StringRef bridge; 2017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis switch(Kind) { 2027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis case OBC_Bridge: 2037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bridge = "__bridge "; break; 2047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis case OBC_BridgeTransfer: 2057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bridge = "__bridge_transfer "; break; 2067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis case OBC_BridgeRetained: 2077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bridge = "__bridge_retained "; break; 2087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TA.clearDiagnostic(diag::err_arc_mismatched_cast, 2117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis diag::err_arc_cast_requires_bridge, 2127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E->getLocStart()); 213684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) { 214684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) { 215684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insertAfterToken(CCE->getLParenLoc(), bridge); 2167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } else { 217684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis SourceLocation insertLoc = E->getSubExpr()->getLocStart(); 218684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis SmallString<128> newCast; 2197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis newCast += '('; 220684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += bridge; 221684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); 222684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += ')'; 223684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis 224684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (isa<ParenExpr>(E->getSubExpr())) { 225684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insert(insertLoc, newCast.str()); 226684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } else { 227684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis newCast += '('; 228684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insert(insertLoc, newCast.str()); 229684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insertAfterToken(E->getLocEnd(), ")"); 230684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } 231684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } 232684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } else { 233684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained); 234d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose SmallString<32> BridgeCall; 235d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose 236d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose Expr *WrapE = E->getSubExpr(); 237d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose SourceLocation InsertLoc = WrapE->getLocStart(); 238d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose 239d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose SourceManager &SM = Pass.Ctx.getSourceManager(); 240d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1)); 241d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose if (Lexer::isIdentifierBodyChar(PrevChar, Pass.Ctx.getLangOpts())) 242d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += ' '; 243d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose 244684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (Kind == OBC_BridgeTransfer) 245d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += "CFBridgingRelease"; 246684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis else 247d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += "CFBridgingRetain"; 248684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis 249684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (isa<ParenExpr>(WrapE)) { 250d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose TA.insert(InsertLoc, BridgeCall); 251684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis } else { 252d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose BridgeCall += '('; 253d880b3aa6d594d1a7f2d307c29378c6f59b216ffJordan Rose TA.insert(InsertLoc, BridgeCall); 254684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis TA.insertAfterToken(WrapE->getLocEnd(), ")"); 2557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 25918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) { 26018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Transaction Trans(Pass.TA); 26118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange()); 26218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans); 26318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 26418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 2657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void transformObjCToNonObjCCast(CastExpr *E) { 2667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (isSelf(E->getSubExpr())) 2677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_Bridge); 26818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 26918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis CallExpr *callE; 27018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (isPassedToCFRetain(E, callE)) 27118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteCastForCFRetain(E, callE); 27218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 27318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr()); 27418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (family == OMF_retain) 27518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_BridgeRetained); 27618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 27718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (family == OMF_autorelease || family == OMF_release) { 27818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis std::string err = "it is not safe to cast to '"; 27930c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); 28018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis err += "' the result of '"; 28118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis err += family == OMF_autorelease ? "autorelease" : "release"; 28218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis err += "' message; a __bridge cast may result in a pointer to a " 28318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis "destroyed object and a __bridge_retained may leak the object"; 28418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.reportError(err, E->getLocStart(), 28518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis E->getSubExpr()->getSourceRange()); 28618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Stmt *parent = E; 28718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis do { 28818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis parent = StmtMap->getParentIgnoreParenImpCasts(parent); 28918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } while (parent && isa<ExprWithCleanups>(parent)); 29018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 29118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) { 29218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis std::string note = "remove the cast and change return type of function " 29318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis "to '"; 29430c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy()); 29518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis note += "' to have the object automatically autoreleased"; 29618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.reportNote(note, retS->getLocStart()); 29718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 29818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 29918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 3004b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *subExpr = E->getSubExpr(); 3014b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3024b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Look through pseudo-object expressions. 3034b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(subExpr)) { 3044b9c2d235fb9449e249d74f48ecfec601650de93John McCall subExpr = pseudo->getResultExpr(); 3054b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(subExpr && "no result for pseudo-object of non-void type?"); 3064b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 3074b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3084b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(subExpr)) { 30933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE->getCastKind() == CK_ARCConsumeObject) 31018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_BridgeRetained); 31133e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE->getCastKind() == CK_ARCReclaimReturnedObject) 31218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return rewriteToBridgedCast(E, OBC_Bridge); 31318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 3144532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis 3154532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis bool isConsumed = false; 3164532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (isPassedToCParamWithKnownOwnership(E, isConsumed)) 3174532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained 3184532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis : OBC_Bridge); 31918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 32018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis static ObjCMethodFamily getFamilyOfMessage(Expr *E) { 32218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis E = E->IgnoreParenCasts(); 32318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) 32418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return ME->getMethodFamily(); 32518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return OMF_None; 32718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 32818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const { 33018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if ((callE = dyn_cast_or_null<CallExpr>( 33118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis StmtMap->getParentIgnoreParenImpCasts(E)))) 33218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (FunctionDecl * 33318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) 33418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 && 33518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis FD->getParent()->isTranslationUnit() && 33618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis FD->getLinkage() == ExternalLinkage) 33718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 33818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 33918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 3407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3424532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const { 3434532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (CallExpr *callE = dyn_cast_or_null<CallExpr>( 3444532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis StmtMap->getParentIgnoreParenImpCasts(E))) 3454532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (FunctionDecl * 3464532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) { 3474532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis unsigned i = 0; 3484532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis for (unsigned e = callE->getNumArgs(); i != e; ++i) { 3494532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis Expr *arg = callE->getArg(i); 3504532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (arg == E || arg->IgnoreParenImpCasts() == E) 3514532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis break; 3524532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 3534532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (i < callE->getNumArgs()) { 3544532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis ParmVarDecl *PD = FD->getParamDecl(i); 3554532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis if (PD->getAttr<CFConsumedAttr>()) { 3564532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis isConsumed = true; 3574532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis return true; 3584532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 3594532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 3604532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 3614532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis 3624532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis return false; 3634532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis } 3644532b5553db699d5bed250454f9a45e0f66f4bf8Argyrios Kyrtzidis 36518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool isSelf(Expr *E) const { 3667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = E->IgnoreParenLValueCasts(); 3677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 36818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) 36918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (IPD->getIdentifier() == SelfII) 37018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 37118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 3727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 3737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 3757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end anonymous namespace 3777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::rewriteUnbridgedCasts(MigrationPass &pass) { 37918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis BodyTransform<UnbridgedCastRewriter> trans(pass); 3807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 3817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 382