blob: 8042c6caba737f9e3ea34423348d67fab6692b48 [file] [log] [blame]
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +00001//===--- TransGCCalls.cpp - Tranformations 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
10#include "Transforms.h"
11#include "Internals.h"
12#include "clang/Sema/SemaDiagnostic.h"
13
14using namespace clang;
15using namespace arcmt;
16using namespace trans;
17
18namespace {
19
20class GCCollectableCallsChecker :
21 public RecursiveASTVisitor<GCCollectableCallsChecker> {
22 MigrationContext &MigrateCtx;
23 ParentMap &PMap;
24 IdentifierInfo *NSMakeCollectableII;
Argyrios Kyrtzidis81eecde2011-11-04 15:58:17 +000025 IdentifierInfo *CFMakeCollectableII;
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000026
27public:
28 GCCollectableCallsChecker(MigrationContext &ctx, ParentMap &map)
29 : MigrateCtx(ctx), PMap(map) {
Argyrios Kyrtzidis81eecde2011-11-04 15:58:17 +000030 IdentifierTable &Ids = MigrateCtx.getPass().Ctx.Idents;
31 NSMakeCollectableII = &Ids.get("NSMakeCollectable");
32 CFMakeCollectableII = &Ids.get("CFMakeCollectable");
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000033 }
34
35 bool VisitCallExpr(CallExpr *E) {
Argyrios Kyrtzidis81eecde2011-11-04 15:58:17 +000036 TransformActions &TA = MigrateCtx.getPass().TA;
37
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000038 Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
39 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
40 if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
Argyrios Kyrtzidis81eecde2011-11-04 15:58:17 +000041 if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
42 return true;
43
44 if (FD->getIdentifier() == NSMakeCollectableII) {
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000045 Transaction Trans(TA);
46 TA.clearDiagnostic(diag::err_unavailable,
47 diag::err_unavailable_message,
Argyrios Kyrtzidis0d579b62011-11-04 15:58:13 +000048 diag::err_ovl_deleted_call, // ObjC++
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000049 DRE->getSourceRange());
50 TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
Argyrios Kyrtzidis81eecde2011-11-04 15:58:17 +000051
52 } else if (FD->getIdentifier() == CFMakeCollectableII) {
53 TA.reportError("CFMakeCollectable will leak the object that it "
54 "receives in ARC", DRE->getLocation(),
55 DRE->getSourceRange());
Argyrios Kyrtzidise0ac7452011-11-04 15:58:08 +000056 }
57 }
58 }
59
60 return true;
61 }
62};
63
64} // anonymous namespace
65
66void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) {
67 GCCollectableCallsChecker(BodyCtx.getMigrationContext(),
68 BodyCtx.getParentMap())
69 .TraverseStmt(BodyCtx.getTopStmt());
70}