freebsd-dev/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp
Dimitry Andric dff0c46c97 Upgrade our copy of llvm/clang to trunk r154661, in preparation of the
upcoming 3.1 release (expected in a few weeks).  Preliminary release
notes can be found at: <http://llvm.org/docs/ReleaseNotes.html>

MFC after:	2 weeks
2012-04-16 21:23:25 +00:00

78 lines
2.1 KiB
C++

//===--- TransUnusedInitDelegate.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.
//
//===----------------------------------------------------------------------===//
// Transformations:
//===----------------------------------------------------------------------===//
//
// rewriteUnusedInitDelegate:
//
// Rewrites an unused result of calling a delegate initialization, to assigning
// the result to self.
// e.g
// [self init];
// ---->
// self = [self init];
//
//===----------------------------------------------------------------------===//
#include "Transforms.h"
#include "Internals.h"
#include "clang/Sema/SemaDiagnostic.h"
using namespace clang;
using namespace arcmt;
using namespace trans;
namespace {
class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
Stmt *Body;
MigrationPass &Pass;
ExprSet Removables;
public:
UnusedInitRewriter(MigrationPass &pass)
: Body(0), Pass(pass) { }
void transformBody(Stmt *body) {
Body = body;
collectRemovables(body, Removables);
TraverseStmt(body);
}
bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
if (ME->isDelegateInitCall() &&
isRemovable(ME) &&
Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
ME->getExprLoc())) {
Transaction Trans(Pass.TA);
Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
ME->getExprLoc());
SourceRange ExprRange = ME->getSourceRange();
Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
std::string retStr = ")) return ";
retStr += getNilString(Pass.Ctx);
Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
}
return true;
}
private:
bool isRemovable(Expr *E) const {
return Removables.count(E);
}
};
} // anonymous namespace
void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
BodyTransform<UnusedInitRewriter> trans(pass);
trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
}