clang  14.0.0git
TransARCAssign.cpp
Go to the documentation of this file.
1 //===--- TransARCAssign.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 // makeAssignARCSafe:
10 //
11 // Add '__strong' where appropriate.
12 //
13 // for (id x in collection) {
14 // x = 0;
15 // }
16 // ---->
17 // for (__strong id x in collection) {
18 // x = 0;
19 // }
20 //
21 //===----------------------------------------------------------------------===//
22 
23 #include "Transforms.h"
24 #include "Internals.h"
25 #include "clang/AST/ASTContext.h"
27 
28 using namespace clang;
29 using namespace arcmt;
30 using namespace trans;
31 
32 namespace {
33 
34 class ARCAssignChecker : public RecursiveASTVisitor<ARCAssignChecker> {
35  MigrationPass &Pass;
36  llvm::DenseSet<VarDecl *> ModifiedVars;
37 
38 public:
39  ARCAssignChecker(MigrationPass &pass) : Pass(pass) { }
40 
41  bool VisitBinaryOperator(BinaryOperator *Exp) {
42  if (Exp->getType()->isDependentType())
43  return true;
44 
45  Expr *E = Exp->getLHS();
46  SourceLocation OrigLoc = E->getExprLoc();
47  SourceLocation Loc = OrigLoc;
48  DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
49  if (declRef && isa<VarDecl>(declRef->getDecl())) {
50  ASTContext &Ctx = Pass.Ctx;
52  if (IsLV != Expr::MLV_ConstQualified)
53  return true;
54  VarDecl *var = cast<VarDecl>(declRef->getDecl());
55  if (var->isARCPseudoStrong()) {
56  Transaction Trans(Pass.TA);
57  if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration,
58  Exp->getOperatorLoc())) {
59  if (!ModifiedVars.count(var)) {
60  TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc();
61  Pass.TA.insert(TLoc.getBeginLoc(), "__strong ");
62  ModifiedVars.insert(var);
63  }
64  }
65  }
66  }
67 
68  return true;
69  }
70 };
71 
72 } // anonymous namespace
73 
75  ARCAssignChecker assignCheck(pass);
76  assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
77 }
clang::arcmt::MigrationPass
Definition: Internals.h:146
Transforms.h
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::Expr::MLV_ConstQualified
@ MLV_ConstQualified
Definition: Expr.h:298
clang::Expr::isModifiableLvalue
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, does not have an incomplet...
Definition: ExprClassification.cpp:697
clang::arcmt::trans::makeAssignARCSafe
void makeAssignARCSafe(MigrationPass &pass)
Definition: TransARCAssign.cpp:74
Internals.h
clang::arcmt::MigrationPass::TA
TransformActions & TA
Definition: Internals.h:152
clang::ASTContext::getTranslationUnitDecl
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1057
clang::TypeLoc::getBeginLoc
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:191
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3803
clang::arcmt::Transaction
Definition: Internals.h:124
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::RecursiveASTVisitor
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Definition: RecursiveASTVisitor.h:164
clang::arcmt::TransformActions::insert
void insert(SourceLocation loc, StringRef text)
Definition: TransformActions.cpp:629
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1289
ASTContext.h
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:876
llvm::DenseSet
Definition: Sema.h:77
clang::arcmt::MigrationPass::Ctx
ASTContext & Ctx
Definition: Internals.h:148
clang::Expr::IgnoreParenCasts
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2921
clang::Type::isDependentType
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2174
SemaDiagnostic.h
clang::BinaryOperator::getLHS
Expr * getLHS() const
Definition: Expr.h:3852
clang::Expr::getExprLoc
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:229
clang::TypeLoc
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
clang::BinaryOperator::getOperatorLoc
SourceLocation getOperatorLoc() const
Definition: Expr.h:3844
clang::VarDecl::isARCPseudoStrong
bool isARCPseudoStrong() const
Determine whether this variable is an ARC pseudo-__strong variable.
Definition: Decl.h:1457
clang
Definition: CalledOnceCheck.h:17
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::arcmt::TransformActions::clearDiagnostic
bool clearDiagnostic(ArrayRef< unsigned > IDs, SourceRange range)
Definition: TransformActions.cpp:671
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::Expr::isModifiableLvalueResult
isModifiableLvalueResult
Definition: Expr.h:290
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1217
clang::DeclaratorDecl::getTypeSourceInfo
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:757
clang::TypeSourceInfo::getTypeLoc
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:244