clang  19.0.0git
TransGCCalls.cpp
Go to the documentation of this file.
1 //===--- TransGCCalls.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 
9 #include "Transforms.h"
10 #include "Internals.h"
11 #include "clang/AST/ASTContext.h"
13 
14 using namespace clang;
15 using namespace arcmt;
16 using namespace trans;
17 
18 namespace {
19 
20 class GCCollectableCallsChecker :
21  public RecursiveASTVisitor<GCCollectableCallsChecker> {
22  MigrationContext &MigrateCtx;
23  IdentifierInfo *NSMakeCollectableII;
24  IdentifierInfo *CFMakeCollectableII;
25 
26 public:
27  GCCollectableCallsChecker(MigrationContext &ctx)
28  : MigrateCtx(ctx) {
29  IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
30  NSMakeCollectableII = &Ids.get("NSMakeCollectable");
31  CFMakeCollectableII = &Ids.get("CFMakeCollectable");
32  }
33 
34  bool shouldWalkTypesOfTypeLocs() const { return false; }
35 
36  bool VisitCallExpr(CallExpr *E) {
37  TransformActions &TA = MigrateCtx.Pass.TA;
38 
39  if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
40  TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc,
41  E->getSourceRange());
42  return true;
43  }
44 
45  Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
46  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
47  if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
48  if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
49  return true;
50 
51  if (FD->getIdentifier() == NSMakeCollectableII) {
52  Transaction Trans(TA);
53  TA.clearDiagnostic(diag::err_unavailable,
54  diag::err_unavailable_message,
55  diag::err_ovl_deleted_call, // ObjC++
56  DRE->getSourceRange());
57  TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
58 
59  } else if (FD->getIdentifier() == CFMakeCollectableII) {
60  TA.reportError("CFMakeCollectable will leak the object that it "
61  "receives in ARC", DRE->getLocation(),
62  DRE->getSourceRange());
63  }
64  }
65  }
66 
67  return true;
68  }
69 };
70 
71 } // anonymous namespace
72 
74  GCCollectableCallsChecker(BodyCtx.getMigrationContext())
75  .TraverseStmt(BodyCtx.getTopStmt());
76 }
Defines the clang::ASTContext interface.
IdentifierTable & Idents
Definition: ASTContext.h:647
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2872
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:1693
Expr * getCallee()
Definition: Expr.h:3022
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
This represents one expression.
Definition: Expr.h:110
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3111
QualType getType() const
Definition: Expr.h:142
Represents a function declaration or definition.
Definition: Decl.h:1972
One of these records is kept for each identifier that is lexed.
Implements an efficient mapping from strings to IdentifierInfo nodes.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
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
DiagnosticBuilder report(SourceLocation loc, unsigned diagId, SourceRange range=SourceRange())
bool clearDiagnostic(ArrayRef< unsigned > IDs, SourceRange range)
void reportError(StringRef error, SourceLocation loc, SourceRange range=SourceRange())
void replace(SourceRange range, StringRef text)
MigrationContext & getMigrationContext()
Definition: Transforms.h:54
void traverseBody(BodyContext &BodyCtx) override
The JSON file list parser is used to communicate input to InstallAPI.