diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-06-21 20:20:42 +0000 | 
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-06-21 20:20:42 +0000 | 
| commit | e5acb84e636b1728175a5cb86b874718d336317f (patch) | |
| tree | a70ee0dc11a457fe5fb6983e1bb680eb57ead245 /clang/lib/ARCMigrate | |
| parent | e5b475c6881ff8ce6de1f4bc42e452c1d8059d83 (diff) | |
| download | bcm5719-llvm-e5acb84e636b1728175a5cb86b874718d336317f.tar.gz bcm5719-llvm-e5acb84e636b1728175a5cb86b874718d336317f.zip  | |
[arcmt] Merge 'removeEmptyStatements' and 'removeDeallocMethod' passes to cut down on one compilation
pass and increase migration speed.
llvm-svn: 133540
Diffstat (limited to 'clang/lib/ARCMigrate')
| -rw-r--r-- | clang/lib/ARCMigrate/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | clang/lib/ARCMigrate/TransDeallocMethod.cpp | 47 | ||||
| -rw-r--r-- | clang/lib/ARCMigrate/TransEmptyStatements.cpp | 161 | ||||
| -rw-r--r-- | clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp | 211 | ||||
| -rw-r--r-- | clang/lib/ARCMigrate/Transforms.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/ARCMigrate/Transforms.h | 4 | 
6 files changed, 215 insertions, 216 deletions
diff --git a/clang/lib/ARCMigrate/CMakeLists.txt b/clang/lib/ARCMigrate/CMakeLists.txt index 56db384bef2..7e5fc13bba4 100644 --- a/clang/lib/ARCMigrate/CMakeLists.txt +++ b/clang/lib/ARCMigrate/CMakeLists.txt @@ -8,7 +8,6 @@ add_clang_library(clangARCMigrate    TransARCAssign.cpp    TransAutoreleasePool.cpp    TransBlockObjCVariable.cpp -  TransDeallocMethod.cpp    TransEmptyStatements.cpp    TransformActions.cpp    Transforms.cpp diff --git a/clang/lib/ARCMigrate/TransDeallocMethod.cpp b/clang/lib/ARCMigrate/TransDeallocMethod.cpp deleted file mode 100644 index a7c3c1e9d64..00000000000 --- a/clang/lib/ARCMigrate/TransDeallocMethod.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===--- TransDeallocMethod.cpp - Tranformations to ARC mode --------------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; -using llvm::StringRef; - -void trans::removeDeallocMethod(MigrationPass &pass) { -  ASTContext &Ctx = pass.Ctx; -  TransformActions &TA = pass.TA; -  DeclContext *DC = Ctx.getTranslationUnitDecl(); -  ObjCMethodDecl *DeallocMethodDecl = 0; -  IdentifierInfo *II = &Ctx.Idents.get("dealloc"); - -  for (DeclContext::decl_iterator -         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { -    Decl *D = *I; -    if (ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(D)) { -      DeallocMethodDecl = 0; -      for (ObjCImplementationDecl::instmeth_iterator -             I = IMD->instmeth_begin(), E = IMD->instmeth_end(); -          I != E; ++I) { -        ObjCMethodDecl *OMD = *I; -        if (OMD->isInstanceMethod() && -            OMD->getSelector() == Ctx.Selectors.getSelector(0, &II)) { -          DeallocMethodDecl = OMD; -          break; -        } -      } -      if (DeallocMethodDecl &&  -          DeallocMethodDecl->getCompoundBody()->body_empty()) { -        Transaction Trans(TA); -        TA.remove(DeallocMethodDecl->getSourceRange()); -      } -    } -  } -} diff --git a/clang/lib/ARCMigrate/TransEmptyStatements.cpp b/clang/lib/ARCMigrate/TransEmptyStatements.cpp deleted file mode 100644 index 1b62bbf0354..00000000000 --- a/clang/lib/ARCMigrate/TransEmptyStatements.cpp +++ /dev/null @@ -1,161 +0,0 @@ -//===--- TransEmptyStatements.cpp - Tranformations to ARC mode ------------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// removeEmptyStatements: -// -// Removes empty statements that are leftovers from previous transformations. -// e.g for -// -//  [x retain]; -// -// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements -// will remove. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/StmtVisitor.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; -using llvm::StringRef; - -namespace { - -class EmptyStatementsRemover : -                            public RecursiveASTVisitor<EmptyStatementsRemover> { -  MigrationPass &Pass; -  llvm::DenseSet<unsigned> MacroLocs; - -public: -  EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { -    for (unsigned i = 0, e = Pass.ARCMTMacroLocs.size(); i != e; ++i) -      MacroLocs.insert(Pass.ARCMTMacroLocs[i].getRawEncoding()); -  } - -  bool TraverseStmtExpr(StmtExpr *E) { -    CompoundStmt *S = E->getSubStmt(); -    for (CompoundStmt::body_iterator -           I = S->body_begin(), E = S->body_end(); I != E; ++I) { -      if (I != E - 1) -        check(*I); -      TraverseStmt(*I); -    } -    return true; -  } - -  bool VisitCompoundStmt(CompoundStmt *S) { -    for (CompoundStmt::body_iterator -           I = S->body_begin(), E = S->body_end(); I != E; ++I) -      check(*I); -    return true; -  } - -  bool isMacroLoc(SourceLocation loc) { -    if (loc.isInvalid()) return false; -    return MacroLocs.count(loc.getRawEncoding()); -  } - -  ASTContext &getContext() { return Pass.Ctx; } - -private: -  /// \brief Returns true if the statement became empty due to previous -  /// transformations. -  class EmptyChecker : public StmtVisitor<EmptyChecker, bool> { -    EmptyStatementsRemover &Trans; - -  public: -    EmptyChecker(EmptyStatementsRemover &trans) : Trans(trans) { } - -    bool VisitNullStmt(NullStmt *S) { -      return Trans.isMacroLoc(S->getLeadingEmptyMacroLoc()); -    } -    bool VisitCompoundStmt(CompoundStmt *S) { -      if (S->body_empty()) -        return false; // was already empty, not because of transformations. -      for (CompoundStmt::body_iterator -             I = S->body_begin(), E = S->body_end(); I != E; ++I) -        if (!Visit(*I)) -          return false; -      return true; -    } -    bool VisitIfStmt(IfStmt *S) { -      if (S->getConditionVariable()) -        return false; -      Expr *condE = S->getCond(); -      if (!condE) -        return false; -      if (hasSideEffects(condE, Trans.getContext())) -        return false; -      if (!S->getThen() || !Visit(S->getThen())) -        return false; -      if (S->getElse() && !Visit(S->getElse())) -        return false; -      return true; -    } -    bool VisitWhileStmt(WhileStmt *S) { -      if (S->getConditionVariable()) -        return false; -      Expr *condE = S->getCond(); -      if (!condE) -        return false; -      if (hasSideEffects(condE, Trans.getContext())) -        return false; -      if (!S->getBody()) -        return false; -      return Visit(S->getBody()); -    } -    bool VisitDoStmt(DoStmt *S) { -      Expr *condE = S->getCond(); -      if (!condE) -        return false; -      if (hasSideEffects(condE, Trans.getContext())) -        return false; -      if (!S->getBody()) -        return false; -      return Visit(S->getBody()); -    } -    bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { -      Expr *Exp = S->getCollection(); -      if (!Exp) -        return false; -      if (hasSideEffects(Exp, Trans.getContext())) -        return false; -      if (!S->getBody()) -        return false; -      return Visit(S->getBody()); -    } -    bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { -      if (!S->getSubStmt()) -        return false; -      return Visit(S->getSubStmt()); -    } -  }; - -  void check(Stmt *S) { -    if (!S) return; -    if (EmptyChecker(*this).Visit(S)) { -      Transaction Trans(Pass.TA); -      Pass.TA.removeStmt(S); -    } -  } -}; - -} // anonymous namespace - -void trans::removeEmptyStatements(MigrationPass &pass) { -  EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); - -  for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { -    Transaction Trans(pass.TA); -    pass.TA.remove(pass.ARCMTMacroLocs[i]); -  } -} diff --git a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp new file mode 100644 index 00000000000..d0bc332ff16 --- /dev/null +++ b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp @@ -0,0 +1,211 @@ +//===--- TransEmptyStatements.cpp - Tranformations to ARC mode ------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// removeEmptyStatementsAndDealloc: +// +// Removes empty statements that are leftovers from previous transformations. +// e.g for +// +//  [x retain]; +// +// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements +// will remove. +// +//===----------------------------------------------------------------------===// + +#include "Transforms.h" +#include "Internals.h" +#include "clang/AST/StmtVisitor.h" + +using namespace clang; +using namespace arcmt; +using namespace trans; +using llvm::StringRef; + +namespace { + +/// \brief Returns true if the statement became empty due to previous +/// transformations. +class EmptyChecker : public StmtVisitor<EmptyChecker, bool> { +  ASTContext &Ctx; +  llvm::DenseSet<unsigned> &MacroLocs; + +public: +  EmptyChecker(ASTContext &ctx, llvm::DenseSet<unsigned> ¯oLocs) +    : Ctx(ctx), MacroLocs(macroLocs) { } + +  bool VisitNullStmt(NullStmt *S) { +    return isMacroLoc(S->getLeadingEmptyMacroLoc()); +  } +  bool VisitCompoundStmt(CompoundStmt *S) { +    if (S->body_empty()) +      return false; // was already empty, not because of transformations. +    for (CompoundStmt::body_iterator +           I = S->body_begin(), E = S->body_end(); I != E; ++I) +      if (!Visit(*I)) +        return false; +    return true; +  } +  bool VisitIfStmt(IfStmt *S) { +    if (S->getConditionVariable()) +      return false; +    Expr *condE = S->getCond(); +    if (!condE) +      return false; +    if (hasSideEffects(condE, Ctx)) +      return false; +    if (!S->getThen() || !Visit(S->getThen())) +      return false; +    if (S->getElse() && !Visit(S->getElse())) +      return false; +    return true; +  } +  bool VisitWhileStmt(WhileStmt *S) { +    if (S->getConditionVariable()) +      return false; +    Expr *condE = S->getCond(); +    if (!condE) +      return false; +    if (hasSideEffects(condE, Ctx)) +      return false; +    if (!S->getBody()) +      return false; +    return Visit(S->getBody()); +  } +  bool VisitDoStmt(DoStmt *S) { +    Expr *condE = S->getCond(); +    if (!condE) +      return false; +    if (hasSideEffects(condE, Ctx)) +      return false; +    if (!S->getBody()) +      return false; +    return Visit(S->getBody()); +  } +  bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { +    Expr *Exp = S->getCollection(); +    if (!Exp) +      return false; +    if (hasSideEffects(Exp, Ctx)) +      return false; +    if (!S->getBody()) +      return false; +    return Visit(S->getBody()); +  } +  bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { +    if (!S->getSubStmt()) +      return false; +    return Visit(S->getSubStmt()); +  } + +private: +  bool isMacroLoc(SourceLocation loc) { +    if (loc.isInvalid()) return false; +    return MacroLocs.count(loc.getRawEncoding()); +  } +}; + +class EmptyStatementsRemover : +                            public RecursiveASTVisitor<EmptyStatementsRemover> { +  MigrationPass &Pass; +  llvm::DenseSet<unsigned> &MacroLocs; + +public: +  EmptyStatementsRemover(MigrationPass &pass, +                         llvm::DenseSet<unsigned> ¯oLocs) +    : Pass(pass), MacroLocs(macroLocs) { } + +  bool TraverseStmtExpr(StmtExpr *E) { +    CompoundStmt *S = E->getSubStmt(); +    for (CompoundStmt::body_iterator +           I = S->body_begin(), E = S->body_end(); I != E; ++I) { +      if (I != E - 1) +        check(*I); +      TraverseStmt(*I); +    } +    return true; +  } + +  bool VisitCompoundStmt(CompoundStmt *S) { +    for (CompoundStmt::body_iterator +           I = S->body_begin(), E = S->body_end(); I != E; ++I) +      check(*I); +    return true; +  } + +  bool isMacroLoc(SourceLocation loc) { +    if (loc.isInvalid()) return false; +    return MacroLocs.count(loc.getRawEncoding()); +  } + +  ASTContext &getContext() { return Pass.Ctx; } + +private: +  void check(Stmt *S) { +    if (!S) return; +    if (EmptyChecker(Pass.Ctx, MacroLocs).Visit(S)) { +      Transaction Trans(Pass.TA); +      Pass.TA.removeStmt(S); +    } +  } +}; + +} // anonymous namespace + +static bool isBodyEmpty(CompoundStmt *body, +                        ASTContext &Ctx, llvm::DenseSet<unsigned> &MacroLocs) { +  for (CompoundStmt::body_iterator +         I = body->body_begin(), E = body->body_end(); I != E; ++I) +    if (!EmptyChecker(Ctx, MacroLocs).Visit(*I)) +      return false; + +  return true; +} + +static void removeDeallocMethod(MigrationPass &pass, +                                llvm::DenseSet<unsigned> &MacroLocs) { +  ASTContext &Ctx = pass.Ctx; +  TransformActions &TA = pass.TA; +  DeclContext *DC = Ctx.getTranslationUnitDecl(); + +  typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> +    impl_iterator; +  for (impl_iterator I = impl_iterator(DC->decls_begin()), +                     E = impl_iterator(DC->decls_end()); I != E; ++I) { +    for (ObjCImplementationDecl::instmeth_iterator +           MI = (*I)->instmeth_begin(), +           ME = (*I)->instmeth_end(); MI != ME; ++MI) { +      ObjCMethodDecl *MD = *MI; +      if (MD->getMethodFamily() == OMF_dealloc) { +        if (MD->hasBody() && +            isBodyEmpty(MD->getCompoundBody(), Ctx, MacroLocs)) { +          Transaction Trans(TA); +          TA.remove(MD->getSourceRange()); +        } +        break; +      } +    } +  } +} + +void trans::removeEmptyStatementsAndDealloc(MigrationPass &pass) { +  llvm::DenseSet<unsigned> MacroLocs; +  for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) +    MacroLocs.insert(pass.ARCMTMacroLocs[i].getRawEncoding()); + +  EmptyStatementsRemover(pass, MacroLocs) +    .TraverseDecl(pass.Ctx.getTranslationUnitDecl()); + +  removeDeallocMethod(pass, MacroLocs); + +  for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { +    Transaction Trans(pass.TA); +    pass.TA.remove(pass.ARCMTMacroLocs[i]); +  } +} diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp index 0650e3b94fb..3c2e3fc5323 100644 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ b/clang/lib/ARCMigrate/Transforms.cpp @@ -224,12 +224,9 @@ static void independentTransforms(MigrationPass &pass) {  std::vector<TransformFn> arcmt::getAllTransformations() {    std::vector<TransformFn> transforms; -  // This must come first since rewriteAutoreleasePool depends on -release -  // calls being present to determine the @autorelease ending scope.    transforms.push_back(independentTransforms); - -  transforms.push_back(removeEmptyStatements); -  transforms.push_back(removeDeallocMethod); +  // This depends on previous transformations removing various expressions. +  transforms.push_back(removeEmptyStatementsAndDealloc);    return transforms;  } diff --git a/clang/lib/ARCMigrate/Transforms.h b/clang/lib/ARCMigrate/Transforms.h index d95b1bc3234..6cc6085d617 100644 --- a/clang/lib/ARCMigrate/Transforms.h +++ b/clang/lib/ARCMigrate/Transforms.h @@ -34,13 +34,13 @@ void rewriteUnbridgedCasts(MigrationPass &pass);  void rewriteAllocCopyWithZone(MigrationPass &pass);  void makeAssignARCSafe(MigrationPass &pass);  void removeRetainReleaseDealloc(MigrationPass &pass); -void removeEmptyStatements(MigrationPass &pass);  void removeZeroOutPropsInDealloc(MigrationPass &pass);  void changeIvarsOfAssignProperties(MigrationPass &pass);  void rewriteBlockObjCVariable(MigrationPass &pass); -void removeDeallocMethod(MigrationPass &pass);  void rewriteUnusedInitDelegate(MigrationPass &pass); +void removeEmptyStatementsAndDealloc(MigrationPass &pass); +  //===----------------------------------------------------------------------===//  // Helpers.  //===----------------------------------------------------------------------===//  | 

