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