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