1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===// 27196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 37196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 47196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 57196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 67196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 77196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 87196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 97196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// makeAssignARCSafe: 117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Add '__strong' where appropriate. 137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// for (id x in collection) { 157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// x = 0; 167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// } 177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// ----> 187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// for (__strong id x in collection) { 197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// x = 0; 207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// } 217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Transforms.h" 257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Internals.h" 26471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h" 287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace clang; 307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace arcmt; 317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace { 347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass ARCAssignChecker : public RecursiveASTVisitor<ARCAssignChecker> { 367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis MigrationPass &Pass; 377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis llvm::DenseSet<VarDecl *> ModifiedVars; 387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ARCAssignChecker(MigrationPass &pass) : Pass(pass) { } 417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitBinaryOperator(BinaryOperator *Exp) { 43fcf28b2b5253546732949a5b77062fed9b9d731dArgyrios Kyrtzidis if (Exp->getType()->isDependentType()) 44fcf28b2b5253546732949a5b77062fed9b9d731dArgyrios Kyrtzidis return true; 45fcf28b2b5253546732949a5b77062fed9b9d731dArgyrios Kyrtzidis 467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *E = Exp->getLHS(); 477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation OrigLoc = E->getExprLoc(); 487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation Loc = OrigLoc; 497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()); 507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (declRef && isa<VarDecl>(declRef->getDecl())) { 517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ASTContext &Ctx = Pass.Ctx; 527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(Ctx, &Loc); 537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (IsLV != Expr::MLV_ConstQualified) 547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis VarDecl *var = cast<VarDecl>(declRef->getDecl()); 567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (var->isARCPseudoStrong()) { 577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Transaction Trans(Pass.TA); 587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration, 597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Exp->getOperatorLoc())) { 607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!ModifiedVars.count(var)) { 617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc(); 627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Pass.TA.insert(TLoc.getBeginLoc(), "__strong "); 637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ModifiedVars.insert(var); 647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisvoid trans::makeAssignARCSafe(MigrationPass &pass) { 767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ARCAssignChecker assignCheck(pass); 777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 79