xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/ARCMigrate/TransGCCalls.cpp (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
1*7330f729Sjoerg //===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===//
2*7330f729Sjoerg //
3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*7330f729Sjoerg //
7*7330f729Sjoerg //===----------------------------------------------------------------------===//
8*7330f729Sjoerg 
9*7330f729Sjoerg #include "Transforms.h"
10*7330f729Sjoerg #include "Internals.h"
11*7330f729Sjoerg #include "clang/AST/ASTContext.h"
12*7330f729Sjoerg #include "clang/Sema/SemaDiagnostic.h"
13*7330f729Sjoerg 
14*7330f729Sjoerg using namespace clang;
15*7330f729Sjoerg using namespace arcmt;
16*7330f729Sjoerg using namespace trans;
17*7330f729Sjoerg 
18*7330f729Sjoerg namespace {
19*7330f729Sjoerg 
20*7330f729Sjoerg class GCCollectableCallsChecker :
21*7330f729Sjoerg                          public RecursiveASTVisitor<GCCollectableCallsChecker> {
22*7330f729Sjoerg   MigrationContext &MigrateCtx;
23*7330f729Sjoerg   IdentifierInfo *NSMakeCollectableII;
24*7330f729Sjoerg   IdentifierInfo *CFMakeCollectableII;
25*7330f729Sjoerg 
26*7330f729Sjoerg public:
GCCollectableCallsChecker(MigrationContext & ctx)27*7330f729Sjoerg   GCCollectableCallsChecker(MigrationContext &ctx)
28*7330f729Sjoerg     : MigrateCtx(ctx) {
29*7330f729Sjoerg     IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
30*7330f729Sjoerg     NSMakeCollectableII = &Ids.get("NSMakeCollectable");
31*7330f729Sjoerg     CFMakeCollectableII = &Ids.get("CFMakeCollectable");
32*7330f729Sjoerg   }
33*7330f729Sjoerg 
shouldWalkTypesOfTypeLocs() const34*7330f729Sjoerg   bool shouldWalkTypesOfTypeLocs() const { return false; }
35*7330f729Sjoerg 
VisitCallExpr(CallExpr * E)36*7330f729Sjoerg   bool VisitCallExpr(CallExpr *E) {
37*7330f729Sjoerg     TransformActions &TA = MigrateCtx.Pass.TA;
38*7330f729Sjoerg 
39*7330f729Sjoerg     if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
40*7330f729Sjoerg       TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc,
41*7330f729Sjoerg                 E->getSourceRange());
42*7330f729Sjoerg       return true;
43*7330f729Sjoerg     }
44*7330f729Sjoerg 
45*7330f729Sjoerg     Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
46*7330f729Sjoerg     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
47*7330f729Sjoerg       if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
48*7330f729Sjoerg         if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
49*7330f729Sjoerg           return true;
50*7330f729Sjoerg 
51*7330f729Sjoerg         if (FD->getIdentifier() == NSMakeCollectableII) {
52*7330f729Sjoerg           Transaction Trans(TA);
53*7330f729Sjoerg           TA.clearDiagnostic(diag::err_unavailable,
54*7330f729Sjoerg                              diag::err_unavailable_message,
55*7330f729Sjoerg                              diag::err_ovl_deleted_call, // ObjC++
56*7330f729Sjoerg                              DRE->getSourceRange());
57*7330f729Sjoerg           TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
58*7330f729Sjoerg 
59*7330f729Sjoerg         } else if (FD->getIdentifier() == CFMakeCollectableII) {
60*7330f729Sjoerg           TA.reportError("CFMakeCollectable will leak the object that it "
61*7330f729Sjoerg                          "receives in ARC", DRE->getLocation(),
62*7330f729Sjoerg                          DRE->getSourceRange());
63*7330f729Sjoerg         }
64*7330f729Sjoerg       }
65*7330f729Sjoerg     }
66*7330f729Sjoerg 
67*7330f729Sjoerg     return true;
68*7330f729Sjoerg   }
69*7330f729Sjoerg };
70*7330f729Sjoerg 
71*7330f729Sjoerg } // anonymous namespace
72*7330f729Sjoerg 
traverseBody(BodyContext & BodyCtx)73*7330f729Sjoerg void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) {
74*7330f729Sjoerg   GCCollectableCallsChecker(BodyCtx.getMigrationContext())
75*7330f729Sjoerg                                             .TraverseStmt(BodyCtx.getTopStmt());
76*7330f729Sjoerg }
77