Transforms.cpp revision b0e1e121b32a9a04b39f1b77b3068bce2f3be05a
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) 4586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSMenuView", true) 4686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSPersistentUIWindowInfo", true) 4786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTableCellView", true) 4886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSATSTypeSetter", true) 4986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSATSGlyphStorage", true) 5086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSLineFragmentRenderingContext", true) 5186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSAttributeDictionary", true) 5286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSParagraphStyle", true) 5386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTextTab", true) 5486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSSimpleHorizontalTypesetter", true) 5586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("_NSCachedAttributedString", true) 5686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSStringDrawingTextStorage", true) 5786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSTextView", true) 5886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Case("NSSubTextStorage", true) 5986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis .Default(false); 6086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (inList) 6286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 6386625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return isClassInWeakBlacklist(cls->getSuperClass()); 6586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 6686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 6712192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidisbool trans::canApplyWeak(ASTContext &Ctx, QualType type, 6812192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis bool AllowOnUnknownClass) { 6986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (!Ctx.getLangOptions().ObjCRuntimeHasWeak) 7086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 7186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 7286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis QualType T = type; 73b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (T.isNull()) 74b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 75b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 7686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis while (const PointerType *ptr = T->getAs<PointerType>()) 7786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis T = ptr->getPointeeType(); 7886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { 7986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); 8012192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) 8186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; // id/NSObject is not safe for weak. 8212192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis if (!AllowOnUnknownClass && Class->isForwardDecl()) 835363e8df5d274cb32c0c47fd2df45aa02cf68dfeArgyrios Kyrtzidis return false; // forward classes are not verifiable, therefore not safe. 8486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (Class->isArcWeakrefUnavailable()) 8586625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 8686625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis if (isClassInWeakBlacklist(Class)) 8786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return false; 8886625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis } 8986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 9086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis return true; 9186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis} 9286625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis 937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// \brief 'Loc' is the end of a statement range. This returns the location 947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// immediately after the semicolon following the statement. 957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// source location will be invalid. 977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios KyrtzidisSourceLocation trans::findLocationAfterSemi(SourceLocation loc, 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ASTContext &Ctx) { 99aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx); 100aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (SemiLoc.isInvalid()) 101aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return SourceLocation(); 102a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return SemiLoc.getLocWithOffset(1); 103aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis} 104aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 105aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// \brief \arg Loc is the end of a statement range. This returns the location 106aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// of the semicolon following the statement. 107aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned 108aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// source location will be invalid. 109aec230d29835285777ecc467e268c83b33a2addeArgyrios KyrtzidisSourceLocation trans::findSemiAfterLocation(SourceLocation loc, 110aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis ASTContext &Ctx) { 1117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 1127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (loc.isMacroID()) { 113433db06b614f26dc6829e86d6ff469e2cca7d4f9Chandler Carruth if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOptions())) 1147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return SourceLocation(); 115edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth loc = SM.getExpansionRange(loc).second; 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; 305e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 306e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic: 307e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { } 308e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 309f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 310f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 311b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) { 312b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext ImplCtx(MigrateCtx, D); 313b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis for (MigrationContext::traverser_iterator 314b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis I = MigrateCtx.traversers_begin(), 315b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis E = MigrateCtx.traversers_end(); I != E; ++I) 316b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis (*I)->traverseObjCImplementation(ImplCtx); 317b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis 318b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis return true; 319b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis } 320b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis 321e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis bool TraverseStmt(Stmt *rootS) { 322e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (!rootS) 323e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 324e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 325e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis BodyContext BodyCtx(MigrateCtx, rootS); 326e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis for (MigrationContext::traverser_iterator 327e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis I = MigrateCtx.traversers_begin(), 328e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis E = MigrateCtx.traversers_end(); I != E; ++I) 329e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis (*I)->traverseBody(BodyCtx); 330e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 331e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 332e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 333e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis}; 334e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 335e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 336e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 337e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios KyrtzidisMigrationContext::~MigrationContext() { 338e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis for (traverser_iterator 339e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis I = traversers_begin(), E = traversers_end(); I != E; ++I) 340e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis delete *I; 341e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 342e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 3431fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidisbool MigrationContext::isGCOwnedNonObjC(QualType T) { 3441fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis while (!T.isNull()) { 3451fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (const AttributedType *AttrT = T->getAs<AttributedType>()) { 3461fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership) 3471fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return !AttrT->getModifiedType()->isObjCRetainableType(); 3481fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 3491fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 3501fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (T->isArrayType()) 3511fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = Pass.Ctx.getBaseElementType(T); 3521fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else if (const PointerType *PT = T->getAs<PointerType>()) 3531fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = PT->getPointeeType(); 3541fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 3551fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis T = RT->getPointeeType(); 3561fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis else 3571fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis break; 3581fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 3591fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 3601fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return false; 3611fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis} 3621fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 363b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidisbool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, 364b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef toAttr, 365b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) { 366b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (atLoc.isMacroID()) 367b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 368b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 369b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 370b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 371b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Break down the source location. 372b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 373b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 374b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Try to load the file buffer. 375b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool invalidTemp = false; 376b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 377b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (invalidTemp) 378b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 379b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 380b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 381b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 382b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // Lex from the start of the given location. 383b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 384b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.Ctx.getLangOptions(), 385b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 386b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token tok; 387b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 388b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 389b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 390b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 391b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 392b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis != "property") 393b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 394b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 395b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::l_paren)) return false; 396b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 397b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token BeforeTok = tok; 398b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Token AfterTok; 399b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok.startToken(); 400b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation AttrLoc; 401b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 402b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 403b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.is(tok::r_paren)) 404b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 405b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 406b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis while (1) { 407b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 408b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis StringRef ident(tok.getRawIdentifierData(), tok.getLength()); 409b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (ident == fromAttr) { 410b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!toAttr.empty()) { 411b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr); 412b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return true; 413b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 414b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // We want to remove the attribute. 415b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AttrLoc = tok.getLocation(); 416b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 417b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 418b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis do { 419b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 420b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (AttrLoc.isValid() && AfterTok.is(tok::unknown)) 421b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok = tok; 422b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren)); 423b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (tok.is(tok::r_paren)) 424b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis break; 425b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (AttrLoc.isInvalid()) 426b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis BeforeTok = tok; 427b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis lexer.LexFromRawLexer(tok); 428b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 429b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 430b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) { 431b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // We want to remove the attribute. 432b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) { 433b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(BeforeTok.getLocation(), 434b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis AfterTok.getLocation())); 435b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) { 436b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation())); 437b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } else { 438b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc)); 439b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 440b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 441b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return true; 442b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 443b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 444b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 445b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis} 446b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 447e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisvoid MigrationContext::traverse(TranslationUnitDecl *TU) { 448f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis for (traverser_iterator 449f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis I = traversers_begin(), E = traversers_end(); I != E; ++I) 450f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis (*I)->traverseTU(*this); 451f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 452e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ASTTransform(*this).TraverseDecl(TU); 453e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 454e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 455e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 4568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// getAllTransformations. 4578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 4588f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 459e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisstatic void traverseAST(MigrationPass &pass) { 460e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext MigrateCtx(pass); 461e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 462e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (pass.isGCMigration()) { 463e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrateCtx.addTraverser(new GCCollectableCallsTraverser); 464f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis MigrateCtx.addTraverser(new GCAttrsTraverser()); 465e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 466b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis MigrateCtx.addTraverser(new PropertyRewriteTraverser()); 467e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 468e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl()); 469e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 470e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 4718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void independentTransforms(MigrationPass &pass) { 4728f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall rewriteAutoreleasePool(pass); 473e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis removeRetainReleaseDeallocFinalize(pass); 4747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnusedInitDelegate(pass); 475e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis removeZeroOutPropsInDeallocFinalize(pass); 4768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall makeAssignARCSafe(pass); 4777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis rewriteUnbridgedCasts(pass); 4788f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall rewriteBlockObjCVariable(pass); 479fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis checkAPIUses(pass); 480e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis traverseAST(pass); 4818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 4828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 483e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisstd::vector<TransformFn> arcmt::getAllTransformations( 484e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis LangOptions::GCMode OrigGCMode) { 4858f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall std::vector<TransformFn> transforms; 4868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 4878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall transforms.push_back(independentTransforms); 488fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis // This depends on previous transformations removing various expressions. 489e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis transforms.push_back(removeEmptyStatementsAndDeallocFinalize); 4908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 4918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return transforms; 4928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 493