clang API Documentation

Transforms.h
Go to the documentation of this file.
00001 //===-- Transforms.h - Tranformations to ARC mode ---------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
00011 #define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
00012 
00013 #include "clang/AST/RecursiveASTVisitor.h"
00014 #include "clang/AST/ParentMap.h"
00015 #include "llvm/ADT/DenseSet.h"
00016 
00017 namespace clang {
00018   class Decl;
00019   class Stmt;
00020   class BlockDecl;
00021   class ObjCMethodDecl;
00022   class FunctionDecl;
00023 
00024 namespace arcmt {
00025   class MigrationPass;
00026 
00027 namespace trans {
00028 
00029   class MigrationContext;
00030 
00031 //===----------------------------------------------------------------------===//
00032 // Transformations.
00033 //===----------------------------------------------------------------------===//
00034 
00035 void rewriteAutoreleasePool(MigrationPass &pass);
00036 void rewriteUnbridgedCasts(MigrationPass &pass);
00037 void makeAssignARCSafe(MigrationPass &pass);
00038 void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
00039 void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
00040 void rewriteUnusedInitDelegate(MigrationPass &pass);
00041 void checkAPIUses(MigrationPass &pass);
00042 
00043 void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
00044 
00045 class BodyContext {
00046   MigrationContext &MigrateCtx;
00047   ParentMap PMap;
00048   Stmt *TopStmt;
00049 
00050 public:
00051   BodyContext(MigrationContext &MigrateCtx, Stmt *S)
00052     : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
00053 
00054   MigrationContext &getMigrationContext() { return MigrateCtx; }
00055   ParentMap &getParentMap() { return PMap; }
00056   Stmt *getTopStmt() { return TopStmt; }
00057 };
00058 
00059 class ObjCImplementationContext {
00060   MigrationContext &MigrateCtx;
00061   ObjCImplementationDecl *ImpD;
00062 
00063 public:
00064   ObjCImplementationContext(MigrationContext &MigrateCtx,
00065                             ObjCImplementationDecl *D)
00066     : MigrateCtx(MigrateCtx), ImpD(D) {}
00067 
00068   MigrationContext &getMigrationContext() { return MigrateCtx; }
00069   ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
00070 };
00071 
00072 class ASTTraverser {
00073 public:
00074   virtual ~ASTTraverser();
00075   virtual void traverseTU(MigrationContext &MigrateCtx) { }
00076   virtual void traverseBody(BodyContext &BodyCtx) { }
00077   virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
00078 };
00079 
00080 class MigrationContext {
00081   std::vector<ASTTraverser *> Traversers;
00082 
00083 public:
00084   MigrationPass &Pass;
00085 
00086   struct GCAttrOccurrence {
00087     enum AttrKind { Weak, Strong } Kind;
00088     SourceLocation Loc;
00089     QualType ModifiedType;
00090     Decl *Dcl;
00091     /// \brief true if the attribute is owned, e.g. it is in a body and not just
00092     /// in an interface.
00093     bool FullyMigratable;
00094   };
00095   std::vector<GCAttrOccurrence> GCAttrs;
00096   llvm::DenseSet<unsigned> AttrSet;
00097   llvm::DenseSet<unsigned> RemovedAttrSet;
00098 
00099   /// \brief Set of raw '@' locations for 'assign' properties group that contain
00100   /// GC __weak.
00101   llvm::DenseSet<unsigned> AtPropsWeak;
00102 
00103   explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
00104   ~MigrationContext();
00105   
00106   typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
00107   traverser_iterator traversers_begin() { return Traversers.begin(); }
00108   traverser_iterator traversers_end() { return Traversers.end(); }
00109 
00110   void addTraverser(ASTTraverser *traverser) {
00111     Traversers.push_back(traverser);
00112   }
00113 
00114   bool isGCOwnedNonObjC(QualType T);
00115   bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
00116     return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
00117   }
00118   bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
00119                                 SourceLocation atLoc);
00120   bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
00121 
00122   void traverse(TranslationUnitDecl *TU);
00123 
00124   void dumpGCAttrs();
00125 };
00126 
00127 class PropertyRewriteTraverser : public ASTTraverser {
00128 public:
00129   virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
00130 };
00131 
00132 class BlockObjCVariableTraverser : public ASTTraverser {
00133 public:
00134   virtual void traverseBody(BodyContext &BodyCtx);
00135 };
00136 
00137 // GC transformations
00138 
00139 class GCAttrsTraverser : public ASTTraverser {
00140 public:
00141   virtual void traverseTU(MigrationContext &MigrateCtx);
00142 };
00143 
00144 class GCCollectableCallsTraverser : public ASTTraverser {
00145 public:
00146   virtual void traverseBody(BodyContext &BodyCtx);
00147 };
00148 
00149 //===----------------------------------------------------------------------===//
00150 // Helpers.
00151 //===----------------------------------------------------------------------===//
00152 
00153 /// \brief Determine whether we can add weak to the given type.
00154 bool canApplyWeak(ASTContext &Ctx, QualType type,
00155                   bool AllowOnUnknownClass = false);
00156 
00157 /// \brief 'Loc' is the end of a statement range. This returns the location
00158 /// immediately after the semicolon following the statement.
00159 /// If no semicolon is found or the location is inside a macro, the returned
00160 /// source location will be invalid.
00161 SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
00162 
00163 /// \brief \arg Loc is the end of a statement range. This returns the location
00164 /// of the semicolon following the statement.
00165 /// If no semicolon is found or the location is inside a macro, the returned
00166 /// source location will be invalid.
00167 SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx);
00168 
00169 bool hasSideEffects(Expr *E, ASTContext &Ctx);
00170 bool isGlobalVar(Expr *E);
00171 /// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
00172 StringRef getNilString(ASTContext &Ctx);
00173 
00174 template <typename BODY_TRANS>
00175 class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
00176   MigrationPass &Pass;
00177 
00178 public:
00179   BodyTransform(MigrationPass &pass) : Pass(pass) { }
00180 
00181   bool TraverseStmt(Stmt *rootS) {
00182     if (rootS)
00183       BODY_TRANS(Pass).transformBody(rootS);
00184     return true;
00185   }
00186 };
00187 
00188 typedef llvm::DenseSet<Expr *> ExprSet;
00189 
00190 void clearRefsIn(Stmt *S, ExprSet &refs);
00191 template <typename iterator>
00192 void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
00193   for (; begin != end; ++begin)
00194     clearRefsIn(*begin, refs);
00195 }
00196 
00197 void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
00198 
00199 void collectRemovables(Stmt *S, ExprSet &exprs);
00200 
00201 } // end namespace trans
00202 
00203 } // end namespace arcmt
00204 
00205 } // end namespace clang
00206 
00207 #endif