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"
29 class MigrationContext;
31 //===----------------------------------------------------------------------===//
33 //===----------------------------------------------------------------------===//
35 void rewriteAutoreleasePool(MigrationPass &pass);
36 void rewriteUnbridgedCasts(MigrationPass &pass);
37 void makeAssignARCSafe(MigrationPass &pass);
38 void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
39 void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
40 void rewriteUnusedInitDelegate(MigrationPass &pass);
41 void checkAPIUses(MigrationPass &pass);
43 void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
46 MigrationContext &MigrateCtx;
51 BodyContext(MigrationContext &MigrateCtx, Stmt *S)
52 : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
54 MigrationContext &getMigrationContext() { return MigrateCtx; }
55 ParentMap &getParentMap() { return PMap; }
56 Stmt *getTopStmt() { return TopStmt; }
59 class ObjCImplementationContext {
60 MigrationContext &MigrateCtx;
61 ObjCImplementationDecl *ImpD;
64 ObjCImplementationContext(MigrationContext &MigrateCtx,
65 ObjCImplementationDecl *D)
66 : MigrateCtx(MigrateCtx), ImpD(D) {}
68 MigrationContext &getMigrationContext() { return MigrateCtx; }
69 ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
74 virtual ~ASTTraverser();
75 virtual void traverseTU(MigrationContext &MigrateCtx) { }
76 virtual void traverseBody(BodyContext &BodyCtx) { }
77 virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
80 class MigrationContext {
81 std::vector<ASTTraverser *> Traversers;
86 struct GCAttrOccurrence {
87 enum AttrKind { Weak, Strong } Kind;
89 QualType ModifiedType;
91 /// \brief true if the attribute is owned, e.g. it is in a body and not just
95 std::vector<GCAttrOccurrence> GCAttrs;
96 llvm::DenseSet<unsigned> AttrSet;
97 llvm::DenseSet<unsigned> RemovedAttrSet;
99 /// \brief Set of raw '@' locations for 'assign' properties group that contain
101 llvm::DenseSet<unsigned> AtPropsWeak;
103 explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
106 typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
107 traverser_iterator traversers_begin() { return Traversers.begin(); }
108 traverser_iterator traversers_end() { return Traversers.end(); }
110 void addTraverser(ASTTraverser *traverser) {
111 Traversers.push_back(traverser);
114 bool isGCOwnedNonObjC(QualType T);
115 bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
116 return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
118 bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
119 SourceLocation atLoc);
120 bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
122 void traverse(TranslationUnitDecl *TU);
127 class PropertyRewriteTraverser : public ASTTraverser {
129 virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
132 class BlockObjCVariableTraverser : public ASTTraverser {
134 virtual void traverseBody(BodyContext &BodyCtx);
137 // GC transformations
139 class GCAttrsTraverser : public ASTTraverser {
141 virtual void traverseTU(MigrationContext &MigrateCtx);
144 class GCCollectableCallsTraverser : public ASTTraverser {
146 virtual void traverseBody(BodyContext &BodyCtx);
149 //===----------------------------------------------------------------------===//
151 //===----------------------------------------------------------------------===//
153 /// \brief Determine whether we can add weak to the given type.
154 bool canApplyWeak(ASTContext &Ctx, QualType type,
155 bool AllowOnUnknownClass = false);
157 /// \brief 'Loc' is the end of a statement range. This returns the location
158 /// immediately after the semicolon following the statement.
159 /// If no semicolon is found or the location is inside a macro, the returned
160 /// source location will be invalid.
161 SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
163 /// \brief \arg Loc is the end of a statement range. This returns the location
164 /// of the semicolon following the statement.
165 /// If no semicolon is found or the location is inside a macro, the returned
166 /// source location will be invalid.
167 SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx);
169 bool hasSideEffects(Expr *E, ASTContext &Ctx);
170 bool isGlobalVar(Expr *E);
171 /// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
172 StringRef getNilString(ASTContext &Ctx);
174 template <typename BODY_TRANS>
175 class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
179 BodyTransform(MigrationPass &pass) : Pass(pass) { }
181 bool TraverseStmt(Stmt *rootS) {
183 BODY_TRANS(Pass).transformBody(rootS);
188 typedef llvm::DenseSet<Expr *> ExprSet;
190 void clearRefsIn(Stmt *S, ExprSet &refs);
191 template <typename iterator>
192 void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
193 for (; begin != end; ++begin)
194 clearRefsIn(*begin, refs);
197 void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
199 void collectRemovables(Stmt *S, ExprSet &exprs);
201 } // end namespace trans
203 } // end namespace arcmt
205 } // end namespace clang