1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- TransGCCalls.cpp - Transformations 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" 12471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 13e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h" 14e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 15e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisusing namespace clang; 16e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisusing namespace arcmt; 17e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisusing namespace trans; 18e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 19e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisnamespace { 20e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 21e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisclass GCCollectableCallsChecker : 22e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis public RecursiveASTVisitor<GCCollectableCallsChecker> { 23e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis MigrationContext &MigrateCtx; 24e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis IdentifierInfo *NSMakeCollectableII; 2581eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis IdentifierInfo *CFMakeCollectableII; 26e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 27e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidispublic: 28facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer GCCollectableCallsChecker(MigrationContext &ctx) 29facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer : MigrateCtx(ctx) { 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())) { 416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TA.report(E->getLocStart(), diag::warn_arcmt_nsalloc_realloc, 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines E->getSourceRange()); 431fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis return true; 441fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis } 451fe4203ca05d0a3283efc8a2e8c01ecdf78fbf2eArgyrios Kyrtzidis 46e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis Expr *CEE = E->getCallee()->IgnoreParenImpCasts(); 47e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 48e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) { 4981eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis if (!FD->getDeclContext()->getRedeclContext()->isFileContext()) 5081eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis return true; 5181eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis 5281eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis if (FD->getIdentifier() == NSMakeCollectableII) { 53e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis Transaction Trans(TA); 54e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis TA.clearDiagnostic(diag::err_unavailable, 55e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis diag::err_unavailable_message, 560d579b6a3f555c0e37e84e517c81eb9244fef099Argyrios Kyrtzidis diag::err_ovl_deleted_call, // ObjC++ 57e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis DRE->getSourceRange()); 58e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis TA.replace(DRE->getSourceRange(), "CFBridgingRelease"); 5981eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis 6081eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis } else if (FD->getIdentifier() == CFMakeCollectableII) { 6181eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis TA.reportError("CFMakeCollectable will leak the object that it " 6281eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis "receives in ARC", DRE->getLocation(), 6381eecde879712729712966b60c0cb1540b41293bArgyrios Kyrtzidis DRE->getSourceRange()); 64e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 65e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 66e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 67e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 68e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis return true; 69e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis } 70e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis}; 71e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 72e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} // anonymous namespace 73e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis 74e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidisvoid GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) { 75facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer GCCollectableCallsChecker(BodyCtx.getMigrationContext()) 76e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis .TraverseStmt(BodyCtx.getTopStmt()); 77e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis} 78