17196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===-- Transforms.h - Tranformations to ARC mode ---------------*- C++ -*-===//
27196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//
37196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
47196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//
57196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
67196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
77196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//
87196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
97196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/AST/RecursiveASTVisitor.h"
14e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis#include "clang/AST/ParentMap.h"
157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "llvm/ADT/DenseSet.h"
1676a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis#include "llvm/Support/SaveAndRestore.h"
177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace clang {
197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class Decl;
207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class Stmt;
217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class BlockDecl;
227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class ObjCMethodDecl;
237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class FunctionDecl;
247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace arcmt {
267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class MigrationPass;
277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace trans {
297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
30e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  class MigrationContext;
31e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Transformations.
347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteAutoreleasePool(MigrationPass &pass);
377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteUnbridgedCasts(MigrationPass &pass);
387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid makeAssignARCSafe(MigrationPass &pass);
39e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid removeRetainReleaseDeallocFinalize(MigrationPass &pass);
40e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteUnusedInitDelegate(MigrationPass &pass);
42fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidisvoid checkAPIUses(MigrationPass &pass);
437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
44e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
45fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis
46e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass BodyContext {
47e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  MigrationContext &MigrateCtx;
48e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  ParentMap PMap;
49e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  Stmt *TopStmt;
50e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
51e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
52e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  BodyContext(MigrationContext &MigrateCtx, Stmt *S)
53e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
54e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
55e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  MigrationContext &getMigrationContext() { return MigrateCtx; }
56e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  ParentMap &getParentMap() { return PMap; }
57e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  Stmt *getTopStmt() { return TopStmt; }
58e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
59e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
60b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidisclass ObjCImplementationContext {
61b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  MigrationContext &MigrateCtx;
62b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  ObjCImplementationDecl *ImpD;
63b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis
64b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidispublic:
65b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  ObjCImplementationContext(MigrationContext &MigrateCtx,
66b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis                            ObjCImplementationDecl *D)
67b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis    : MigrateCtx(MigrateCtx), ImpD(D) {}
68b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis
69b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  MigrationContext &getMigrationContext() { return MigrateCtx; }
70b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
71b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis};
72b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis
73e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass ASTTraverser {
74e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
75e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  virtual ~ASTTraverser();
76b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  virtual void traverseTU(MigrationContext &MigrateCtx) { }
77e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  virtual void traverseBody(BodyContext &BodyCtx) { }
78b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
79e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
80e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
81e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass MigrationContext {
82e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  std::vector<ASTTraverser *> Traversers;
83e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
84e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
85f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis  MigrationPass &Pass;
86f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis
87f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis  struct GCAttrOccurrence {
88f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    enum AttrKind { Weak, Strong } Kind;
89f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    SourceLocation Loc;
90f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    QualType ModifiedType;
91f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    Decl *Dcl;
92f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    /// \brief true if the attribute is owned, e.g. it is in a body and not just
93f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    /// in an interface.
94f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis    bool FullyMigratable;
95f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis  };
96f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis  std::vector<GCAttrOccurrence> GCAttrs;
97f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis  llvm::DenseSet<unsigned> AttrSet;
987cfd7fe020144afe61ffe4de6c43c10340c415a7Argyrios Kyrtzidis  llvm::DenseSet<unsigned> RemovedAttrSet;
99f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis
100b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis  /// \brief Set of raw '@' locations for 'assign' properties group that contain
101b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis  /// GC __weak.
102b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis  llvm::DenseSet<unsigned> AtPropsWeak;
103bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis
104e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
105e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  ~MigrationContext();
106e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
107e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
108e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  traverser_iterator traversers_begin() { return Traversers.begin(); }
109e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  traverser_iterator traversers_end() { return Traversers.end(); }
110e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
111e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  void addTraverser(ASTTraverser *traverser) {
112e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    Traversers.push_back(traverser);
113e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  }
114e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
1151fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis  bool isGCOwnedNonObjC(QualType T);
1166da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis  bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
1176da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis    return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
1186da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis  }
119b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis  bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
120b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis                                SourceLocation atLoc);
1216da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis  bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
1221fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis
123e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  void traverse(TranslationUnitDecl *TU);
12417ac3197941b9f135424dfe3900577a04407c5c2Argyrios Kyrtzidis
12517ac3197941b9f135424dfe3900577a04407c5c2Argyrios Kyrtzidis  void dumpGCAttrs();
126e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
127e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
128b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidisclass PropertyRewriteTraverser : public ASTTraverser {
129b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidispublic:
130b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis  virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
131b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis};
132b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis
1332a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidisclass BlockObjCVariableTraverser : public ASTTraverser {
1342a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidispublic:
1352a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidis  virtual void traverseBody(BodyContext &BodyCtx);
1362a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidis};
1372a2781805a6b55573d369e34c5dcfba307ce83e9Argyrios Kyrtzidis
138e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// GC transformations
139e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
140f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidisclass GCAttrsTraverser : public ASTTraverser {
141f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidispublic:
142f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis  virtual void traverseTU(MigrationContext &MigrateCtx);
143f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis};
144f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis
145e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass GCCollectableCallsTraverser : public ASTTraverser {
146e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
147e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  virtual void traverseBody(BodyContext &BodyCtx);
148e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
149e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
1507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Helpers.
1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
15486625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis/// \brief Determine whether we can add weak to the given type.
15512192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidisbool canApplyWeak(ASTContext &Ctx, QualType type,
15612192cf50a96cb59a3039af044b7fa97f043101cArgyrios Kyrtzidis                  bool AllowOnUnknownClass = false);
15786625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis
1581b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidisbool isPlusOneAssign(const BinaryOperator *E);
1591b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis
1607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// \brief 'Loc' is the end of a statement range. This returns the location
1617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// immediately after the semicolon following the statement.
1627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned
1637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// source location will be invalid.
1647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios KyrtzidisSourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
1657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
166aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// \brief \arg Loc is the end of a statement range. This returns the location
167aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// of the semicolon following the statement.
168aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned
169aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// source location will be invalid.
170aec230d29835285777ecc467e268c83b33a2addeArgyrios KyrtzidisSourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx);
171aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis
1727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisbool hasSideEffects(Expr *E, ASTContext &Ctx);
1732c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidisbool isGlobalVar(Expr *E);
17418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis/// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
17518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios KyrtzidisStringRef getNilString(ASTContext &Ctx);
1767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidistemplate <typename BODY_TRANS>
1787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
1797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  MigrationPass &Pass;
18076a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis  Decl *ParentD;
1817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
18276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis  typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base;
1837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic:
18476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis  BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(0) { }
1857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
186b1094a0621c3bf91141f7cd9684ca80b357ae61eArgyrios Kyrtzidis  bool TraverseStmt(Stmt *rootS) {
187fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis    if (rootS)
18876a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis      BODY_TRANS(Pass).transformBody(rootS, ParentD);
1897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis    return true;
1907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  }
19176a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis
19276a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
19376a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis    SaveAndRestore<Decl *> SetParent(ParentD, D);
19476a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis    return base::TraverseObjCMethodDecl(D);
19576a5245d7fb558625453ebe2281ee0bc9c93c245Argyrios Kyrtzidis  }
1967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis};
1977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidistypedef llvm::DenseSet<Expr *> ExprSet;
1997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid clearRefsIn(Stmt *S, ExprSet &refs);
2017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidistemplate <typename iterator>
2027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
2037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  for (; begin != end; ++begin)
2047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis    clearRefsIn(*begin, refs);
2057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}
2067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
2087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid collectRemovables(Stmt *S, ExprSet &exprs);
2107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end namespace trans
2127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end namespace arcmt
2147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end namespace clang
2167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
2177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#endif
218