clang API Documentation
00001 //===--- TransUnusedInitDelegate.cpp - Tranformations to ARC mode ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // Transformations: 00010 //===----------------------------------------------------------------------===// 00011 // 00012 // rewriteUnusedInitDelegate: 00013 // 00014 // Rewrites an unused result of calling a delegate initialization, to assigning 00015 // the result to self. 00016 // e.g 00017 // [self init]; 00018 // ----> 00019 // self = [self init]; 00020 // 00021 //===----------------------------------------------------------------------===// 00022 00023 #include "Transforms.h" 00024 #include "Internals.h" 00025 #include "clang/Sema/SemaDiagnostic.h" 00026 00027 using namespace clang; 00028 using namespace arcmt; 00029 using namespace trans; 00030 00031 namespace { 00032 00033 class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> { 00034 Stmt *Body; 00035 MigrationPass &Pass; 00036 00037 ExprSet Removables; 00038 00039 public: 00040 UnusedInitRewriter(MigrationPass &pass) 00041 : Body(0), Pass(pass) { } 00042 00043 void transformBody(Stmt *body) { 00044 Body = body; 00045 collectRemovables(body, Removables); 00046 TraverseStmt(body); 00047 } 00048 00049 bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { 00050 if (ME->isDelegateInitCall() && 00051 isRemovable(ME) && 00052 Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message, 00053 ME->getExprLoc())) { 00054 Transaction Trans(Pass.TA); 00055 Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message, 00056 ME->getExprLoc()); 00057 SourceRange ExprRange = ME->getSourceRange(); 00058 Pass.TA.insert(ExprRange.getBegin(), "if (!(self = "); 00059 std::string retStr = ")) return "; 00060 retStr += getNilString(Pass.Ctx); 00061 Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr); 00062 } 00063 return true; 00064 } 00065 00066 private: 00067 bool isRemovable(Expr *E) const { 00068 return Removables.count(E); 00069 } 00070 }; 00071 00072 } // anonymous namespace 00073 00074 void trans::rewriteUnusedInitDelegate(MigrationPass &pass) { 00075 BodyTransform<UnusedInitRewriter> trans(pass); 00076 trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 00077 }