This starts to switch ARCMT to use proper diagnostic messages. The old use was based on incorrect example code from the documentation. The logic of the previous report() functions has been retained to support any external consumers that might be intercepting diagnostic messages through the old interface. Note that the change in test/Misc/warning-flags.c isn't a new warning without a flag, rather one that was previously invisible to the test. Adding a flag might be a good idea though. llvm-svn: 200124
78 lines
2.5 KiB
C++
78 lines
2.5 KiB
C++
//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===//
|
|
//
|
|
// 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"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/Sema/SemaDiagnostic.h"
|
|
|
|
using namespace clang;
|
|
using namespace arcmt;
|
|
using namespace trans;
|
|
|
|
namespace {
|
|
|
|
class GCCollectableCallsChecker :
|
|
public RecursiveASTVisitor<GCCollectableCallsChecker> {
|
|
MigrationContext &MigrateCtx;
|
|
IdentifierInfo *NSMakeCollectableII;
|
|
IdentifierInfo *CFMakeCollectableII;
|
|
|
|
public:
|
|
GCCollectableCallsChecker(MigrationContext &ctx)
|
|
: MigrateCtx(ctx) {
|
|
IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
|
|
NSMakeCollectableII = &Ids.get("NSMakeCollectable");
|
|
CFMakeCollectableII = &Ids.get("CFMakeCollectable");
|
|
}
|
|
|
|
bool shouldWalkTypesOfTypeLocs() const { return false; }
|
|
|
|
bool VisitCallExpr(CallExpr *E) {
|
|
TransformActions &TA = MigrateCtx.Pass.TA;
|
|
|
|
if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
|
|
TA.report(E->getLocStart(), diag::err_arcmt_nsalloc_realloc,
|
|
E->getSourceRange());
|
|
return true;
|
|
}
|
|
|
|
Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
|
|
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
|
|
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
|
|
if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
|
|
return true;
|
|
|
|
if (FD->getIdentifier() == NSMakeCollectableII) {
|
|
Transaction Trans(TA);
|
|
TA.clearDiagnostic(diag::err_unavailable,
|
|
diag::err_unavailable_message,
|
|
diag::err_ovl_deleted_call, // ObjC++
|
|
DRE->getSourceRange());
|
|
TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
|
|
|
|
} else if (FD->getIdentifier() == CFMakeCollectableII) {
|
|
TA.reportError("CFMakeCollectable will leak the object that it "
|
|
"receives in ARC", DRE->getLocation(),
|
|
DRE->getSourceRange());
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) {
|
|
GCCollectableCallsChecker(BodyCtx.getMigrationContext())
|
|
.TraverseStmt(BodyCtx.getTopStmt());
|
|
}
|