blob: 60ed32aef4ce6d0574c03a4635a4bac2f919432e [file] [log] [blame]
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +00001//===--- TransUnusedInitDelegate.cpp - Tranformations to ARC mode ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// Transformations:
10//===----------------------------------------------------------------------===//
11//
12// rewriteUnusedInitDelegate:
13//
14// Rewrites an unused result of calling a delegate initialization, to assigning
15// the result to self.
16// e.g
17// [self init];
18// ---->
19// self = [self init];
20//
21//===----------------------------------------------------------------------===//
22
23#include "Transforms.h"
24#include "Internals.h"
25#include "clang/Sema/SemaDiagnostic.h"
26
27using namespace clang;
28using namespace arcmt;
29using namespace trans;
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000030
31namespace {
32
33class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000034 Stmt *Body;
35 MigrationPass &Pass;
36
37 ExprSet Removables;
38
39public:
Argyrios Kyrtzidisb1094a02011-06-23 21:21:33 +000040 UnusedInitRewriter(MigrationPass &pass)
41 : Body(0), Pass(pass) { }
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000042
43 void transformBody(Stmt *body) {
44 Body = body;
45 collectRemovables(body, Removables);
46 TraverseStmt(body);
47 }
48
49 bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
50 if (ME->isDelegateInitCall() &&
51 isRemovable(ME) &&
52 Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
53 ME->getExprLoc())) {
54 Transaction Trans(Pass.TA);
55 Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
56 ME->getExprLoc());
Argyrios Kyrtzidisd76e1cd2012-03-31 01:34:06 +000057 SourceRange ExprRange = ME->getSourceRange();
58 Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
59 std::string retStr = ")) return ";
60 retStr += getNilString(Pass.Ctx);
61 Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
Argyrios Kyrtzidis7196d062011-06-21 20:20:39 +000062 }
63 return true;
64 }
65
66private:
67 bool isRemovable(Expr *E) const {
68 return Removables.count(E);
69 }
70};
71
72} // anonymous namespace
73
74void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
75 BodyTransform<UnusedInitRewriter> trans(pass);
76 trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
77}