TransUnusedInitDelegate.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //===--- TransUnusedInitDelegate.cpp - Transformations 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. #include "Transforms.h"
  23. #include "Internals.h"
  24. #include "clang/AST/ASTContext.h"
  25. #include "clang/Sema/SemaDiagnostic.h"
  26. using namespace clang;
  27. using namespace arcmt;
  28. using namespace trans;
  29. namespace {
  30. class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
  31. Stmt *Body;
  32. MigrationPass &Pass;
  33. ExprSet Removables;
  34. public:
  35. UnusedInitRewriter(MigrationPass &pass)
  36. : Body(nullptr), Pass(pass) { }
  37. void transformBody(Stmt *body, Decl *ParentD) {
  38. Body = body;
  39. collectRemovables(body, Removables);
  40. TraverseStmt(body);
  41. }
  42. bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
  43. if (ME->isDelegateInitCall() &&
  44. isRemovable(ME) &&
  45. Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
  46. ME->getExprLoc())) {
  47. Transaction Trans(Pass.TA);
  48. Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
  49. ME->getExprLoc());
  50. SourceRange ExprRange = ME->getSourceRange();
  51. Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
  52. std::string retStr = ")) return ";
  53. retStr += getNilString(Pass);
  54. Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
  55. }
  56. return true;
  57. }
  58. private:
  59. bool isRemovable(Expr *E) const {
  60. return Removables.count(E);
  61. }
  62. };
  63. } // anonymous namespace
  64. void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
  65. BodyTransform<UnusedInitRewriter> trans(pass);
  66. trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
  67. }