Transforms.h revision e7ef8556f4ee3012a0479308c993af0fbee448df
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"
167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace clang {
187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class Decl;
197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class Stmt;
207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class BlockDecl;
217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class ObjCMethodDecl;
227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class FunctionDecl;
237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace arcmt {
257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  class MigrationPass;
267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace trans {
287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
29e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  class MigrationContext;
30e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Transformations.
337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteAutoreleasePool(MigrationPass &pass);
367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteUnbridgedCasts(MigrationPass &pass);
377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid makeAssignARCSafe(MigrationPass &pass);
38e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid removeRetainReleaseDeallocFinalize(MigrationPass &pass);
39e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
4014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidisvoid rewriteProperties(MigrationPass &pass);
417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteBlockObjCVariable(MigrationPass &pass);
427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid rewriteUnusedInitDelegate(MigrationPass &pass);
43fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidisvoid checkAPIUses(MigrationPass &pass);
447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
45e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
46fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis
47e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass BodyContext {
48e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  MigrationContext &MigrateCtx;
49e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  ParentMap PMap;
50e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  Stmt *TopStmt;
51e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
52e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
53e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  BodyContext(MigrationContext &MigrateCtx, Stmt *S)
54e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
55e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
56e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  MigrationContext &getMigrationContext() { return MigrateCtx; }
57e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  ParentMap &getParentMap() { return PMap; }
58e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  Stmt *getTopStmt() { return TopStmt; }
59e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
60e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
61e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass ASTTraverser {
62e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
63e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  virtual ~ASTTraverser();
64e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  virtual void traverseBody(BodyContext &BodyCtx) { }
65e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
66e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
67e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass MigrationContext {
68e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  MigrationPass &Pass;
69e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  std::vector<ASTTraverser *> Traversers;
70e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
71e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
72e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
73e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  ~MigrationContext();
74e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
75e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  MigrationPass &getPass() { return Pass; }
76e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
77e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
78e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  traverser_iterator traversers_begin() { return Traversers.begin(); }
79e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  traverser_iterator traversers_end() { return Traversers.end(); }
80e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
81e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  void addTraverser(ASTTraverser *traverser) {
82e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    Traversers.push_back(traverser);
83e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  }
84e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
85e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  void traverse(TranslationUnitDecl *TU);
86e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
87e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
88e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// GC transformations
89e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
90e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass GCCollectableCallsTraverser : public ASTTraverser {
91e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic:
92e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis  virtual void traverseBody(BodyContext &BodyCtx);
93e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis};
94e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis
957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Helpers.
977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
9986625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis/// \brief Determine whether we can add weak to the given type.
10086625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidisbool canApplyWeak(ASTContext &Ctx, QualType type);
10186625b5650cdddc38c0b4cc1eb7fb460478c9d11Argyrios Kyrtzidis
1027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// \brief 'Loc' is the end of a statement range. This returns the location
1037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// immediately after the semicolon following the statement.
1047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned
1057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis/// source location will be invalid.
1067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios KyrtzidisSourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
1077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
108aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// \brief \arg Loc is the end of a statement range. This returns the location
109aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// of the semicolon following the statement.
110aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// If no semicolon is found or the location is inside a macro, the returned
111aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis/// source location will be invalid.
112aec230d29835285777ecc467e268c83b33a2addeArgyrios KyrtzidisSourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx);
113aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis
1147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisbool hasSideEffects(Expr *E, ASTContext &Ctx);
1152c18ca0575b60082f2a9f4563b4071071960d37cArgyrios Kyrtzidisbool isGlobalVar(Expr *E);
11618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis/// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
11718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios KyrtzidisStringRef getNilString(ASTContext &Ctx);
1187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidistemplate <typename BODY_TRANS>
1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
1217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  MigrationPass &Pass;
1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic:
1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  BodyTransform(MigrationPass &pass) : Pass(pass) { }
1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
126b1094a0621c3bf91141f7cd9684ca80b357ae61eArgyrios Kyrtzidis  bool TraverseStmt(Stmt *rootS) {
127fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis    if (rootS)
128fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis      BODY_TRANS(Pass).transformBody(rootS);
1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis    return true;
1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  }
1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis};
1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidistypedef llvm::DenseSet<Expr *> ExprSet;
1347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid clearRefsIn(Stmt *S, ExprSet &refs);
1367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidistemplate <typename iterator>
1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
1387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis  for (; begin != end; ++begin)
1397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis    clearRefsIn(*begin, refs);
1407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}
1417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
1437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid collectRemovables(Stmt *S, ExprSet &exprs);
1457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end namespace trans
1477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end namespace arcmt
1497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // end namespace clang
1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis
1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#endif
153