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