1e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===--- TransGCCalls.cpp - Tranformations to ARC mode --------------------===// 2e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// 3e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// The LLVM Compiler Infrastructure 4e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// 5e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 6e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// License. See LICENSE.TXT for details. 7e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis// 8e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 9e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 10e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis#include "Transforms.h" 11e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis#include "Internals.h" 12e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h" 13e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 14e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisusing namespace clang; 15e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisusing namespace arcmt; 16e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisusing namespace trans; 17e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 18e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisnamespace { 19e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 20e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass GCCollectableCallsChecker : 21e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis public RecursiveASTVisitor<GCCollectableCallsChecker> { 22e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext &MigrateCtx; 23e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis ParentMap &PMap; 24e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis IdentifierInfo *NSMakeCollectableII; 2581eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis IdentifierInfo *CFMakeCollectableII; 26e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 27e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic: 28e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis GCCollectableCallsChecker(MigrationContext &ctx, ParentMap &map) 29e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis : MigrateCtx(ctx), PMap(map) { 30f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents; 3181eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis NSMakeCollectableII = &Ids.get("NSMakeCollectable"); 3281eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis CFMakeCollectableII = &Ids.get("CFMakeCollectable"); 33e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 34e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 35f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; } 36f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis 37e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis bool VisitCallExpr(CallExpr *E) { 38f38fa73e605587abfa32ab6a39887cdebc0a320aArgyrios Kyrtzidis TransformActions &TA = MigrateCtx.Pass.TA; 3981eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis 401fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis if (MigrateCtx.isGCOwnedNonObjC(E->getType())) { 41b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian if (MigrateCtx.Pass.noNSAllocReallocError()) 42b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian TA.reportWarning("call returns pointer to GC managed memory; " 43b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian "it will become unmanaged in ARC", 44b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian E->getLocStart(), E->getSourceRange()); 45b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian else 46b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian TA.reportError("call returns pointer to GC managed memory; " 47b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian "it will become unmanaged in ARC", 48b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian E->getLocStart(), E->getSourceRange()); 491fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return true; 501fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 511fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 52e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis Expr *CEE = E->getCallee()->IgnoreParenImpCasts(); 53e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 54e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) { 5581eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis if (!FD->getDeclContext()->getRedeclContext()->isFileContext()) 5681eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis return true; 5781eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis 5881eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis if (FD->getIdentifier() == NSMakeCollectableII) { 59e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis Transaction Trans(TA); 60e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis TA.clearDiagnostic(diag::err_unavailable, 61e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis diag::err_unavailable_message, 620d579b6a3f555c0e37e84e517c81eb9244fef099Argyrios Kyrtzidis diag::err_ovl_deleted_call, // ObjC++ 63e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis DRE->getSourceRange()); 64e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis TA.replace(DRE->getSourceRange(), "CFBridgingRelease"); 6581eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis 6681eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis } else if (FD->getIdentifier() == CFMakeCollectableII) { 6781eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis TA.reportError("CFMakeCollectable will leak the object that it " 6881eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis "receives in ARC", DRE->getLocation(), 6981eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis DRE->getSourceRange()); 70e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 71e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 72e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 73e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 74e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 75e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 76e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis}; 77e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 78e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} // anonymous namespace 79e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 80e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisvoid GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) { 81e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis GCCollectableCallsChecker(BodyCtx.getMigrationContext(), 82e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis BodyCtx.getParentMap()) 83e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis .TraverseStmt(BodyCtx.getTopStmt()); 84e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 85