Transforms.cpp revision a64ccefdf0ea4e03ec88805d71b0af74950c7472
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/AST/ParentMap.h" 168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Analysis/DomainSpecific/CocoaConventions.h" 178f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Lex/Lexer.h" 188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Basic/SourceManager.h" 198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "llvm/ADT/StringSwitch.h" 208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "llvm/ADT/DenseSet.h" 218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <map> 228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace clang; 248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace arcmt; 257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 278f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Helpers. 298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 308f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis/// \brief True if the class is one that does not support weak. 3286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidisstatic bool isClassInWeakBlacklist(ObjCInterfaceDecl *cls) { 3386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (!cls) 3486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 3586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 3686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis bool inList = llvm::StringSwitch<bool>(cls->getName()) 3786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSColorSpace", true) 3886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSFont", true) 3986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSFontPanel", true) 4086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSImage", true) 4186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSLazyBrowserCell", true) 4286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSWindow", true) 4386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSWindowController", true) 4486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSMenuView", true) 4586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSPersistentUIWindowInfo", true) 4686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTableCellView", true) 4786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSATSTypeSetter", true) 4886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSATSGlyphStorage", true) 4986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSLineFragmentRenderingContext", true) 5086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSAttributeDictionary", true) 5186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSParagraphStyle", true) 5286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTextTab", true) 5386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSSimpleHorizontalTypesetter", true) 5486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("_NSCachedAttributedString", true) 5586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSStringDrawingTextStorage", true) 5686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTextView", true) 5786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSSubTextStorage", true) 5886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Default(false); 5986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (inList) 6186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 6286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return isClassInWeakBlacklist(cls->getSuperClass()); 6486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 6586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidisbool trans::canApplyWeak(ASTContext &Ctx, QualType type) { 6786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (!Ctx.getLangOptions().ObjCRuntimeHasWeak) 6886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 6986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 7086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis QualType T = type; 7186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis while (const PointerType *ptr = T->getAs<PointerType>()) 7286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis T = ptr->getPointeeType(); 7386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { 7486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); 7586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (!Class || Class->getName() == "NSObject") 7686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; // id/NSObject is not safe for weak. 775363e8df5d274cb32c0c47fd2df45aa02cf68dfeArgyrios Kyrtzidis if (Class->isForwardDecl()) 785363e8df5d274cb32c0c47fd2df45aa02cf68dfeArgyrios Kyrtzidis return false; // forward classes are not verifiable, therefore not safe. 7986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (Class->isArcWeakrefUnavailable()) 8086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 8186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (isClassInWeakBlacklist(Class)) 8286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 8386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis } 8486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 8586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 8686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 8786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// \brief 'Loc' is the end of a statement range. This returns the location 897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// immediately after the semicolon following the statement. 907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// source location will be invalid. 927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios KyrtzidisSourceLocation trans::findLocationAfterSemi(SourceLocation loc, 937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ASTContext &Ctx) { 94aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx); 95aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (SemiLoc.isInvalid()) 96aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return SourceLocation(); 97a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return SemiLoc.getLocWithOffset(1); 98aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis} 99aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 100aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// \brief \arg Loc is the end of a statement range. This returns the location 101aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// of the semicolon following the statement. 102aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 103aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// source location will be invalid. 104aec230d29835285777ecc467e268c83b33a2addeArgyrios KyrtzidisSourceLocation trans::findSemiAfterLocation(SourceLocation loc, 105aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis ASTContext &Ctx) { 1067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 1077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (loc.isMacroID()) { 108433db06b614f26dc6829e86d6ff469e2cca7d4f9Chandler Carruth if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOptions())) 1097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 110edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth loc = SM.getExpansionRange(loc).second; 1117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOptions()); 1138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Break down the source location. 1157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc); 1168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Try to load the file buffer. 1187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool invalidTemp = false; 1195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (invalidTemp) 1217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Lex from the start of the given location. 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Ctx.getLangOptions(), 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Token tok; 1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (tok.isNot(tok::semi)) 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 1338f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 134aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return tok.getLocation(); 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 1368f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisbool trans::hasSideEffects(Expr *E, ASTContext &Ctx) { 1388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!E || !E->HasSideEffects(Ctx)) 1398f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1408f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall E = E->IgnoreParenCasts(); 1428f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E); 1438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!ME) 1448f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall switch (ME->getMethodFamily()) { 1468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_autorelease: 1478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_dealloc: 1488f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_release: 1498f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case OMF_retain: 1508f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall switch (ME->getReceiverKind()) { 1518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case ObjCMessageExpr::SuperInstance: 1528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1538f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall case ObjCMessageExpr::Instance: 1547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return hasSideEffects(ME->getInstanceReceiver(), Ctx); 1558f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall default: 1568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1588f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1598f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall default: 1608f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 1618f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1628f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1638f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 1658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1662c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidisbool trans::isGlobalVar(Expr *E) { 1672c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis E = E->IgnoreParenCasts(); 1682c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 16918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return DRE->getDecl()->getDeclContext()->isFileContext() && 17018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis DRE->getDecl()->getLinkage() == ExternalLinkage; 1712c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E)) 1722c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis return isGlobalVar(condOp->getTrueExpr()) && 1732c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis isGlobalVar(condOp->getFalseExpr()); 1742c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis 1752c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis return false; 1762c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis} 1772c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidis 17818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios KyrtzidisStringRef trans::getNilString(ASTContext &Ctx) { 17918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (Ctx.Idents.get("nil").hasMacroDefinition()) 18018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return "nil"; 18118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis else 18218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return "0"; 18318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis} 18418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 1858f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallnamespace { 1868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass ReferenceClear : public RecursiveASTVisitor<ReferenceClear> { 1887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Refs; 1898f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 1907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceClear(ExprSet &refs) : Refs(refs) { } 1918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; } 1928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Refs.erase(E); return true; } 1938f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 1948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> { 1968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ValueDecl *Dcl; 1977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Refs; 1988f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1998f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceCollector(ValueDecl *D, ExprSet &refs) 2017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis : Dcl(D), Refs(refs) { } 2028f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2038f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitDeclRefExpr(DeclRefExpr *E) { 2048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (E->getDecl() == Dcl) 2058f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall Refs.insert(E); 2068f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2078f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2088f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2098f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { 2108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (E->getDecl() == Dcl) 2118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall Refs.insert(E); 2128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 2158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> { 2177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet &Removables; 2188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 2207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RemovablesCollector(ExprSet &removables) 2217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis : Removables(removables) { } 2227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 2247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseStmtExpr(StmtExpr *E) { 2267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis CompoundStmt *S = E->getSubStmt(); 2277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (CompoundStmt::body_iterator 2287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) { 2297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (I != E - 1) 2307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(*I); 2317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TraverseStmt(*I); 2328f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2338f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2348f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitCompoundStmt(CompoundStmt *S) { 2377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (CompoundStmt::body_iterator 2387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) 2397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(*I); 2408f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitIfStmt(IfStmt *S) { 2447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getThen()); 2457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getElse()); 2468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitWhileStmt(WhileStmt *S) { 2507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitDoStmt(DoStmt *S) { 2557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitForStmt(ForStmt *S) { 2607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getInit()); 2617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getInc()); 2627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis mark(S->getBody()); 2638f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 2648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 2657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2668f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallprivate: 2677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis void mark(Stmt *S) { 2687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!S) return; 2697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2707e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall while (LabelStmt *Label = dyn_cast<LabelStmt>(S)) 2717e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall S = Label->getSubStmt(); 2727e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall S = S->IgnoreImplicit(); 2737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (Expr *E = dyn_cast<Expr>(S)) 2747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Removables.insert(E); 2758e2ce7fdf9e8033b77788662a9c3f61334eb5dafArgyrios Kyrtzidis } 2767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 2778e2ce7fdf9e8033b77788662a9c3f61334eb5dafArgyrios Kyrtzidis 2787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end anonymous namespace 2798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::clearRefsIn(Stmt *S, ExprSet &refs) { 2817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceClear(refs).TraverseStmt(S); 2827196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 2838f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs) { 2857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ReferenceCollector(D, refs).TraverseStmt(S); 2868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 2878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::collectRemovables(Stmt *S, ExprSet &exprs) { 2897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RemovablesCollector(exprs).TraverseStmt(S); 2908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 2918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 2938f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// getAllTransformations. 2948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 2958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void independentTransforms(MigrationPass &pass) { 2978f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall rewriteAutoreleasePool(pass); 29814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis rewriteProperties(pass); 2998f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall removeRetainReleaseDealloc(pass); 3007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnusedInitDelegate(pass); 3017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis removeZeroOutPropsInDealloc(pass); 3028f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall makeAssignARCSafe(pass); 3037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnbridgedCasts(pass); 3048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall rewriteBlockObjCVariable(pass); 305fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis checkAPIUses(pass); 3068f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 3078f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3088f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstd::vector<TransformFn> arcmt::getAllTransformations() { 3098f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall std::vector<TransformFn> transforms; 3108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall transforms.push_back(independentTransforms); 312fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis // This depends on previous transformations removing various expressions. 313fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis transforms.push_back(removeEmptyStatementsAndDealloc); 3148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return transforms; 3168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 317