diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp | 86 |
1 files changed, 54 insertions, 32 deletions
diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp index d0bc332..3ad05e6 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp @@ -22,11 +22,53 @@ #include "Transforms.h" #include "Internals.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Basic/SourceManager.h" using namespace clang; using namespace arcmt; using namespace trans; -using llvm::StringRef; + +static bool isEmptyARCMTMacroStatement(NullStmt *S, + std::vector<SourceLocation> &MacroLocs, + ASTContext &Ctx) { + if (!S->hasLeadingEmptyMacro()) + return false; + + SourceLocation SemiLoc = S->getSemiLoc(); + if (SemiLoc.isInvalid() || SemiLoc.isMacroID()) + return false; + + if (MacroLocs.empty()) + return false; + + SourceManager &SM = Ctx.getSourceManager(); + std::vector<SourceLocation>::iterator + I = std::upper_bound(MacroLocs.begin(), MacroLocs.end(), SemiLoc, + SourceManager::LocBeforeThanCompare(SM)); + --I; + SourceLocation + AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size()); + assert(AfterMacroLoc.isFileID()); + + if (AfterMacroLoc == SemiLoc) + return true; + + int RelOffs = 0; + if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs)) + return false; + if (RelOffs < 0) + return false; + + // We make the reasonable assumption that a semicolon after 100 characters + // means that it is not the next token after our macro. If this assumption + // fails it is not critical, we will just fail to clear out, e.g., an empty + // 'if'. + if (RelOffs - getARCMTMacroName().size() > 100) + return false; + + SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx); + return AfterMacroSemiLoc == SemiLoc; +} namespace { @@ -34,14 +76,14 @@ namespace { /// transformations. class EmptyChecker : public StmtVisitor<EmptyChecker, bool> { ASTContext &Ctx; - llvm::DenseSet<unsigned> &MacroLocs; + std::vector<SourceLocation> &MacroLocs; public: - EmptyChecker(ASTContext &ctx, llvm::DenseSet<unsigned> ¯oLocs) + EmptyChecker(ASTContext &ctx, std::vector<SourceLocation> ¯oLocs) : Ctx(ctx), MacroLocs(macroLocs) { } bool VisitNullStmt(NullStmt *S) { - return isMacroLoc(S->getLeadingEmptyMacroLoc()); + return isEmptyARCMTMacroStatement(S, MacroLocs, Ctx); } bool VisitCompoundStmt(CompoundStmt *S) { if (S->body_empty()) @@ -103,23 +145,14 @@ public: 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) { } + EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { } bool TraverseStmtExpr(StmtExpr *E) { CompoundStmt *S = E->getSubStmt(); @@ -139,17 +172,12 @@ public: 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)) { + if (EmptyChecker(Pass.Ctx, Pass.ARCMTMacroLocs).Visit(S)) { Transaction Trans(Pass.TA); Pass.TA.removeStmt(S); } @@ -158,8 +186,8 @@ private: } // anonymous namespace -static bool isBodyEmpty(CompoundStmt *body, - ASTContext &Ctx, llvm::DenseSet<unsigned> &MacroLocs) { +static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, + std::vector<SourceLocation> &MacroLocs) { for (CompoundStmt::body_iterator I = body->body_begin(), E = body->body_end(); I != E; ++I) if (!EmptyChecker(Ctx, MacroLocs).Visit(*I)) @@ -168,8 +196,7 @@ static bool isBodyEmpty(CompoundStmt *body, return true; } -static void removeDeallocMethod(MigrationPass &pass, - llvm::DenseSet<unsigned> &MacroLocs) { +static void removeDeallocMethod(MigrationPass &pass) { ASTContext &Ctx = pass.Ctx; TransformActions &TA = pass.TA; DeclContext *DC = Ctx.getTranslationUnitDecl(); @@ -184,7 +211,7 @@ static void removeDeallocMethod(MigrationPass &pass, ObjCMethodDecl *MD = *MI; if (MD->getMethodFamily() == OMF_dealloc) { if (MD->hasBody() && - isBodyEmpty(MD->getCompoundBody(), Ctx, MacroLocs)) { + isBodyEmpty(MD->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { Transaction Trans(TA); TA.remove(MD->getSourceRange()); } @@ -195,14 +222,9 @@ static void removeDeallocMethod(MigrationPass &pass, } 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()); + EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); - removeDeallocMethod(pass, MacroLocs); + removeDeallocMethod(pass); for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { Transaction Trans(pass.TA); |