diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h | 118 |
1 files changed, 112 insertions, 6 deletions
diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h b/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h index 5e4db56..445c3e5 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/ParentMap.h" #include "llvm/ADT/DenseSet.h" namespace clang { @@ -25,6 +26,8 @@ namespace arcmt { namespace trans { + class MigrationContext; + //===----------------------------------------------------------------------===// // Transformations. //===----------------------------------------------------------------------===// @@ -32,21 +35,124 @@ namespace trans { void rewriteAutoreleasePool(MigrationPass &pass); void rewriteUnbridgedCasts(MigrationPass &pass); void makeAssignARCSafe(MigrationPass &pass); -void removeRetainReleaseDealloc(MigrationPass &pass); -void removeZeroOutPropsInDealloc(MigrationPass &pass); -void rewriteProperties(MigrationPass &pass); -void rewriteBlockObjCVariable(MigrationPass &pass); +void removeRetainReleaseDeallocFinalize(MigrationPass &pass); +void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass); void rewriteUnusedInitDelegate(MigrationPass &pass); void checkAPIUses(MigrationPass &pass); -void removeEmptyStatementsAndDealloc(MigrationPass &pass); +void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass); + +class BodyContext { + MigrationContext &MigrateCtx; + ParentMap PMap; + Stmt *TopStmt; + +public: + BodyContext(MigrationContext &MigrateCtx, Stmt *S) + : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {} + + MigrationContext &getMigrationContext() { return MigrateCtx; } + ParentMap &getParentMap() { return PMap; } + Stmt *getTopStmt() { return TopStmt; } +}; + +class ObjCImplementationContext { + MigrationContext &MigrateCtx; + ObjCImplementationDecl *ImpD; + +public: + ObjCImplementationContext(MigrationContext &MigrateCtx, + ObjCImplementationDecl *D) + : MigrateCtx(MigrateCtx), ImpD(D) {} + + MigrationContext &getMigrationContext() { return MigrateCtx; } + ObjCImplementationDecl *getImplementationDecl() { return ImpD; } +}; + +class ASTTraverser { +public: + virtual ~ASTTraverser(); + virtual void traverseTU(MigrationContext &MigrateCtx) { } + virtual void traverseBody(BodyContext &BodyCtx) { } + virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {} +}; + +class MigrationContext { + std::vector<ASTTraverser *> Traversers; + +public: + MigrationPass &Pass; + + struct GCAttrOccurrence { + enum AttrKind { Weak, Strong } Kind; + SourceLocation Loc; + QualType ModifiedType; + Decl *Dcl; + /// \brief true if the attribute is owned, e.g. it is in a body and not just + /// in an interface. + bool FullyMigratable; + }; + std::vector<GCAttrOccurrence> GCAttrs; + llvm::DenseSet<unsigned> AttrSet; + llvm::DenseSet<unsigned> RemovedAttrSet; + + /// \brief Set of raw '@' locations for 'assign' properties group that contain + /// GC __weak. + llvm::DenseSet<unsigned> AtPropsWeak; + + explicit MigrationContext(MigrationPass &pass) : Pass(pass) {} + ~MigrationContext(); + + typedef std::vector<ASTTraverser *>::iterator traverser_iterator; + traverser_iterator traversers_begin() { return Traversers.begin(); } + traverser_iterator traversers_end() { return Traversers.end(); } + + void addTraverser(ASTTraverser *traverser) { + Traversers.push_back(traverser); + } + + bool isGCOwnedNonObjC(QualType T); + bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) { + return rewritePropertyAttribute(fromAttr, StringRef(), atLoc); + } + bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr, + SourceLocation atLoc); + bool addPropertyAttribute(StringRef attr, SourceLocation atLoc); + + void traverse(TranslationUnitDecl *TU); + + void dumpGCAttrs(); +}; + +class PropertyRewriteTraverser : public ASTTraverser { +public: + virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx); +}; + +class BlockObjCVariableTraverser : public ASTTraverser { +public: + virtual void traverseBody(BodyContext &BodyCtx); +}; + +// GC transformations + +class GCAttrsTraverser : public ASTTraverser { +public: + virtual void traverseTU(MigrationContext &MigrateCtx); +}; + +class GCCollectableCallsTraverser : public ASTTraverser { +public: + virtual void traverseBody(BodyContext &BodyCtx); +}; //===----------------------------------------------------------------------===// // Helpers. //===----------------------------------------------------------------------===// /// \brief Determine whether we can add weak to the given type. -bool canApplyWeak(ASTContext &Ctx, QualType type); +bool canApplyWeak(ASTContext &Ctx, QualType type, + bool AllowOnUnknownClass = false); /// \brief 'Loc' is the end of a statement range. This returns the location /// immediately after the semicolon following the statement. |