llvm-project
76 строк · 2.5 Кб
1//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Transforms.h"10#include "Internals.h"11#include "clang/AST/ASTContext.h"12#include "clang/Sema/SemaDiagnostic.h"13
14using namespace clang;15using namespace arcmt;16using namespace trans;17
18namespace {19
20class GCCollectableCallsChecker :21public RecursiveASTVisitor<GCCollectableCallsChecker> {22MigrationContext &MigrateCtx;23IdentifierInfo *NSMakeCollectableII;24IdentifierInfo *CFMakeCollectableII;25
26public:27GCCollectableCallsChecker(MigrationContext &ctx)28: MigrateCtx(ctx) {29IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;30NSMakeCollectableII = &Ids.get("NSMakeCollectable");31CFMakeCollectableII = &Ids.get("CFMakeCollectable");32}33
34bool shouldWalkTypesOfTypeLocs() const { return false; }35
36bool VisitCallExpr(CallExpr *E) {37TransformActions &TA = MigrateCtx.Pass.TA;38
39if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {40TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc,41E->getSourceRange());42return true;43}44
45Expr *CEE = E->getCallee()->IgnoreParenImpCasts();46if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {47if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {48if (!FD->getDeclContext()->getRedeclContext()->isFileContext())49return true;50
51if (FD->getIdentifier() == NSMakeCollectableII) {52Transaction Trans(TA);53TA.clearDiagnostic(diag::err_unavailable,54diag::err_unavailable_message,55diag::err_ovl_deleted_call, // ObjC++56DRE->getSourceRange());57TA.replace(DRE->getSourceRange(), "CFBridgingRelease");58
59} else if (FD->getIdentifier() == CFMakeCollectableII) {60TA.reportError("CFMakeCollectable will leak the object that it "61"receives in ARC", DRE->getLocation(),62DRE->getSourceRange());63}64}65}66
67return true;68}69};70
71} // anonymous namespace72
73void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) {74GCCollectableCallsChecker(BodyCtx.getMigrationContext())75.TraverseStmt(BodyCtx.getTopStmt());76}
77