1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- Transforms.cpp - Transformations to ARC mode ---------------------===// 28f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// 38f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// The LLVM Compiler Infrastructure 48f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// 58f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// This file is distributed under the University of Illinois Open Source 68f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// License. See LICENSE.TXT for details. 78f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// 88f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 98f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Transforms.h" 118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "Internals.h" 12471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/AST/RecursiveASTVisitor.h" 148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/AST/StmtVisitor.h" 1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/DomainSpecific/CocoaConventions.h" 168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Basic/SourceManager.h" 179852f58f50b4fc20914fbce5b4454135a42343f4Benjamin Kramer#include "clang/Basic/TargetInfo.h" 18471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Lex/Lexer.h" 19471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Sema/Sema.h" 20471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/Sema/SemaDiagnostic.h" 218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "llvm/ADT/DenseSet.h" 229852f58f50b4fc20914fbce5b4454135a42343f4Benjamin Kramer#include "llvm/ADT/StringSwitch.h" 238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <map> 248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace clang; 268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace arcmt; 277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 29e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios KyrtzidisASTTraverser::~ASTTraverser() { } 30e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 31684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidisbool MigrationPass::CFBridgingFunctionsDefined() { 32684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis if (!EnableCFBridgeFns.hasValue()) 33684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis EnableCFBridgeFns = SemaRef.isKnownName("CFBridgingRetain") && 34684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis SemaRef.isKnownName("CFBridgingRelease"); 35684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis return *EnableCFBridgeFns; 36684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis} 37684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis 388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Helpers. 408f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 4212192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidisbool trans::canApplyWeak(ASTContext &Ctx, QualType type, 4312192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis bool AllowOnUnknownClass) { 440a7dd788dbef975f35f273c7ab913f480f7edd60John McCall if (!Ctx.getLangOpts().ObjCARCWeak) 4586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 4686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 4786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis QualType T = type; 48b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (T.isNull()) 49b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 50b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 512af504bf157cce51bdb4a9bab0e6d3b34f898f6eArgyrios Kyrtzidis // iOS is always safe to use 'weak'. 522af504bf157cce51bdb4a9bab0e6d3b34f898f6eArgyrios Kyrtzidis if (Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::IOS) 532af504bf157cce51bdb4a9bab0e6d3b34f898f6eArgyrios Kyrtzidis AllowOnUnknownClass = true; 542af504bf157cce51bdb4a9bab0e6d3b34f898f6eArgyrios Kyrtzidis 5586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis while (const PointerType *ptr = T->getAs<PointerType>()) 5686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis T = ptr->getPointeeType(); 5786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { 5886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); 5912192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) 6086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; // id/NSObject is not safe for weak. 617723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (!AllowOnUnknownClass && !Class->hasDefinition()) 625363e8df5d274cb32c0c47fd2df45aa02cf68dfeArgyrios Kyrtzidis return false; // forward classes are not verifiable, therefore not safe. 63a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith if (Class && Class->isArcWeakrefUnavailable()) 6486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 6586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis } 6686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 6886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 6986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 701b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidisbool trans::isPlusOneAssign(const BinaryOperator *E) { 711b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (E->getOpcode() != BO_Assign) 721b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis return false; 731b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 7420bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis return isPlusOne(E->getRHS()); 7520bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis} 7620bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis 7720bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidisbool trans::isPlusOne(const Expr *E) { 7820bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis if (!E) 7920bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis return false; 8020bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E)) 8120bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis E = EWC->getSubExpr(); 8220bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis 831b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (const ObjCMessageExpr * 8420bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis ME = dyn_cast<ObjCMessageExpr>(E->IgnoreParenCasts())) 851b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (ME->getMethodFamily() == OMF_retain) 861b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis return true; 871b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 881b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (const CallExpr * 8920bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis callE = dyn_cast<CallExpr>(E->IgnoreParenCasts())) { 901b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (const FunctionDecl *FD = callE->getDirectCallee()) { 911b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (FD->getAttr<CFReturnsRetainedAttr>()) 921b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis return true; 931b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 941b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (FD->isGlobal() && 951b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis FD->getIdentifier() && 961b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis FD->getParent()->isTranslationUnit() && 97181e3ecc0907ae0103586a9f4db52241995a8267Rafael Espindola FD->isExternallyVisible() && 981b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis ento::cocoa::isRefType(callE->getType(), "CF", 991b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis FD->getIdentifier()->getName())) { 1001b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis StringRef fname = FD->getIdentifier()->getName(); 1011b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (fname.endswith("Retain") || 1021b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis fname.find("Create") != StringRef::npos || 1031b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis fname.find("Copy") != StringRef::npos) { 1041b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis return true; 1051b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis } 1061b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis } 1071b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis } 1081b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis } 1091b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 11020bcd4ead46e3764a5d1279845f8ed351f4d3984Argyrios Kyrtzidis const ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E); 1111b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis while (implCE && implCE->getCastKind() == CK_BitCast) 1121b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr()); 1131b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 1141b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (implCE && implCE->getCastKind() == CK_ARCConsumeObject) 1151b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis return true; 1161b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 1171b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis return false; 1181b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis} 1191b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis 1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// \brief 'Loc' is the end of a statement range. This returns the location 1217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// immediately after the semicolon following the statement. 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// source location will be invalid. 1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios KyrtzidisSourceLocation trans::findLocationAfterSemi(SourceLocation loc, 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ASTContext &Ctx) { 126aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx); 127aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (SemiLoc.isInvalid()) 128aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return SourceLocation(); 129a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return SemiLoc.getLocWithOffset(1); 130aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis} 131aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 132aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// \brief \arg Loc is the end of a statement range. This returns the location 133aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// of the semicolon following the statement. 134aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 135aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// source location will be invalid. 136aec230d29835285777ecc467e268c83b33a2addeArgyrios KyrtzidisSourceLocation trans::findSemiAfterLocation(SourceLocation loc, 137aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis ASTContext &Ctx) { 1387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 1397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (loc.isMacroID()) { 1404e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc)) 1417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1434e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts()); 1448f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Break down the source location. 1467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc); 1478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Try to load the file buffer. 1497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool invalidTemp = false; 1505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (invalidTemp) 1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 1557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Lex from the start of the given location. 1577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 1584e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Ctx.getLangOpts(), 1597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 1607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Token tok; 1617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 1627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (tok.isNot(tok::semi)) 1637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 165aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return tok.getLocation(); 1667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 1678f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisbool trans::hasSideEffects(Expr *E, ASTContext &Ctx) { 1698f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!E || !E->HasSideEffects(Ctx)) 1708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1728f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall E = E->IgnoreParenCasts(); 1738f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E); 1748f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!ME) 1758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall switch (ME->getMethodFamily()) { 1778f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_autorelease: 1788f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_dealloc: 1798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_release: 1808f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_retain: 1818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall switch (ME->getReceiverKind()) { 1828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case ObjCMessageExpr::SuperInstance: 1838f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1848f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case ObjCMessageExpr::Instance: 1857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return hasSideEffects(ME->getInstanceReceiver(), Ctx); 1868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall default: 1878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1888f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1898f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall default: 1918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1938f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 1968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1972c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidisbool trans::isGlobalVar(Expr *E) { 1982c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis E = E->IgnoreParenCasts(); 1992c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 20018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return DRE->getDecl()->getDeclContext()->isFileContext() && 201181e3ecc0907ae0103586a9f4db52241995a8267Rafael Espindola DRE->getDecl()->isExternallyVisible(); 2022c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E)) 2032c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis return isGlobalVar(condOp->getTrueExpr()) && 2042c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis isGlobalVar(condOp->getFalseExpr()); 2052c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis 2062c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis return false; 2072c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis} 2082c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis 20918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios KyrtzidisStringRef trans::getNilString(ASTContext &Ctx) { 21018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (Ctx.Idents.get("nil").hasMacroDefinition()) 21118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return "nil"; 21218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis else 21318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return "0"; 21418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis} 21518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 2168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallnamespace { 2178f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass ReferenceClear : public RecursiveASTVisitor<ReferenceClear> { 2197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Refs; 2208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceClear(ExprSet &refs) : Refs(refs) { } 2228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; } 2238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 2248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> { 2268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ValueDecl *Dcl; 2277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Refs; 2288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceCollector(ValueDecl *D, ExprSet &refs) 2317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis : Dcl(D), Refs(refs) { } 2328f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2338f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitDeclRefExpr(DeclRefExpr *E) { 2348f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (E->getDecl() == Dcl) 2358f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall Refs.insert(E); 2368f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2378f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 2398f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> { 2417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Removables; 2428f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RemovablesCollector(ExprSet &removables) 2457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis : Removables(removables) { } 2467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 2487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseStmtExpr(StmtExpr *E) { 2507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis CompoundStmt *S = E->getSubStmt(); 2517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (CompoundStmt::body_iterator 2527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) { 2537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (I != E - 1) 2547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(*I); 2557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TraverseStmt(*I); 2568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2588f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitCompoundStmt(CompoundStmt *S) { 2617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (CompoundStmt::body_iterator 2627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) 2637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(*I); 2648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitIfStmt(IfStmt *S) { 2687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getThen()); 2697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getElse()); 2708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitWhileStmt(WhileStmt *S) { 2747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitDoStmt(DoStmt *S) { 2797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2808f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2827196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitForStmt(ForStmt *S) { 2847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getInit()); 2857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getInc()); 2867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2888f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallprivate: 2917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void mark(Stmt *S) { 2927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!S) return; 2937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2947e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall while (LabelStmt *Label = dyn_cast<LabelStmt>(S)) 2957e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall S = Label->getSubStmt(); 2967e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall S = S->IgnoreImplicit(); 2977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (Expr *E = dyn_cast<Expr>(S)) 2987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Removables.insert(E); 2998e2ce7fdf9e8033b77788662a9c3f61334eb5dafArgyrios Kyrtzidis } 3007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 3018e2ce7fdf9e8033b77788662a9c3f61334eb5dafArgyrios Kyrtzidis 3027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end anonymous namespace 3038f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::clearRefsIn(Stmt *S, ExprSet &refs) { 3057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceClear(refs).TraverseStmt(S); 3067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 3078f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs) { 3097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceCollector(D, refs).TraverseStmt(S); 3108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 3118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::collectRemovables(Stmt *S, ExprSet &exprs) { 3137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RemovablesCollector(exprs).TraverseStmt(S); 3148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 3158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 317e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// MigrationContext 318e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 319e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 320e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisnamespace { 321e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 322e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass ASTTransform : public RecursiveASTVisitor<ASTTransform> { 323e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext &MigrateCtx; 324a33849b368b0973e64ee9c49af4c080a59f99eb4Argyrios Kyrtzidis typedef RecursiveASTVisitor<ASTTransform> base; 325e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 326e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic: 327e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { } 328e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 329f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 330f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 331b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) { 332b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext ImplCtx(MigrateCtx, D); 333b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis for (MigrationContext::traverser_iterator 334b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis I = MigrateCtx.traversers_begin(), 335b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis E = MigrateCtx.traversers_end(); I != E; ++I) 336b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis (*I)->traverseObjCImplementation(ImplCtx); 337b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis 338a33849b368b0973e64ee9c49af4c080a59f99eb4Argyrios Kyrtzidis return base::TraverseObjCImplementationDecl(D); 339b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis } 340b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis 341e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis bool TraverseStmt(Stmt *rootS) { 342e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (!rootS) 343e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 344e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 345e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis BodyContext BodyCtx(MigrateCtx, rootS); 346e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis for (MigrationContext::traverser_iterator 347e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis I = MigrateCtx.traversers_begin(), 348e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis E = MigrateCtx.traversers_end(); I != E; ++I) 349e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis (*I)->traverseBody(BodyCtx); 350e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 351e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 352e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 353e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis}; 354e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 355e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 356e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 357e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios KyrtzidisMigrationContext::~MigrationContext() { 358e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis for (traverser_iterator 359e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis I = traversers_begin(), E = traversers_end(); I != E; ++I) 360e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis delete *I; 361e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 362e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 3631fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidisbool MigrationContext::isGCOwnedNonObjC(QualType T) { 3641fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis while (!T.isNull()) { 3651fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (const AttributedType *AttrT = T->getAs<AttributedType>()) { 3661fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership) 3671fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return !AttrT->getModifiedType()->isObjCRetainableType(); 3681fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 3691fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 3701fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (T->isArrayType()) 3711fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = Pass.Ctx.getBaseElementType(T); 3721fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else if (const PointerType *PT = T->getAs<PointerType>()) 3731fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = PT->getPointeeType(); 3741fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 3751fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = RT->getPointeeType(); 3761fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else 3771fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis break; 3781fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 3791fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 3801fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return false; 3811fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis} 3821fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 383b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidisbool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, 384b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef toAttr, 385b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) { 386b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (atLoc.isMacroID()) 387b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 388b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 389b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 390b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 391b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Break down the source location. 392b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 393b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 394b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Try to load the file buffer. 395b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool invalidTemp = false; 396b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 397b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (invalidTemp) 398b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 399b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 400b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 401b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 402b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Lex from the start of the given location. 403b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 4044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Pass.Ctx.getLangOpts(), 405b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 406b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token tok; 407b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 408b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 409b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 410b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 411b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 412b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis != "property") 413b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 414b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 415b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::l_paren)) return false; 416b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 417b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token BeforeTok = tok; 418b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token AfterTok; 419b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok.startToken(); 420b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation AttrLoc; 421b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 422b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 423b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.is(tok::r_paren)) 424b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 425b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 426b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis while (1) { 427b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 428b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef ident(tok.getRawIdentifierData(), tok.getLength()); 429b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (ident == fromAttr) { 430b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!toAttr.empty()) { 431b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr); 432b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return true; 433b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 434b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // We want to remove the attribute. 435b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AttrLoc = tok.getLocation(); 436b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 437b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 438b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis do { 439b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 440b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (AttrLoc.isValid() && AfterTok.is(tok::unknown)) 441b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok = tok; 442b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren)); 443b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.is(tok::r_paren)) 444b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis break; 445b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (AttrLoc.isInvalid()) 446b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis BeforeTok = tok; 447b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 448b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 449b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 450b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) { 451b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // We want to remove the attribute. 452b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) { 453b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(BeforeTok.getLocation(), 454b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok.getLocation())); 455b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) { 456b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation())); 457b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } else { 458b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc)); 459b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 460b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 461b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return true; 462b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 463b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 464b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 465b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis} 466b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 4676da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidisbool MigrationContext::addPropertyAttribute(StringRef attr, 4686da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis SourceLocation atLoc) { 4696da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (atLoc.isMacroID()) 4706da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return false; 4716da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4726da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 4736da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4746da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis // Break down the source location. 4756da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 4766da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4776da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis // Try to load the file buffer. 4786da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis bool invalidTemp = false; 4796da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 4806da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (invalidTemp) 4816da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return false; 4826da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4836da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 4846da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4856da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis // Lex from the start of the given location. 4866da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 4874e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Pass.Ctx.getLangOpts(), 4886da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 4896da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Token tok; 4906da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4916da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 4926da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4936da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 4946da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 4956da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis != "property") 4966da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return false; 4976da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4986da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4996da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::l_paren)) { 5006da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") "); 5016da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return true; 5026da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis } 5036da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 5046da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 5056da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.is(tok::r_paren)) { 5066da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), attr); 5076da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return true; 5086da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis } 5096da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 5106da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 5116da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 5126da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string(attr) + ", "); 5136da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return true; 5146da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis} 5156da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 516e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisvoid MigrationContext::traverse(TranslationUnitDecl *TU) { 517f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis for (traverser_iterator 518f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis I = traversers_begin(), E = traversers_end(); I != E; ++I) 519f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis (*I)->traverseTU(*this); 520f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 521e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ASTTransform(*this).TraverseDecl(TU); 522e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 523e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 524bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanianstatic void GCRewriteFinalize(MigrationPass &pass) { 525bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ASTContext &Ctx = pass.Ctx; 526bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian TransformActions &TA = pass.TA; 527bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian DeclContext *DC = Ctx.getTranslationUnitDecl(); 528bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian Selector FinalizeSel = 529bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); 530bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 531bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> 532bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian impl_iterator; 533bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian for (impl_iterator I = impl_iterator(DC->decls_begin()), 534bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian E = impl_iterator(DC->decls_end()); I != E; ++I) { 535bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian for (ObjCImplementationDecl::instmeth_iterator 536262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie MI = I->instmeth_begin(), 537262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie ME = I->instmeth_end(); MI != ME; ++MI) { 538bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ObjCMethodDecl *MD = *MI; 539bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian if (!MD->hasBody()) 540bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian continue; 541bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 542bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { 543bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ObjCMethodDecl *FinalizeM = MD; 544bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian Transaction Trans(TA); 545bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian TA.insert(FinalizeM->getSourceRange().getBegin(), 546bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian "#if !__has_feature(objc_arc)\n"); 547bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian CharSourceRange::getTokenRange(FinalizeM->getSourceRange()); 548bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian const SourceManager &SM = pass.Ctx.getSourceManager(); 5494e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie const LangOptions &LangOpts = pass.Ctx.getLangOpts(); 550bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian bool Invalid; 551bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian std::string str = "\n#endif\n"; 552bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian str += Lexer::getSourceText( 553bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian CharSourceRange::getTokenRange(FinalizeM->getSourceRange()), 554bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian SM, LangOpts, &Invalid); 555bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str); 556bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 557bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian break; 558bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian } 559bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian } 560bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian } 561bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian} 562bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 563e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 5648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// getAllTransformations. 5658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 5668f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 567e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisstatic void traverseAST(MigrationPass &pass) { 568e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext MigrateCtx(pass); 569e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 570e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (pass.isGCMigration()) { 571e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrateCtx.addTraverser(new GCCollectableCallsTraverser); 572f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis MigrateCtx.addTraverser(new GCAttrsTraverser()); 573e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 574b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis MigrateCtx.addTraverser(new PropertyRewriteTraverser()); 5752a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidis MigrateCtx.addTraverser(new BlockObjCVariableTraverser()); 576ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis MigrateCtx.addTraverser(new ProtectedScopeTraverser()); 577e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 578e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl()); 579e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 580e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 5818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void independentTransforms(MigrationPass &pass) { 5828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall rewriteAutoreleasePool(pass); 583e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis removeRetainReleaseDeallocFinalize(pass); 5847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnusedInitDelegate(pass); 585e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis removeZeroOutPropsInDeallocFinalize(pass); 5868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall makeAssignARCSafe(pass); 5877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnbridgedCasts(pass); 588fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis checkAPIUses(pass); 589e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis traverseAST(pass); 5908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 5918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 592e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisstd::vector<TransformFn> arcmt::getAllTransformations( 593bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian LangOptions::GCMode OrigGCMode, 594bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian bool NoFinalizeRemoval) { 5958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall std::vector<TransformFn> transforms; 5968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 597bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian if (OrigGCMode == LangOptions::GCOnly && NoFinalizeRemoval) 598bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian transforms.push_back(GCRewriteFinalize); 5998f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall transforms.push_back(independentTransforms); 600fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis // This depends on previous transformations removing various expressions. 601e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis transforms.push_back(removeEmptyStatementsAndDeallocFinalize); 6028f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 6038f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return transforms; 6048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 605