]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h
MFC r234353:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / ARCMigrate / Transforms.h
1 //===-- 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"
14 #include "clang/AST/ParentMap.h"
15 #include "llvm/ADT/DenseSet.h"
16
17 namespace clang {
18   class Decl;
19   class Stmt;
20   class BlockDecl;
21   class ObjCMethodDecl;
22   class FunctionDecl;
23
24 namespace arcmt {
25   class MigrationPass;
26
27 namespace trans {
28
29   class MigrationContext;
30
31 //===----------------------------------------------------------------------===//
32 // Transformations.
33 //===----------------------------------------------------------------------===//
34
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);
42
43 void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
44
45 class BodyContext {
46   MigrationContext &MigrateCtx;
47   ParentMap PMap;
48   Stmt *TopStmt;
49
50 public:
51   BodyContext(MigrationContext &MigrateCtx, Stmt *S)
52     : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
53
54   MigrationContext &getMigrationContext() { return MigrateCtx; }
55   ParentMap &getParentMap() { return PMap; }
56   Stmt *getTopStmt() { return TopStmt; }
57 };
58
59 class ObjCImplementationContext {
60   MigrationContext &MigrateCtx;
61   ObjCImplementationDecl *ImpD;
62
63 public:
64   ObjCImplementationContext(MigrationContext &MigrateCtx,
65                             ObjCImplementationDecl *D)
66     : MigrateCtx(MigrateCtx), ImpD(D) {}
67
68   MigrationContext &getMigrationContext() { return MigrateCtx; }
69   ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
70 };
71
72 class ASTTraverser {
73 public:
74   virtual ~ASTTraverser();
75   virtual void traverseTU(MigrationContext &MigrateCtx) { }
76   virtual void traverseBody(BodyContext &BodyCtx) { }
77   virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
78 };
79
80 class MigrationContext {
81   std::vector<ASTTraverser *> Traversers;
82
83 public:
84   MigrationPass &Pass;
85
86   struct GCAttrOccurrence {
87     enum AttrKind { Weak, Strong } Kind;
88     SourceLocation Loc;
89     QualType ModifiedType;
90     Decl *Dcl;
91     /// \brief true if the attribute is owned, e.g. it is in a body and not just
92     /// in an interface.
93     bool FullyMigratable;
94   };
95   std::vector<GCAttrOccurrence> GCAttrs;
96   llvm::DenseSet<unsigned> AttrSet;
97   llvm::DenseSet<unsigned> RemovedAttrSet;
98
99   /// \brief Set of raw '@' locations for 'assign' properties group that contain
100   /// GC __weak.
101   llvm::DenseSet<unsigned> AtPropsWeak;
102
103   explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
104   ~MigrationContext();
105   
106   typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
107   traverser_iterator traversers_begin() { return Traversers.begin(); }
108   traverser_iterator traversers_end() { return Traversers.end(); }
109
110   void addTraverser(ASTTraverser *traverser) {
111     Traversers.push_back(traverser);
112   }
113
114   bool isGCOwnedNonObjC(QualType T);
115   bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
116     return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
117   }
118   bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
119                                 SourceLocation atLoc);
120   bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
121
122   void traverse(TranslationUnitDecl *TU);
123
124   void dumpGCAttrs();
125 };
126
127 class PropertyRewriteTraverser : public ASTTraverser {
128 public:
129   virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
130 };
131
132 class BlockObjCVariableTraverser : public ASTTraverser {
133 public:
134   virtual void traverseBody(BodyContext &BodyCtx);
135 };
136
137 // GC transformations
138
139 class GCAttrsTraverser : public ASTTraverser {
140 public:
141   virtual void traverseTU(MigrationContext &MigrateCtx);
142 };
143
144 class GCCollectableCallsTraverser : public ASTTraverser {
145 public:
146   virtual void traverseBody(BodyContext &BodyCtx);
147 };
148
149 //===----------------------------------------------------------------------===//
150 // Helpers.
151 //===----------------------------------------------------------------------===//
152
153 /// \brief Determine whether we can add weak to the given type.
154 bool canApplyWeak(ASTContext &Ctx, QualType type,
155                   bool AllowOnUnknownClass = false);
156
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);
162
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);
168
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);
173
174 template <typename BODY_TRANS>
175 class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
176   MigrationPass &Pass;
177
178 public:
179   BodyTransform(MigrationPass &pass) : Pass(pass) { }
180
181   bool TraverseStmt(Stmt *rootS) {
182     if (rootS)
183       BODY_TRANS(Pass).transformBody(rootS);
184     return true;
185   }
186 };
187
188 typedef llvm::DenseSet<Expr *> ExprSet;
189
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);
195 }
196
197 void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
198
199 void collectRemovables(Stmt *S, ExprSet &exprs);
200
201 } // end namespace trans
202
203 } // end namespace arcmt
204
205 } // end namespace clang
206
207 #endif