2012-11-14 23:08:31 +08:00
|
|
|
//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===//
|
2011-11-04 23:58:08 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Transforms.h"
|
|
|
|
#include "Internals.h"
|
2012-07-05 04:19:54 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2011-11-04 23:58:08 +08:00
|
|
|
#include "clang/Sema/SemaDiagnostic.h"
|
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
using namespace arcmt;
|
|
|
|
using namespace trans;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class GCCollectableCallsChecker :
|
|
|
|
public RecursiveASTVisitor<GCCollectableCallsChecker> {
|
|
|
|
MigrationContext &MigrateCtx;
|
|
|
|
IdentifierInfo *NSMakeCollectableII;
|
2011-11-04 23:58:17 +08:00
|
|
|
IdentifierInfo *CFMakeCollectableII;
|
2011-11-04 23:58:08 +08:00
|
|
|
|
|
|
|
public:
|
2012-06-07 01:32:50 +08:00
|
|
|
GCCollectableCallsChecker(MigrationContext &ctx)
|
|
|
|
: MigrateCtx(ctx) {
|
2011-11-07 02:58:03 +08:00
|
|
|
IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
|
2011-11-04 23:58:17 +08:00
|
|
|
NSMakeCollectableII = &Ids.get("NSMakeCollectable");
|
|
|
|
CFMakeCollectableII = &Ids.get("CFMakeCollectable");
|
2011-11-04 23:58:08 +08:00
|
|
|
}
|
|
|
|
|
2011-11-07 02:58:03 +08:00
|
|
|
bool shouldWalkTypesOfTypeLocs() const { return false; }
|
|
|
|
|
2011-11-04 23:58:08 +08:00
|
|
|
bool VisitCallExpr(CallExpr *E) {
|
2011-11-07 02:58:03 +08:00
|
|
|
TransformActions &TA = MigrateCtx.Pass.TA;
|
2011-11-04 23:58:17 +08:00
|
|
|
|
2011-11-05 07:43:03 +08:00
|
|
|
if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
|
2018-08-10 05:08:08 +08:00
|
|
|
TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc,
|
2014-01-26 13:07:32 +08:00
|
|
|
E->getSourceRange());
|
2011-11-05 07:43:03 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-11-04 23:58:08 +08:00
|
|
|
Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
|
|
|
|
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
|
|
|
|
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
|
2011-11-04 23:58:17 +08:00
|
|
|
if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (FD->getIdentifier() == NSMakeCollectableII) {
|
2011-11-04 23:58:08 +08:00
|
|
|
Transaction Trans(TA);
|
|
|
|
TA.clearDiagnostic(diag::err_unavailable,
|
|
|
|
diag::err_unavailable_message,
|
2011-11-04 23:58:13 +08:00
|
|
|
diag::err_ovl_deleted_call, // ObjC++
|
2011-11-04 23:58:08 +08:00
|
|
|
DRE->getSourceRange());
|
|
|
|
TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
|
2011-11-04 23:58:17 +08:00
|
|
|
|
|
|
|
} else if (FD->getIdentifier() == CFMakeCollectableII) {
|
|
|
|
TA.reportError("CFMakeCollectable will leak the object that it "
|
|
|
|
"receives in ARC", DRE->getLocation(),
|
|
|
|
DRE->getSourceRange());
|
2011-11-04 23:58:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) {
|
2012-06-07 01:32:50 +08:00
|
|
|
GCCollectableCallsChecker(BodyCtx.getMigrationContext())
|
2011-11-04 23:58:08 +08:00
|
|
|
.TraverseStmt(BodyCtx.getTopStmt());
|
|
|
|
}
|