Home | History | Annotate | Line # | Download | only in ARCMigrate
      1      1.1  joerg //===-- Transforms.h - Transformations to ARC mode --------------*- C++ -*-===//
      2      1.1  joerg //
      3      1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4      1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5      1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6      1.1  joerg //
      7      1.1  joerg //===----------------------------------------------------------------------===//
      8      1.1  joerg 
      9      1.1  joerg #ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
     10      1.1  joerg #define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
     11      1.1  joerg 
     12      1.1  joerg #include "clang/AST/ParentMap.h"
     13      1.1  joerg #include "clang/AST/RecursiveASTVisitor.h"
     14      1.1  joerg #include "llvm/ADT/DenseSet.h"
     15      1.1  joerg #include "llvm/Support/SaveAndRestore.h"
     16      1.1  joerg 
     17      1.1  joerg namespace clang {
     18      1.1  joerg   class Decl;
     19      1.1  joerg   class Stmt;
     20      1.1  joerg   class BlockDecl;
     21      1.1  joerg   class ObjCMethodDecl;
     22      1.1  joerg   class FunctionDecl;
     23      1.1  joerg 
     24      1.1  joerg namespace arcmt {
     25      1.1  joerg   class MigrationPass;
     26      1.1  joerg 
     27      1.1  joerg namespace trans {
     28      1.1  joerg 
     29      1.1  joerg   class MigrationContext;
     30      1.1  joerg 
     31      1.1  joerg //===----------------------------------------------------------------------===//
     32      1.1  joerg // Transformations.
     33      1.1  joerg //===----------------------------------------------------------------------===//
     34      1.1  joerg 
     35      1.1  joerg void rewriteAutoreleasePool(MigrationPass &pass);
     36      1.1  joerg void rewriteUnbridgedCasts(MigrationPass &pass);
     37      1.1  joerg void makeAssignARCSafe(MigrationPass &pass);
     38      1.1  joerg void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
     39      1.1  joerg void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
     40      1.1  joerg void rewriteUnusedInitDelegate(MigrationPass &pass);
     41      1.1  joerg void checkAPIUses(MigrationPass &pass);
     42      1.1  joerg 
     43      1.1  joerg void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
     44      1.1  joerg 
     45      1.1  joerg class BodyContext {
     46      1.1  joerg   MigrationContext &MigrateCtx;
     47      1.1  joerg   ParentMap PMap;
     48      1.1  joerg   Stmt *TopStmt;
     49      1.1  joerg 
     50      1.1  joerg public:
     51      1.1  joerg   BodyContext(MigrationContext &MigrateCtx, Stmt *S)
     52      1.1  joerg     : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
     53      1.1  joerg 
     54      1.1  joerg   MigrationContext &getMigrationContext() { return MigrateCtx; }
     55      1.1  joerg   ParentMap &getParentMap() { return PMap; }
     56      1.1  joerg   Stmt *getTopStmt() { return TopStmt; }
     57      1.1  joerg };
     58      1.1  joerg 
     59      1.1  joerg class ObjCImplementationContext {
     60      1.1  joerg   MigrationContext &MigrateCtx;
     61      1.1  joerg   ObjCImplementationDecl *ImpD;
     62      1.1  joerg 
     63      1.1  joerg public:
     64      1.1  joerg   ObjCImplementationContext(MigrationContext &MigrateCtx,
     65      1.1  joerg                             ObjCImplementationDecl *D)
     66      1.1  joerg     : MigrateCtx(MigrateCtx), ImpD(D) {}
     67      1.1  joerg 
     68      1.1  joerg   MigrationContext &getMigrationContext() { return MigrateCtx; }
     69      1.1  joerg   ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
     70      1.1  joerg };
     71      1.1  joerg 
     72      1.1  joerg class ASTTraverser {
     73      1.1  joerg public:
     74      1.1  joerg   virtual ~ASTTraverser();
     75      1.1  joerg   virtual void traverseTU(MigrationContext &MigrateCtx) { }
     76      1.1  joerg   virtual void traverseBody(BodyContext &BodyCtx) { }
     77      1.1  joerg   virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
     78      1.1  joerg };
     79      1.1  joerg 
     80      1.1  joerg class MigrationContext {
     81      1.1  joerg   std::vector<ASTTraverser *> Traversers;
     82      1.1  joerg 
     83      1.1  joerg public:
     84      1.1  joerg   MigrationPass &Pass;
     85      1.1  joerg 
     86      1.1  joerg   struct GCAttrOccurrence {
     87      1.1  joerg     enum AttrKind { Weak, Strong } Kind;
     88      1.1  joerg     SourceLocation Loc;
     89      1.1  joerg     QualType ModifiedType;
     90      1.1  joerg     Decl *Dcl;
     91      1.1  joerg     /// true if the attribute is owned, e.g. it is in a body and not just
     92      1.1  joerg     /// in an interface.
     93      1.1  joerg     bool FullyMigratable;
     94      1.1  joerg   };
     95      1.1  joerg   std::vector<GCAttrOccurrence> GCAttrs;
     96  1.1.1.2  joerg   llvm::DenseSet<SourceLocation> AttrSet;
     97  1.1.1.2  joerg   llvm::DenseSet<SourceLocation> RemovedAttrSet;
     98      1.1  joerg 
     99      1.1  joerg   /// Set of raw '@' locations for 'assign' properties group that contain
    100      1.1  joerg   /// GC __weak.
    101  1.1.1.2  joerg   llvm::DenseSet<SourceLocation> AtPropsWeak;
    102      1.1  joerg 
    103      1.1  joerg   explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
    104      1.1  joerg   ~MigrationContext();
    105      1.1  joerg 
    106      1.1  joerg   typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
    107      1.1  joerg   traverser_iterator traversers_begin() { return Traversers.begin(); }
    108      1.1  joerg   traverser_iterator traversers_end() { return Traversers.end(); }
    109      1.1  joerg 
    110      1.1  joerg   void addTraverser(ASTTraverser *traverser) {
    111      1.1  joerg     Traversers.push_back(traverser);
    112      1.1  joerg   }
    113      1.1  joerg 
    114      1.1  joerg   bool isGCOwnedNonObjC(QualType T);
    115      1.1  joerg   bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
    116      1.1  joerg     return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
    117      1.1  joerg   }
    118      1.1  joerg   bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
    119      1.1  joerg                                 SourceLocation atLoc);
    120      1.1  joerg   bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
    121      1.1  joerg 
    122      1.1  joerg   void traverse(TranslationUnitDecl *TU);
    123      1.1  joerg 
    124      1.1  joerg   void dumpGCAttrs();
    125      1.1  joerg };
    126      1.1  joerg 
    127      1.1  joerg class PropertyRewriteTraverser : public ASTTraverser {
    128      1.1  joerg public:
    129      1.1  joerg   void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override;
    130      1.1  joerg };
    131      1.1  joerg 
    132      1.1  joerg class BlockObjCVariableTraverser : public ASTTraverser {
    133      1.1  joerg public:
    134      1.1  joerg   void traverseBody(BodyContext &BodyCtx) override;
    135      1.1  joerg };
    136      1.1  joerg 
    137      1.1  joerg class ProtectedScopeTraverser : public ASTTraverser {
    138      1.1  joerg public:
    139      1.1  joerg   void traverseBody(BodyContext &BodyCtx) override;
    140      1.1  joerg };
    141      1.1  joerg 
    142      1.1  joerg // GC transformations
    143      1.1  joerg 
    144      1.1  joerg class GCAttrsTraverser : public ASTTraverser {
    145      1.1  joerg public:
    146      1.1  joerg   void traverseTU(MigrationContext &MigrateCtx) override;
    147      1.1  joerg };
    148      1.1  joerg 
    149      1.1  joerg class GCCollectableCallsTraverser : public ASTTraverser {
    150      1.1  joerg public:
    151      1.1  joerg   void traverseBody(BodyContext &BodyCtx) override;
    152      1.1  joerg };
    153      1.1  joerg 
    154      1.1  joerg //===----------------------------------------------------------------------===//
    155      1.1  joerg // Helpers.
    156      1.1  joerg //===----------------------------------------------------------------------===//
    157      1.1  joerg 
    158      1.1  joerg /// Determine whether we can add weak to the given type.
    159      1.1  joerg bool canApplyWeak(ASTContext &Ctx, QualType type,
    160      1.1  joerg                   bool AllowOnUnknownClass = false);
    161      1.1  joerg 
    162      1.1  joerg bool isPlusOneAssign(const BinaryOperator *E);
    163      1.1  joerg bool isPlusOne(const Expr *E);
    164      1.1  joerg 
    165      1.1  joerg /// 'Loc' is the end of a statement range. This returns the location
    166      1.1  joerg /// immediately after the semicolon following the statement.
    167      1.1  joerg /// If no semicolon is found or the location is inside a macro, the returned
    168      1.1  joerg /// source location will be invalid.
    169      1.1  joerg SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx,
    170      1.1  joerg                                      bool IsDecl = false);
    171      1.1  joerg 
    172      1.1  joerg /// 'Loc' is the end of a statement range. This returns the location
    173      1.1  joerg /// of the semicolon following the statement.
    174      1.1  joerg /// If no semicolon is found or the location is inside a macro, the returned
    175      1.1  joerg /// source location will be invalid.
    176      1.1  joerg SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx,
    177      1.1  joerg                                      bool IsDecl = false);
    178      1.1  joerg 
    179      1.1  joerg bool hasSideEffects(Expr *E, ASTContext &Ctx);
    180      1.1  joerg bool isGlobalVar(Expr *E);
    181      1.1  joerg /// Returns "nil" or "0" if 'nil' macro is not actually defined.
    182      1.1  joerg StringRef getNilString(MigrationPass &Pass);
    183      1.1  joerg 
    184      1.1  joerg template <typename BODY_TRANS>
    185      1.1  joerg class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
    186      1.1  joerg   MigrationPass &Pass;
    187      1.1  joerg   Decl *ParentD;
    188      1.1  joerg 
    189      1.1  joerg   typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base;
    190      1.1  joerg public:
    191      1.1  joerg   BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { }
    192      1.1  joerg 
    193      1.1  joerg   bool TraverseStmt(Stmt *rootS) {
    194      1.1  joerg     if (rootS)
    195      1.1  joerg       BODY_TRANS(Pass).transformBody(rootS, ParentD);
    196      1.1  joerg     return true;
    197      1.1  joerg   }
    198      1.1  joerg 
    199      1.1  joerg   bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
    200      1.1  joerg     SaveAndRestore<Decl *> SetParent(ParentD, D);
    201      1.1  joerg     return base::TraverseObjCMethodDecl(D);
    202      1.1  joerg   }
    203      1.1  joerg };
    204      1.1  joerg 
    205      1.1  joerg typedef llvm::DenseSet<Expr *> ExprSet;
    206      1.1  joerg 
    207      1.1  joerg void clearRefsIn(Stmt *S, ExprSet &refs);
    208      1.1  joerg template <typename iterator>
    209      1.1  joerg void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
    210      1.1  joerg   for (; begin != end; ++begin)
    211      1.1  joerg     clearRefsIn(*begin, refs);
    212      1.1  joerg }
    213      1.1  joerg 
    214      1.1  joerg void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
    215      1.1  joerg 
    216      1.1  joerg void collectRemovables(Stmt *S, ExprSet &exprs);
    217      1.1  joerg 
    218      1.1  joerg } // end namespace trans
    219      1.1  joerg 
    220      1.1  joerg } // end namespace arcmt
    221      1.1  joerg 
    222      1.1  joerg } // end namespace clang
    223      1.1  joerg 
    224      1.1  joerg #endif
    225