blob: 515844656a0f4a45b4a19b79dacf685157752cf8 [file] [log] [blame]
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +00001//===-- Transforms.h - Tranformations to ARC mode ---------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
11#define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
12
13#include "clang/AST/RecursiveASTVisitor.h"
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000014#include "clang/AST/ParentMap.h"
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000015#include "llvm/ADT/DenseSet.h"
16
17namespace clang {
18 class Decl;
19 class Stmt;
20 class BlockDecl;
21 class ObjCMethodDecl;
22 class FunctionDecl;
23
24namespace arcmt {
25 class MigrationPass;
26
27namespace trans {
28
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000029 class MigrationContext;
30
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000031//===----------------------------------------------------------------------===//
32// Transformations.
33//===----------------------------------------------------------------------===//
34
35void rewriteAutoreleasePool(MigrationPass &pass);
36void rewriteUnbridgedCasts(MigrationPass &pass);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000037void makeAssignARCSafe(MigrationPass &pass);
Argyrios Kyrtzidise7ef8552011-11-04 15:58:22 +000038void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
39void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
Argyrios Kyrtzidis14c4b442011-07-13 19:22:00 +000040void rewriteProperties(MigrationPass &pass);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000041void rewriteBlockObjCVariable(MigrationPass &pass);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000042void rewriteUnusedInitDelegate(MigrationPass &pass);
Argyrios Kyrtzidisfd103982011-07-18 07:44:45 +000043void checkAPIUses(MigrationPass &pass);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000044
Argyrios Kyrtzidise7ef8552011-11-04 15:58:22 +000045void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
Argyrios Kyrtzidisfd3455a2011-06-21 20:20:42 +000046
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000047class BodyContext {
48 MigrationContext &MigrateCtx;
49 ParentMap PMap;
50 Stmt *TopStmt;
51
52public:
53 BodyContext(MigrationContext &MigrateCtx, Stmt *S)
54 : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
55
56 MigrationContext &getMigrationContext() { return MigrateCtx; }
57 ParentMap &getParentMap() { return PMap; }
58 Stmt *getTopStmt() { return TopStmt; }
59};
60
61class ASTTraverser {
62public:
63 virtual ~ASTTraverser();
64 virtual void traverseBody(BodyContext &BodyCtx) { }
65};
66
67class MigrationContext {
68 MigrationPass &Pass;
69 std::vector<ASTTraverser *> Traversers;
70
71public:
72 explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
73 ~MigrationContext();
74
75 MigrationPass &getPass() { return Pass; }
76
77 typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
78 traverser_iterator traversers_begin() { return Traversers.begin(); }
79 traverser_iterator traversers_end() { return Traversers.end(); }
80
81 void addTraverser(ASTTraverser *traverser) {
82 Traversers.push_back(traverser);
83 }
84
Argyrios Kyrtzidis1fe42032011-11-04 23:43:03 +000085 bool isGCOwnedNonObjC(QualType T);
86
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000087 void traverse(TranslationUnitDecl *TU);
88};
89
90// GC transformations
91
92class GCCollectableCallsTraverser : public ASTTraverser {
93public:
94 virtual void traverseBody(BodyContext &BodyCtx);
95};
96
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000097//===----------------------------------------------------------------------===//
98// Helpers.
99//===----------------------------------------------------------------------===//
100
Argyrios Kyrtzidis86625b52011-07-12 22:05:17 +0000101/// \brief Determine whether we can add weak to the given type.
102bool canApplyWeak(ASTContext &Ctx, QualType type);
103
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +0000104/// \brief 'Loc' is the end of a statement range. This returns the location
105/// immediately after the semicolon following the statement.
106/// If no semicolon is found or the location is inside a macro, the returned
107/// source location will be invalid.
108SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
109
Argyrios Kyrtzidisaec230d2011-09-01 20:53:18 +0000110/// \brief \arg Loc is the end of a statement range. This returns the location
111/// of the semicolon following the statement.
112/// If no semicolon is found or the location is inside a macro, the returned
113/// source location will be invalid.
114SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx);
115
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +0000116bool hasSideEffects(Expr *E, ASTContext &Ctx);
Argyrios Kyrtzidis2c18ca02011-07-14 23:32:04 +0000117bool isGlobalVar(Expr *E);
Argyrios Kyrtzidis18fd0c62011-07-27 05:28:18 +0000118/// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
119StringRef getNilString(ASTContext &Ctx);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +0000120
121template <typename BODY_TRANS>
122class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
123 MigrationPass &Pass;
124
125public:
126 BodyTransform(MigrationPass &pass) : Pass(pass) { }
127
Argyrios Kyrtzidisb1094a02011-06-23 21:21:33 +0000128 bool TraverseStmt(Stmt *rootS) {
Argyrios Kyrtzidisfd103982011-07-18 07:44:45 +0000129 if (rootS)
130 BODY_TRANS(Pass).transformBody(rootS);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +0000131 return true;
132 }
133};
134
135typedef llvm::DenseSet<Expr *> ExprSet;
136
137void clearRefsIn(Stmt *S, ExprSet &refs);
138template <typename iterator>
139void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
140 for (; begin != end; ++begin)
141 clearRefsIn(*begin, refs);
142}
143
144void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
145
146void collectRemovables(Stmt *S, ExprSet &exprs);
147
148} // end namespace trans
149
150} // end namespace arcmt
151
152} // end namespace clang
153
154#endif