1249423Sdim//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===// 2234287Sdim// 3234287Sdim// The LLVM Compiler Infrastructure 4234287Sdim// 5234287Sdim// This file is distributed under the University of Illinois Open Source 6234287Sdim// License. See LICENSE.TXT for details. 7234287Sdim// 8234287Sdim//===----------------------------------------------------------------------===// 9234287Sdim 10234287Sdim#include "Transforms.h" 11234287Sdim#include "Internals.h" 12239462Sdim#include "clang/AST/ASTContext.h" 13234287Sdim#include "clang/Sema/SemaDiagnostic.h" 14234287Sdim 15234287Sdimusing namespace clang; 16234287Sdimusing namespace arcmt; 17234287Sdimusing namespace trans; 18234287Sdim 19234287Sdimnamespace { 20234287Sdim 21234287Sdimclass GCCollectableCallsChecker : 22234287Sdim public RecursiveASTVisitor<GCCollectableCallsChecker> { 23234287Sdim MigrationContext &MigrateCtx; 24234287Sdim IdentifierInfo *NSMakeCollectableII; 25234287Sdim IdentifierInfo *CFMakeCollectableII; 26234287Sdim 27234287Sdimpublic: 28239462Sdim GCCollectableCallsChecker(MigrationContext &ctx) 29239462Sdim : MigrateCtx(ctx) { 30234287Sdim IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents; 31234287Sdim NSMakeCollectableII = &Ids.get("NSMakeCollectable"); 32234287Sdim CFMakeCollectableII = &Ids.get("CFMakeCollectable"); 33234287Sdim } 34234287Sdim 35234287Sdim bool shouldWalkTypesOfTypeLocs() const { return false; } 36234287Sdim 37234287Sdim bool VisitCallExpr(CallExpr *E) { 38234287Sdim TransformActions &TA = MigrateCtx.Pass.TA; 39234287Sdim 40234287Sdim if (MigrateCtx.isGCOwnedNonObjC(E->getType())) { 41234287Sdim if (MigrateCtx.Pass.noNSAllocReallocError()) 42234287Sdim TA.reportWarning("call returns pointer to GC managed memory; " 43234287Sdim "it will become unmanaged in ARC", 44234287Sdim E->getLocStart(), E->getSourceRange()); 45234287Sdim else 46234287Sdim TA.reportError("call returns pointer to GC managed memory; " 47234287Sdim "it will become unmanaged in ARC", 48234287Sdim E->getLocStart(), E->getSourceRange()); 49234287Sdim return true; 50234287Sdim } 51234287Sdim 52234287Sdim Expr *CEE = E->getCallee()->IgnoreParenImpCasts(); 53234287Sdim if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 54234287Sdim if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) { 55234287Sdim if (!FD->getDeclContext()->getRedeclContext()->isFileContext()) 56234287Sdim return true; 57234287Sdim 58234287Sdim if (FD->getIdentifier() == NSMakeCollectableII) { 59234287Sdim Transaction Trans(TA); 60234287Sdim TA.clearDiagnostic(diag::err_unavailable, 61234287Sdim diag::err_unavailable_message, 62234287Sdim diag::err_ovl_deleted_call, // ObjC++ 63234287Sdim DRE->getSourceRange()); 64234287Sdim TA.replace(DRE->getSourceRange(), "CFBridgingRelease"); 65234287Sdim 66234287Sdim } else if (FD->getIdentifier() == CFMakeCollectableII) { 67234287Sdim TA.reportError("CFMakeCollectable will leak the object that it " 68234287Sdim "receives in ARC", DRE->getLocation(), 69234287Sdim DRE->getSourceRange()); 70234287Sdim } 71234287Sdim } 72234287Sdim } 73234287Sdim 74234287Sdim return true; 75234287Sdim } 76234287Sdim}; 77234287Sdim 78234287Sdim} // anonymous namespace 79234287Sdim 80234287Sdimvoid GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) { 81239462Sdim GCCollectableCallsChecker(BodyCtx.getMigrationContext()) 82234287Sdim .TraverseStmt(BodyCtx.getTopStmt()); 83234287Sdim} 84