TransUnusedInitDelegate.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. //===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // Transformations:
  9. //===----------------------------------------------------------------------===//
  10. //
  11. // rewriteUnusedInitDelegate:
  12. //
  13. // Rewrites an unused result of calling a delegate initialization, to assigning
  14. // the result to self.
  15. // e.g
  16. // [self init];
  17. // ---->
  18. // self = [self init];
  19. //
  20. //===----------------------------------------------------------------------===//
  21. #include "Transforms.h"
  22. #include "Internals.h"
  23. #include "clang/AST/ASTContext.h"
  24. #include "clang/Sema/SemaDiagnostic.h"
  25. using namespace clang;
  26. using namespace arcmt;
  27. using namespace trans;
  28. namespace {
  29. class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
  30. Stmt *Body;
  31. MigrationPass &Pass;
  32. ExprSet Removables;
  33. public:
  34. UnusedInitRewriter(MigrationPass &pass)
  35. : Body(nullptr), Pass(pass) { }
  36. void transformBody(Stmt *body, Decl *ParentD) {
  37. Body = body;
  38. collectRemovables(body, Removables);
  39. TraverseStmt(body);
  40. }
  41. bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
  42. if (ME->isDelegateInitCall() &&
  43. isRemovable(ME) &&
  44. Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
  45. ME->getExprLoc())) {
  46. Transaction Trans(Pass.TA);
  47. Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
  48. ME->getExprLoc());
  49. SourceRange ExprRange = ME->getSourceRange();
  50. Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
  51. std::string retStr = ")) return ";
  52. retStr += getNilString(Pass);
  53. Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
  54. }
  55. return true;
  56. }
  57. private:
  58. bool isRemovable(Expr *E) const {
  59. return Removables.count(E);
  60. }
  61. };
  62. } // anonymous namespace
  63. void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
  64. BodyTransform<UnusedInitRewriter> trans(pass);
  65. trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
  66. }