Path: blob/main/contrib/llvm-project/clang/lib/ARCMigrate/TransARCAssign.cpp
35236 views
//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// makeAssignARCSafe:9//10// Add '__strong' where appropriate.11//12// for (id x in collection) {13// x = 0;14// }15// ---->16// for (__strong id x in collection) {17// x = 0;18// }19//20//===----------------------------------------------------------------------===//2122#include "Transforms.h"23#include "Internals.h"24#include "clang/AST/ASTContext.h"25#include "clang/Sema/SemaDiagnostic.h"2627using namespace clang;28using namespace arcmt;29using namespace trans;3031namespace {3233class ARCAssignChecker : public RecursiveASTVisitor<ARCAssignChecker> {34MigrationPass &Pass;35llvm::DenseSet<VarDecl *> ModifiedVars;3637public:38ARCAssignChecker(MigrationPass &pass) : Pass(pass) { }3940bool VisitBinaryOperator(BinaryOperator *Exp) {41if (Exp->getType()->isDependentType())42return true;4344Expr *E = Exp->getLHS();45SourceLocation OrigLoc = E->getExprLoc();46SourceLocation Loc = OrigLoc;47DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());48if (declRef && isa<VarDecl>(declRef->getDecl())) {49ASTContext &Ctx = Pass.Ctx;50Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(Ctx, &Loc);51if (IsLV != Expr::MLV_ConstQualified)52return true;53VarDecl *var = cast<VarDecl>(declRef->getDecl());54if (var->isARCPseudoStrong()) {55Transaction Trans(Pass.TA);56if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration,57Exp->getOperatorLoc())) {58if (!ModifiedVars.count(var)) {59TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc();60Pass.TA.insert(TLoc.getBeginLoc(), "__strong ");61ModifiedVars.insert(var);62}63}64}65}6667return true;68}69};7071} // anonymous namespace7273void trans::makeAssignARCSafe(MigrationPass &pass) {74ARCAssignChecker assignCheck(pass);75assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl());76}777879