clang  19.0.0git
TransUnusedInitDelegate.cpp
Go to the documentation of this file.
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 
22 #include "Transforms.h"
23 #include "Internals.h"
24 #include "clang/AST/ASTContext.h"
26 
27 using namespace clang;
28 using namespace arcmt;
29 using namespace trans;
30 
31 namespace {
32 
33 class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
34  Stmt *Body;
35  MigrationPass &Pass;
36 
37  ExprSet Removables;
38 
39 public:
40  UnusedInitRewriter(MigrationPass &pass)
41  : Body(nullptr), Pass(pass) { }
42 
43  void transformBody(Stmt *body, Decl *ParentD) {
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());
57  SourceRange ExprRange = ME->getSourceRange();
58  Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
59  std::string retStr = ")) return ";
60  retStr += getNilString(Pass);
61  Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
62  }
63  return true;
64  }
65 
66 private:
67  bool isRemovable(Expr *E) const {
68  return Removables.count(E);
69  }
70 };
71 
72 } // anonymous namespace
73 
77 }
Defines the clang::ASTContext interface.
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1076
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
This represents one expression.
Definition: Expr.h:110
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:277
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:945
bool isDelegateInitCall() const
isDelegateInitCall - Answers whether this message send has been tagged as a "delegate init call",...
Definition: ExprObjC.h:1413
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition: Stmt.h:84
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
TransformActions & TA
Definition: Internals.h:152
void insertAfterToken(SourceLocation loc, StringRef text)
void insert(SourceLocation loc, StringRef text)
bool clearDiagnostic(ArrayRef< unsigned > IDs, SourceRange range)
bool hasDiagnostic(unsigned ID, SourceRange range)
Definition: Internals.h:89
StringRef getNilString(MigrationPass &Pass)
Returns "nil" or "0" if 'nil' macro is not actually defined.
Definition: Transforms.cpp:208
void rewriteUnusedInitDelegate(MigrationPass &pass)
void collectRemovables(Stmt *S, ExprSet &exprs)
Definition: Transforms.cpp:308
The JSON file list parser is used to communicate input to InstallAPI.