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