summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp86
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> &macroLocs)
+ EmptyChecker(ASTContext &ctx, std::vector<SourceLocation> &macroLocs)
: 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> &macroLocs)
- : 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);
OpenPOWER on IntegriCloud