clang API Documentation
00001 //===--- TransUnusedInitDelegate.cpp - Transformations 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/AST/ASTContext.h" 00026 #include "clang/Sema/SemaDiagnostic.h" 00027 00028 using namespace clang; 00029 using namespace arcmt; 00030 using namespace trans; 00031 00032 namespace { 00033 00034 class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> { 00035 Stmt *Body; 00036 MigrationPass &Pass; 00037 00038 ExprSet Removables; 00039 00040 public: 00041 UnusedInitRewriter(MigrationPass &pass) 00042 : Body(nullptr), Pass(pass) { } 00043 00044 void transformBody(Stmt *body, Decl *ParentD) { 00045 Body = body; 00046 collectRemovables(body, Removables); 00047 TraverseStmt(body); 00048 } 00049 00050 bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { 00051 if (ME->isDelegateInitCall() && 00052 isRemovable(ME) && 00053 Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message, 00054 ME->getExprLoc())) { 00055 Transaction Trans(Pass.TA); 00056 Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message, 00057 ME->getExprLoc()); 00058 SourceRange ExprRange = ME->getSourceRange(); 00059 Pass.TA.insert(ExprRange.getBegin(), "if (!(self = "); 00060 std::string retStr = ")) return "; 00061 retStr += getNilString(Pass.Ctx); 00062 Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr); 00063 } 00064 return true; 00065 } 00066 00067 private: 00068 bool isRemovable(Expr *E) const { 00069 return Removables.count(E); 00070 } 00071 }; 00072 00073 } // anonymous namespace 00074 00075 void trans::rewriteUnusedInitDelegate(MigrationPass &pass) { 00076 BodyTransform<UnusedInitRewriter> trans(pass); 00077 trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 00078 }