1 //===-- Transforms.h - Tranformations to ARC mode ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
11 #define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
13 #include "clang/AST/RecursiveASTVisitor.h"
14 #include "clang/AST/ParentMap.h"
15 #include "llvm/ADT/DenseSet.h"
16 #include "llvm/Support/SaveAndRestore.h"
30 class MigrationContext;
32 //===----------------------------------------------------------------------===//
34 //===----------------------------------------------------------------------===//
36 void rewriteAutoreleasePool(MigrationPass &pass);
37 void rewriteUnbridgedCasts(MigrationPass &pass);
38 void makeAssignARCSafe(MigrationPass &pass);
39 void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
40 void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
41 void rewriteUnusedInitDelegate(MigrationPass &pass);
42 void checkAPIUses(MigrationPass &pass);
44 void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
47 MigrationContext &MigrateCtx;
52 BodyContext(MigrationContext &MigrateCtx, Stmt *S)
53 : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
55 MigrationContext &getMigrationContext() { return MigrateCtx; }
56 ParentMap &getParentMap() { return PMap; }
57 Stmt *getTopStmt() { return TopStmt; }
60 class ObjCImplementationContext {
61 MigrationContext &MigrateCtx;
62 ObjCImplementationDecl *ImpD;
65 ObjCImplementationContext(MigrationContext &MigrateCtx,
66 ObjCImplementationDecl *D)
67 : MigrateCtx(MigrateCtx), ImpD(D) {}
69 MigrationContext &getMigrationContext() { return MigrateCtx; }
70 ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
75 virtual ~ASTTraverser();
76 virtual void traverseTU(MigrationContext &MigrateCtx) { }
77 virtual void traverseBody(BodyContext &BodyCtx) { }
78 virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
81 class MigrationContext {
82 std::vector<ASTTraverser *> Traversers;
87 struct GCAttrOccurrence {
88 enum AttrKind { Weak, Strong } Kind;
90 QualType ModifiedType;
92 /// \brief true if the attribute is owned, e.g. it is in a body and not just
96 std::vector<GCAttrOccurrence> GCAttrs;
97 llvm::DenseSet<unsigned> AttrSet;
98 llvm::DenseSet<unsigned> RemovedAttrSet;
100 /// \brief Set of raw '@' locations for 'assign' properties group that contain
102 llvm::DenseSet<unsigned> AtPropsWeak;
104 explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
107 typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
108 traverser_iterator traversers_begin() { return Traversers.begin(); }
109 traverser_iterator traversers_end() { return Traversers.end(); }
111 void addTraverser(ASTTraverser *traverser) {
112 Traversers.push_back(traverser);
115 bool isGCOwnedNonObjC(QualType T);
116 bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
117 return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
119 bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
120 SourceLocation atLoc);
121 bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
123 void traverse(TranslationUnitDecl *TU);
128 class PropertyRewriteTraverser : public ASTTraverser {
130 virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
133 class BlockObjCVariableTraverser : public ASTTraverser {
135 virtual void traverseBody(BodyContext &BodyCtx);
138 // GC transformations
140 class GCAttrsTraverser : public ASTTraverser {
142 virtual void traverseTU(MigrationContext &MigrateCtx);
145 class GCCollectableCallsTraverser : public ASTTraverser {
147 virtual void traverseBody(BodyContext &BodyCtx);
150 //===----------------------------------------------------------------------===//
152 //===----------------------------------------------------------------------===//
154 /// \brief Determine whether we can add weak to the given type.
155 bool canApplyWeak(ASTContext &Ctx, QualType type,
156 bool AllowOnUnknownClass = false);
158 bool isPlusOneAssign(const BinaryOperator *E);
160 /// \brief 'Loc' is the end of a statement range. This returns the location
161 /// immediately after the semicolon following the statement.
162 /// If no semicolon is found or the location is inside a macro, the returned
163 /// source location will be invalid.
164 SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
166 /// \brief \arg Loc is the end of a statement range. This returns the location
167 /// of the semicolon following the statement.
168 /// If no semicolon is found or the location is inside a macro, the returned
169 /// source location will be invalid.
170 SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx);
172 bool hasSideEffects(Expr *E, ASTContext &Ctx);
173 bool isGlobalVar(Expr *E);
174 /// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
175 StringRef getNilString(ASTContext &Ctx);
177 template <typename BODY_TRANS>
178 class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
182 typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base;
184 BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(0) { }
186 bool TraverseStmt(Stmt *rootS) {
188 BODY_TRANS(Pass).transformBody(rootS, ParentD);
192 bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
193 SaveAndRestore<Decl *> SetParent(ParentD, D);
194 return base::TraverseObjCMethodDecl(D);
198 typedef llvm::DenseSet<Expr *> ExprSet;
200 void clearRefsIn(Stmt *S, ExprSet &refs);
201 template <typename iterator>
202 void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
203 for (; begin != end; ++begin)
204 clearRefsIn(*begin, refs);
207 void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
209 void collectRemovables(Stmt *S, ExprSet &exprs);
211 } // end namespace trans
213 } // end namespace arcmt
215 } // end namespace clang