Transforms.cpp revision 2a2781805a6b55573d369e34c5dcfba307ce83e9
18f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===--- Tranforms.cpp - Tranformations 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" 128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Sema/SemaDiagnostic.h" 138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/AST/RecursiveASTVisitor.h" 148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/AST/StmtVisitor.h" 158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Analysis/DomainSpecific/CocoaConventions.h" 168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Lex/Lexer.h" 178f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Basic/SourceManager.h" 188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "llvm/ADT/StringSwitch.h" 198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "llvm/ADT/DenseSet.h" 208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <map> 218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace clang; 238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace arcmt; 247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 26e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios KyrtzidisASTTraverser::~ASTTraverser() { } 27e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Helpers. 308f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 318f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis/// \brief True if the class is one that does not support weak. 3386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidisstatic bool isClassInWeakBlacklist(ObjCInterfaceDecl *cls) { 3486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (!cls) 3586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 3686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 3786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis bool inList = llvm::StringSwitch<bool>(cls->getName()) 3886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSColorSpace", true) 3986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSFont", true) 4086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSFontPanel", true) 4186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSImage", true) 4286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSLazyBrowserCell", true) 4386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSWindow", true) 4486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSWindowController", true) 45263d66718365aadc621c3feb9badedf46d787e0eArgyrios Kyrtzidis .Case("NSViewController", true) 4686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSMenuView", true) 4786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSPersistentUIWindowInfo", true) 4886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTableCellView", true) 4986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSATSTypeSetter", true) 5086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSATSGlyphStorage", true) 5186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSLineFragmentRenderingContext", true) 5286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSAttributeDictionary", true) 5386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSParagraphStyle", true) 5486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTextTab", true) 5586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSSimpleHorizontalTypesetter", true) 5686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("_NSCachedAttributedString", true) 5786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSStringDrawingTextStorage", true) 5886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTextView", true) 5986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSSubTextStorage", true) 6086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Default(false); 6186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (inList) 6386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 6486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return isClassInWeakBlacklist(cls->getSuperClass()); 6686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 6786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6812192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidisbool trans::canApplyWeak(ASTContext &Ctx, QualType type, 6912192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis bool AllowOnUnknownClass) { 7086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (!Ctx.getLangOptions().ObjCRuntimeHasWeak) 7186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 7286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 7386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis QualType T = type; 74b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (T.isNull()) 75b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 76b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 7786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis while (const PointerType *ptr = T->getAs<PointerType>()) 7886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis T = ptr->getPointeeType(); 7986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { 8086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); 8112192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) 8286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; // id/NSObject is not safe for weak. 837723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (!AllowOnUnknownClass && !Class->hasDefinition()) 845363e8df5d274cb32c0c47fd2df45aa02cf68dfeArgyrios Kyrtzidis return false; // forward classes are not verifiable, therefore not safe. 8586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (Class->isArcWeakrefUnavailable()) 8686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 8786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (isClassInWeakBlacklist(Class)) 8886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 8986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis } 9086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 9186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 9286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 9386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// \brief 'Loc' is the end of a statement range. This returns the location 957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// immediately after the semicolon following the statement. 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// source location will be invalid. 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios KyrtzidisSourceLocation trans::findLocationAfterSemi(SourceLocation loc, 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ASTContext &Ctx) { 100aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx); 101aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (SemiLoc.isInvalid()) 102aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return SourceLocation(); 103a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return SemiLoc.getLocWithOffset(1); 104aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis} 105aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 106aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// \brief \arg Loc is the end of a statement range. This returns the location 107aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// of the semicolon following the statement. 108aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 109aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// source location will be invalid. 110aec230d29835285777ecc467e268c83b33a2addeArgyrios KyrtzidisSourceLocation trans::findSemiAfterLocation(SourceLocation loc, 111aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis ASTContext &Ctx) { 1127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 1137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (loc.isMacroID()) { 11469bda4c027671df7163619f215209529eb236620Argyrios Kyrtzidis if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOptions(), &loc)) 1157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOptions()); 1188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Break down the source location. 1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc); 1218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Try to load the file buffer. 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool invalidTemp = false; 1245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (invalidTemp) 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Lex from the start of the given location. 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Ctx.getLangOptions(), 1337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 1347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Token tok; 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 1367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (tok.isNot(tok::semi)) 1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 139aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return tok.getLocation(); 1407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 1418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisbool trans::hasSideEffects(Expr *E, ASTContext &Ctx) { 1438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!E || !E->HasSideEffects(Ctx)) 1448f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall E = E->IgnoreParenCasts(); 1478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E); 1488f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!ME) 1498f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1508f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall switch (ME->getMethodFamily()) { 1518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_autorelease: 1528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_dealloc: 1538f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_release: 1548f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_retain: 1558f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall switch (ME->getReceiverKind()) { 1568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case ObjCMessageExpr::SuperInstance: 1578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1588f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case ObjCMessageExpr::Instance: 1597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return hasSideEffects(ME->getInstanceReceiver(), Ctx); 1608f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall default: 1618f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1628f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1638f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall default: 1658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1668f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1678f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1688f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1698f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 1708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1712c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidisbool trans::isGlobalVar(Expr *E) { 1722c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis E = E->IgnoreParenCasts(); 1732c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 17418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return DRE->getDecl()->getDeclContext()->isFileContext() && 17518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis DRE->getDecl()->getLinkage() == ExternalLinkage; 1762c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E)) 1772c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis return isGlobalVar(condOp->getTrueExpr()) && 1782c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis isGlobalVar(condOp->getFalseExpr()); 1792c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis 1802c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis return false; 1812c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis} 1822c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis 18318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios KyrtzidisStringRef trans::getNilString(ASTContext &Ctx) { 18418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (Ctx.Idents.get("nil").hasMacroDefinition()) 18518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return "nil"; 18618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis else 18718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return "0"; 18818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis} 18918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 1908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallnamespace { 1918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass ReferenceClear : public RecursiveASTVisitor<ReferenceClear> { 1937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Refs; 1948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 1957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceClear(ExprSet &refs) : Refs(refs) { } 1968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; } 1978f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Refs.erase(E); return true; } 1988f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 1998f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2008f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> { 2018f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ValueDecl *Dcl; 2027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Refs; 2038f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceCollector(ValueDecl *D, ExprSet &refs) 2067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis : Dcl(D), Refs(refs) { } 2078f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2088f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitDeclRefExpr(DeclRefExpr *E) { 2098f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (E->getDecl() == Dcl) 2108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall Refs.insert(E); 2118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { 2158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (E->getDecl() == Dcl) 2168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall Refs.insert(E); 2178f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 2208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> { 2227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Removables; 2238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RemovablesCollector(ExprSet &removables) 2267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis : Removables(removables) { } 2277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 2297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseStmtExpr(StmtExpr *E) { 2317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis CompoundStmt *S = E->getSubStmt(); 2327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (CompoundStmt::body_iterator 2337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) { 2347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (I != E - 1) 2357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(*I); 2367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TraverseStmt(*I); 2378f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2398f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitCompoundStmt(CompoundStmt *S) { 2427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (CompoundStmt::body_iterator 2437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) 2447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(*I); 2458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitIfStmt(IfStmt *S) { 2497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getThen()); 2507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getElse()); 2518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitWhileStmt(WhileStmt *S) { 2557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitDoStmt(DoStmt *S) { 2607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2618f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2628f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitForStmt(ForStmt *S) { 2657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getInit()); 2667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getInc()); 2677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2688f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2698f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallprivate: 2727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void mark(Stmt *S) { 2737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!S) return; 2747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2757e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall while (LabelStmt *Label = dyn_cast<LabelStmt>(S)) 2767e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall S = Label->getSubStmt(); 2777e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall S = S->IgnoreImplicit(); 2787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (Expr *E = dyn_cast<Expr>(S)) 2797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Removables.insert(E); 2808e2ce7fdf9e8033b77788662a9c3f61334eb5dafArgyrios Kyrtzidis } 2817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 2828e2ce7fdf9e8033b77788662a9c3f61334eb5dafArgyrios Kyrtzidis 2837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end anonymous namespace 2848f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::clearRefsIn(Stmt *S, ExprSet &refs) { 2867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceClear(refs).TraverseStmt(S); 2877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 2888f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs) { 2907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceCollector(D, refs).TraverseStmt(S); 2918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 2928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::collectRemovables(Stmt *S, ExprSet &exprs) { 2947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RemovablesCollector(exprs).TraverseStmt(S); 2958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 2968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2978f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 298e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// MigrationContext 299e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 300e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 301e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisnamespace { 302e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 303e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass ASTTransform : public RecursiveASTVisitor<ASTTransform> { 304e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext &MigrateCtx; 305a33849b368b0973e64ee9c49af4c080a59f99eb4Argyrios Kyrtzidis typedef RecursiveASTVisitor<ASTTransform> base; 306e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 307e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic: 308e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { } 309e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 310f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 311f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 312b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) { 313b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext ImplCtx(MigrateCtx, D); 314b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis for (MigrationContext::traverser_iterator 315b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis I = MigrateCtx.traversers_begin(), 316b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis E = MigrateCtx.traversers_end(); I != E; ++I) 317b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis (*I)->traverseObjCImplementation(ImplCtx); 318b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis 319a33849b368b0973e64ee9c49af4c080a59f99eb4Argyrios Kyrtzidis return base::TraverseObjCImplementationDecl(D); 320b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis } 321b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis 322e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis bool TraverseStmt(Stmt *rootS) { 323e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (!rootS) 324e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 325e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 326e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis BodyContext BodyCtx(MigrateCtx, rootS); 327e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis for (MigrationContext::traverser_iterator 328e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis I = MigrateCtx.traversers_begin(), 329e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis E = MigrateCtx.traversers_end(); I != E; ++I) 330e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis (*I)->traverseBody(BodyCtx); 331e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 332e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 333e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 334e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis}; 335e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 336e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 337e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 338e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios KyrtzidisMigrationContext::~MigrationContext() { 339e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis for (traverser_iterator 340e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis I = traversers_begin(), E = traversers_end(); I != E; ++I) 341e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis delete *I; 342e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 343e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 3441fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidisbool MigrationContext::isGCOwnedNonObjC(QualType T) { 3451fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis while (!T.isNull()) { 3461fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (const AttributedType *AttrT = T->getAs<AttributedType>()) { 3471fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership) 3481fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return !AttrT->getModifiedType()->isObjCRetainableType(); 3491fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 3501fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 3511fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (T->isArrayType()) 3521fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = Pass.Ctx.getBaseElementType(T); 3531fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else if (const PointerType *PT = T->getAs<PointerType>()) 3541fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = PT->getPointeeType(); 3551fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 3561fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = RT->getPointeeType(); 3571fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else 3581fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis break; 3591fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 3601fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 3611fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return false; 3621fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis} 3631fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 364b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidisbool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, 365b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef toAttr, 366b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) { 367b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (atLoc.isMacroID()) 368b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 369b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 370b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 371b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 372b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Break down the source location. 373b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 374b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 375b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Try to load the file buffer. 376b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool invalidTemp = false; 377b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 378b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (invalidTemp) 379b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 380b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 381b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 382b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 383b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Lex from the start of the given location. 384b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 385b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.Ctx.getLangOptions(), 386b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 387b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token tok; 388b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 389b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 390b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 391b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 392b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 393b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis != "property") 394b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 395b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 396b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::l_paren)) return false; 397b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 398b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token BeforeTok = tok; 399b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token AfterTok; 400b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok.startToken(); 401b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation AttrLoc; 402b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 403b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 404b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.is(tok::r_paren)) 405b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 406b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 407b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis while (1) { 408b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 409b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef ident(tok.getRawIdentifierData(), tok.getLength()); 410b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (ident == fromAttr) { 411b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!toAttr.empty()) { 412b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr); 413b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return true; 414b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 415b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // We want to remove the attribute. 416b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AttrLoc = tok.getLocation(); 417b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 418b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 419b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis do { 420b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 421b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (AttrLoc.isValid() && AfterTok.is(tok::unknown)) 422b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok = tok; 423b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren)); 424b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.is(tok::r_paren)) 425b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis break; 426b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (AttrLoc.isInvalid()) 427b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis BeforeTok = tok; 428b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 429b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 430b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 431b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) { 432b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // We want to remove the attribute. 433b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) { 434b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(BeforeTok.getLocation(), 435b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok.getLocation())); 436b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) { 437b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation())); 438b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } else { 439b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc)); 440b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 441b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 442b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return true; 443b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 444b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 445b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 446b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis} 447b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 4486da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidisbool MigrationContext::addPropertyAttribute(StringRef attr, 4496da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis SourceLocation atLoc) { 4506da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (atLoc.isMacroID()) 4516da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return false; 4526da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4536da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 4546da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4556da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis // Break down the source location. 4566da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 4576da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4586da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis // Try to load the file buffer. 4596da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis bool invalidTemp = false; 4606da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 4616da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (invalidTemp) 4626da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return false; 4636da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4646da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 4656da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4666da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis // Lex from the start of the given location. 4676da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 4686da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.Ctx.getLangOptions(), 4696da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 4706da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Token tok; 4716da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4726da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 4736da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4746da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 4756da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 4766da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis != "property") 4776da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return false; 4786da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4796da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4806da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::l_paren)) { 4816da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") "); 4826da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return true; 4836da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis } 4846da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4856da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 4866da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.is(tok::r_paren)) { 4876da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), attr); 4886da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return true; 4896da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis } 4906da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4916da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 4926da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 4936da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string(attr) + ", "); 4946da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return true; 4956da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis} 4966da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis 497e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisvoid MigrationContext::traverse(TranslationUnitDecl *TU) { 498f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis for (traverser_iterator 499f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis I = traversers_begin(), E = traversers_end(); I != E; ++I) 500f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis (*I)->traverseTU(*this); 501f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 502e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ASTTransform(*this).TraverseDecl(TU); 503e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 504e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 505bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanianstatic void GCRewriteFinalize(MigrationPass &pass) { 506bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ASTContext &Ctx = pass.Ctx; 507bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian TransformActions &TA = pass.TA; 508bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian DeclContext *DC = Ctx.getTranslationUnitDecl(); 509bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian Selector FinalizeSel = 510bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); 511bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 512bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> 513bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian impl_iterator; 514bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian for (impl_iterator I = impl_iterator(DC->decls_begin()), 515bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian E = impl_iterator(DC->decls_end()); I != E; ++I) { 516bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian for (ObjCImplementationDecl::instmeth_iterator 517bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian MI = (*I)->instmeth_begin(), 518bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ME = (*I)->instmeth_end(); MI != ME; ++MI) { 519bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ObjCMethodDecl *MD = *MI; 520bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian if (!MD->hasBody()) 521bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian continue; 522bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 523bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { 524bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian ObjCMethodDecl *FinalizeM = MD; 525bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian Transaction Trans(TA); 526bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian TA.insert(FinalizeM->getSourceRange().getBegin(), 527bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian "#if !__has_feature(objc_arc)\n"); 528bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian CharSourceRange::getTokenRange(FinalizeM->getSourceRange()); 529bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian const SourceManager &SM = pass.Ctx.getSourceManager(); 530bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian const LangOptions &LangOpts = pass.Ctx.getLangOptions(); 531bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian bool Invalid; 532bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian std::string str = "\n#endif\n"; 533bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian str += Lexer::getSourceText( 534bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian CharSourceRange::getTokenRange(FinalizeM->getSourceRange()), 535bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian SM, LangOpts, &Invalid); 536bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str); 537bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 538bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian break; 539bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian } 540bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian } 541bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian } 542bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian} 543bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian 544e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 5458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// getAllTransformations. 5468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 5478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 548e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisstatic void traverseAST(MigrationPass &pass) { 549e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext MigrateCtx(pass); 550e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 551e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (pass.isGCMigration()) { 552e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrateCtx.addTraverser(new GCCollectableCallsTraverser); 553f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis MigrateCtx.addTraverser(new GCAttrsTraverser()); 554e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 555b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis MigrateCtx.addTraverser(new PropertyRewriteTraverser()); 5562a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidis MigrateCtx.addTraverser(new BlockObjCVariableTraverser()); 557e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 558e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl()); 559e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 560e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 5618f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void independentTransforms(MigrationPass &pass) { 5628f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall rewriteAutoreleasePool(pass); 563e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis removeRetainReleaseDeallocFinalize(pass); 5647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnusedInitDelegate(pass); 565e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis removeZeroOutPropsInDeallocFinalize(pass); 5668f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall makeAssignARCSafe(pass); 5677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnbridgedCasts(pass); 568fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis checkAPIUses(pass); 569e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis traverseAST(pass); 5708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 5718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 572e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisstd::vector<TransformFn> arcmt::getAllTransformations( 573bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian LangOptions::GCMode OrigGCMode, 574bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian bool NoFinalizeRemoval) { 5758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall std::vector<TransformFn> transforms; 5768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 577bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian if (OrigGCMode == LangOptions::GCOnly && NoFinalizeRemoval) 578bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian transforms.push_back(GCRewriteFinalize); 5798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall transforms.push_back(independentTransforms); 580fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis // This depends on previous transformations removing various expressions. 581e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis transforms.push_back(removeEmptyStatementsAndDeallocFinalize); 5828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 5838f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return transforms; 5848f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 585