clang-tools  3.9.0
LoopConvertUtils.cpp
Go to the documentation of this file.
1 //===--- LoopConvertUtils.cpp - clang-tidy --------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "LoopConvertUtils.h"
11 
12 using namespace clang::ast_matchers;
13 using namespace clang::tooling;
14 using namespace clang;
15 using namespace llvm;
16 
17 namespace clang {
18 namespace tidy {
19 namespace modernize {
20 
21 /// \brief Tracks a stack of parent statements during traversal.
22 ///
23 /// All this really does is inject push_back() before running
24 /// RecursiveASTVisitor::TraverseStmt() and pop_back() afterwards. The Stmt atop
25 /// the stack is the parent of the current statement (NULL for the topmost
26 /// statement).
27 bool StmtAncestorASTVisitor::TraverseStmt(Stmt *Statement) {
28  StmtAncestors.insert(std::make_pair(Statement, StmtStack.back()));
29  StmtStack.push_back(Statement);
30  RecursiveASTVisitor<StmtAncestorASTVisitor>::TraverseStmt(Statement);
31  StmtStack.pop_back();
32  return true;
33 }
34 
35 /// \brief Keep track of the DeclStmt associated with each VarDecl.
36 ///
37 /// Combined with StmtAncestors, this provides roughly the same information as
38 /// Scope, as we can map a VarDecl to its DeclStmt, then walk up the parent tree
39 /// using StmtAncestors.
40 bool StmtAncestorASTVisitor::VisitDeclStmt(DeclStmt *Decls) {
41  for (const auto *decl : Decls->decls()) {
42  if (const auto *V = dyn_cast<VarDecl>(decl))
43  DeclParents.insert(std::make_pair(V, Decls));
44  }
45  return true;
46 }
47 
48 /// \brief record the DeclRefExpr as part of the parent expression.
49 bool ComponentFinderASTVisitor::VisitDeclRefExpr(DeclRefExpr *E) {
50  Components.push_back(E);
51  return true;
52 }
53 
54 /// \brief record the MemberExpr as part of the parent expression.
55 bool ComponentFinderASTVisitor::VisitMemberExpr(MemberExpr *Member) {
56  Components.push_back(Member);
57  return true;
58 }
59 
60 /// \brief Forward any DeclRefExprs to a check on the referenced variable
61 /// declaration.
62 bool DependencyFinderASTVisitor::VisitDeclRefExpr(DeclRefExpr *DeclRef) {
63  if (auto *V = dyn_cast_or_null<VarDecl>(DeclRef->getDecl()))
64  return VisitVarDecl(V);
65  return true;
66 }
67 
68 /// \brief Determine if any this variable is declared inside the ContainingStmt.
69 bool DependencyFinderASTVisitor::VisitVarDecl(VarDecl *V) {
70  const Stmt *Curr = DeclParents->lookup(V);
71  // First, see if the variable was declared within an inner scope of the loop.
72  while (Curr != nullptr) {
73  if (Curr == ContainingStmt) {
74  DependsOnInsideVariable = true;
75  return false;
76  }
77  Curr = StmtParents->lookup(Curr);
78  }
79 
80  // Next, check if the variable was removed from existence by an earlier
81  // iteration.
82  for (const auto &I : *ReplacedVars) {
83  if (I.second == V) {
84  DependsOnInsideVariable = true;
85  return false;
86  }
87  }
88  return true;
89 }
90 
91 /// \brief If we already created a variable for TheLoop, check to make sure
92 /// that the name was not already taken.
93 bool DeclFinderASTVisitor::VisitForStmt(ForStmt *TheLoop) {
94  StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(TheLoop);
95  if (I != GeneratedDecls->end() && I->second == Name) {
96  Found = true;
97  return false;
98  }
99  return true;
100 }
101 
102 /// \brief If any named declaration within the AST subtree has the same name,
103 /// then consider Name already taken.
104 bool DeclFinderASTVisitor::VisitNamedDecl(NamedDecl *D) {
105  const IdentifierInfo *Ident = D->getIdentifier();
106  if (Ident && Ident->getName() == Name) {
107  Found = true;
108  return false;
109  }
110  return true;
111 }
112 
113 /// \brief Forward any declaration references to the actual check on the
114 /// referenced declaration.
115 bool DeclFinderASTVisitor::VisitDeclRefExpr(DeclRefExpr *DeclRef) {
116  if (auto *D = dyn_cast<NamedDecl>(DeclRef->getDecl()))
117  return VisitNamedDecl(D);
118  return true;
119 }
120 
121 /// \brief If the new variable name conflicts with any type used in the loop,
122 /// then we mark that variable name as taken.
123 bool DeclFinderASTVisitor::VisitTypeLoc(TypeLoc TL) {
124  QualType QType = TL.getType();
125 
126  // Check if our name conflicts with a type, to handle for typedefs.
127  if (QType.getAsString() == Name) {
128  Found = true;
129  return false;
130  }
131  // Check for base type conflicts. For example, when a struct is being
132  // referenced in the body of the loop, the above getAsString() will return the
133  // whole type (ex. "struct s"), but will be caught here.
134  if (const IdentifierInfo *Ident = QType.getBaseTypeIdentifier()) {
135  if (Ident->getName() == Name) {
136  Found = true;
137  return false;
138  }
139  }
140  return true;
141 }
142 
143 /// \brief Look through conversion/copy constructors to find the explicit
144 /// initialization expression, returning it is found.
145 ///
146 /// The main idea is that given
147 /// vector<int> v;
148 /// we consider either of these initializations
149 /// vector<int>::iterator it = v.begin();
150 /// vector<int>::iterator it(v.begin());
151 /// and retrieve `v.begin()` as the expression used to initialize `it` but do
152 /// not include
153 /// vector<int>::iterator it;
154 /// vector<int>::iterator it(v.begin(), 0); // if this constructor existed
155 /// as being initialized from `v.begin()`
156 const Expr *digThroughConstructors(const Expr *E) {
157  if (!E)
158  return nullptr;
159  E = E->IgnoreImplicit();
160  if (const auto *ConstructExpr = dyn_cast<CXXConstructExpr>(E)) {
161  // The initial constructor must take exactly one parameter, but base class
162  // and deferred constructors can take more.
163  if (ConstructExpr->getNumArgs() != 1 ||
164  ConstructExpr->getConstructionKind() != CXXConstructExpr::CK_Complete)
165  return nullptr;
166  E = ConstructExpr->getArg(0);
167  if (const auto *Temp = dyn_cast<MaterializeTemporaryExpr>(E))
168  E = Temp->GetTemporaryExpr();
169  return digThroughConstructors(E);
170  }
171  return E;
172 }
173 
174 /// \brief Returns true when two Exprs are equivalent.
175 bool areSameExpr(ASTContext *Context, const Expr *First, const Expr *Second) {
176  if (!First || !Second)
177  return false;
178 
179  llvm::FoldingSetNodeID FirstID, SecondID;
180  First->Profile(FirstID, *Context, true);
181  Second->Profile(SecondID, *Context, true);
182  return FirstID == SecondID;
183 }
184 
185 /// \brief Returns the DeclRefExpr represented by E, or NULL if there isn't one.
186 const DeclRefExpr *getDeclRef(const Expr *E) {
187  return dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
188 }
189 
190 /// \brief Returns true when two ValueDecls are the same variable.
191 bool areSameVariable(const ValueDecl *First, const ValueDecl *Second) {
192  return First && Second &&
193  First->getCanonicalDecl() == Second->getCanonicalDecl();
194 }
195 
196 /// \brief Determines if an expression is a declaration reference to a
197 /// particular variable.
198 static bool exprReferencesVariable(const ValueDecl *Target, const Expr *E) {
199  if (!Target || !E)
200  return false;
201  const DeclRefExpr *Decl = getDeclRef(E);
202  return Decl && areSameVariable(Target, Decl->getDecl());
203 }
204 
205 /// \brief If the expression is a dereference or call to operator*(), return the
206 /// operand. Otherwise, return NULL.
207 static const Expr *getDereferenceOperand(const Expr *E) {
208  if (const auto *Uop = dyn_cast<UnaryOperator>(E))
209  return Uop->getOpcode() == UO_Deref ? Uop->getSubExpr() : nullptr;
210 
211  if (const auto *OpCall = dyn_cast<CXXOperatorCallExpr>(E)) {
212  return OpCall->getOperator() == OO_Star && OpCall->getNumArgs() == 1
213  ? OpCall->getArg(0)
214  : nullptr;
215  }
216 
217  return nullptr;
218 }
219 
220 /// \brief Returns true when the Container contains an Expr equivalent to E.
221 template <typename ContainerT>
222 static bool containsExpr(ASTContext *Context, const ContainerT *Container,
223  const Expr *E) {
224  llvm::FoldingSetNodeID ID;
225  E->Profile(ID, *Context, true);
226  for (const auto &I : *Container) {
227  if (ID == I.second)
228  return true;
229  }
230  return false;
231 }
232 
233 /// \brief Returns true when the index expression is a declaration reference to
234 /// IndexVar.
235 ///
236 /// If the index variable is `index`, this function returns true on
237 /// arrayExpression[index];
238 /// containerExpression[index];
239 /// but not
240 /// containerExpression[notIndex];
241 static bool isIndexInSubscriptExpr(const Expr *IndexExpr,
242  const VarDecl *IndexVar) {
243  const DeclRefExpr *Idx = getDeclRef(IndexExpr);
244  return Idx && Idx->getType()->isIntegerType() &&
245  areSameVariable(IndexVar, Idx->getDecl());
246 }
247 
248 /// \brief Returns true when the index expression is a declaration reference to
249 /// IndexVar, Obj is the same expression as SourceExpr after all parens and
250 /// implicit casts are stripped off.
251 ///
252 /// If PermitDeref is true, IndexExpression may
253 /// be a dereference (overloaded or builtin operator*).
254 ///
255 /// This function is intended for array-like containers, as it makes sure that
256 /// both the container and the index match.
257 /// If the loop has index variable `index` and iterates over `container`, then
258 /// isIndexInSubscriptExpr returns true for
259 /// \code
260 /// container[index]
261 /// container.at(index)
262 /// container->at(index)
263 /// \endcode
264 /// but not for
265 /// \code
266 /// container[notIndex]
267 /// notContainer[index]
268 /// \endcode
269 /// If PermitDeref is true, then isIndexInSubscriptExpr additionally returns
270 /// true on these expressions:
271 /// \code
272 /// (*container)[index]
273 /// (*container).at(index)
274 /// \endcode
275 static bool isIndexInSubscriptExpr(ASTContext *Context, const Expr *IndexExpr,
276  const VarDecl *IndexVar, const Expr *Obj,
277  const Expr *SourceExpr, bool PermitDeref) {
278  if (!SourceExpr || !Obj || !isIndexInSubscriptExpr(IndexExpr, IndexVar))
279  return false;
280 
281  if (areSameExpr(Context, SourceExpr->IgnoreParenImpCasts(),
282  Obj->IgnoreParenImpCasts()))
283  return true;
284 
285  if (const Expr *InnerObj = getDereferenceOperand(Obj->IgnoreParenImpCasts()))
286  if (PermitDeref && areSameExpr(Context, SourceExpr->IgnoreParenImpCasts(),
287  InnerObj->IgnoreParenImpCasts()))
288  return true;
289 
290  return false;
291 }
292 
293 /// \brief Returns true when Opcall is a call a one-parameter dereference of
294 /// IndexVar.
295 ///
296 /// For example, if the index variable is `index`, returns true for
297 /// *index
298 /// but not
299 /// index
300 /// *notIndex
301 static bool isDereferenceOfOpCall(const CXXOperatorCallExpr *OpCall,
302  const VarDecl *IndexVar) {
303  return OpCall->getOperator() == OO_Star && OpCall->getNumArgs() == 1 &&
304  exprReferencesVariable(IndexVar, OpCall->getArg(0));
305 }
306 
307 /// \brief Returns true when Uop is a dereference of IndexVar.
308 ///
309 /// For example, if the index variable is `index`, returns true for
310 /// *index
311 /// but not
312 /// index
313 /// *notIndex
314 static bool isDereferenceOfUop(const UnaryOperator *Uop,
315  const VarDecl *IndexVar) {
316  return Uop->getOpcode() == UO_Deref &&
317  exprReferencesVariable(IndexVar, Uop->getSubExpr());
318 }
319 
320 /// \brief Determines whether the given Decl defines a variable initialized to
321 /// the loop object.
322 ///
323 /// This is intended to find cases such as
324 /// \code
325 /// for (int i = 0; i < arraySize(arr); ++i) {
326 /// T t = arr[i];
327 /// // use t, do not use i
328 /// }
329 /// \endcode
330 /// and
331 /// \code
332 /// for (iterator i = container.begin(), e = container.end(); i != e; ++i) {
333 /// T t = *i;
334 /// // use t, do not use i
335 /// }
336 /// \endcode
337 static bool isAliasDecl(ASTContext *Context, const Decl *TheDecl,
338  const VarDecl *IndexVar) {
339  const auto *VDecl = dyn_cast<VarDecl>(TheDecl);
340  if (!VDecl)
341  return false;
342  if (!VDecl->hasInit())
343  return false;
344 
345  bool OnlyCasts = true;
346  const Expr *Init = VDecl->getInit()->IgnoreParenImpCasts();
347  if (Init && isa<CXXConstructExpr>(Init)) {
348  Init = digThroughConstructors(Init);
349  OnlyCasts = false;
350  }
351  if (!Init)
352  return false;
353 
354  // Check that the declared type is the same as (or a reference to) the
355  // container type.
356  if (!OnlyCasts) {
357  QualType InitType = Init->getType();
358  QualType DeclarationType = VDecl->getType();
359  if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
360  DeclarationType = DeclarationType.getNonReferenceType();
361 
362  if (InitType.isNull() || DeclarationType.isNull() ||
363  !Context->hasSameUnqualifiedType(DeclarationType, InitType))
364  return false;
365  }
366 
367  switch (Init->getStmtClass()) {
368  case Stmt::ArraySubscriptExprClass: {
369  const auto *E = cast<ArraySubscriptExpr>(Init);
370  // We don't really care which array is used here. We check to make sure
371  // it was the correct one later, since the AST will traverse it next.
372  return isIndexInSubscriptExpr(E->getIdx(), IndexVar);
373  }
374 
375  case Stmt::UnaryOperatorClass:
376  return isDereferenceOfUop(cast<UnaryOperator>(Init), IndexVar);
377 
378  case Stmt::CXXOperatorCallExprClass: {
379  const auto *OpCall = cast<CXXOperatorCallExpr>(Init);
380  if (OpCall->getOperator() == OO_Star)
381  return isDereferenceOfOpCall(OpCall, IndexVar);
382  if (OpCall->getOperator() == OO_Subscript) {
383  assert(OpCall->getNumArgs() == 2);
384  return isIndexInSubscriptExpr(OpCall->getArg(1), IndexVar);
385  }
386  break;
387  }
388 
389  case Stmt::CXXMemberCallExprClass: {
390  const auto *MemCall = cast<CXXMemberCallExpr>(Init);
391  // This check is needed because getMethodDecl can return nullptr if the
392  // callee is a member function pointer.
393  const auto *MDecl = MemCall->getMethodDecl();
394  if (MDecl && !isa<CXXConversionDecl>(MDecl) &&
395  MDecl->getNameAsString() == "at" && MemCall->getNumArgs() == 1) {
396  return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar);
397  }
398  return false;
399  }
400 
401  default:
402  break;
403  }
404  return false;
405 }
406 
407 /// \brief Determines whether the bound of a for loop condition expression is
408 /// the same as the statically computable size of ArrayType.
409 ///
410 /// Given
411 /// \code
412 /// const int N = 5;
413 /// int arr[N];
414 /// \endcode
415 /// This is intended to permit
416 /// \code
417 /// for (int i = 0; i < N; ++i) { /* use arr[i] */ }
418 /// for (int i = 0; i < arraysize(arr); ++i) { /* use arr[i] */ }
419 /// \endcode
420 static bool arrayMatchesBoundExpr(ASTContext *Context,
421  const QualType &ArrayType,
422  const Expr *ConditionExpr) {
423  if (!ConditionExpr || ConditionExpr->isValueDependent())
424  return false;
425  const ConstantArrayType *ConstType =
426  Context->getAsConstantArrayType(ArrayType);
427  if (!ConstType)
428  return false;
429  llvm::APSInt ConditionSize;
430  if (!ConditionExpr->isIntegerConstantExpr(ConditionSize, *Context))
431  return false;
432  llvm::APSInt ArraySize(ConstType->getSize());
433  return llvm::APSInt::isSameValue(ConditionSize, ArraySize);
434 }
435 
436 ForLoopIndexUseVisitor::ForLoopIndexUseVisitor(ASTContext *Context,
437  const VarDecl *IndexVar,
438  const VarDecl *EndVar,
439  const Expr *ContainerExpr,
440  const Expr *ArrayBoundExpr,
441  bool ContainerNeedsDereference)
442  : Context(Context), IndexVar(IndexVar), EndVar(EndVar),
443  ContainerExpr(ContainerExpr), ArrayBoundExpr(ArrayBoundExpr),
444  ContainerNeedsDereference(ContainerNeedsDereference),
445  OnlyUsedAsIndex(true), AliasDecl(nullptr),
446  ConfidenceLevel(Confidence::CL_Safe), NextStmtParent(nullptr),
447  CurrStmtParent(nullptr), ReplaceWithAliasUse(false),
448  AliasFromForInit(false) {
449  if (ContainerExpr)
450  addComponent(ContainerExpr);
451 }
452 
454  TraverseStmt(const_cast<Stmt *>(Body));
455  return OnlyUsedAsIndex && ContainerExpr;
456 }
457 
459  // FIXME: add sort(on ID)+unique to avoid extra work.
460  for (const auto &I : Components)
461  addComponent(I);
462 }
463 
464 void ForLoopIndexUseVisitor::addComponent(const Expr *E) {
465  FoldingSetNodeID ID;
466  const Expr *Node = E->IgnoreParenImpCasts();
467  Node->Profile(ID, *Context, true);
468  DependentExprs.push_back(std::make_pair(Node, ID));
469 }
470 
472  SourceLocation Begin = U.Range.getBegin();
473  if (Begin.isMacroID())
474  Begin = Context->getSourceManager().getSpellingLoc(Begin);
475 
476  if (UsageLocations.insert(Begin).second)
477  Usages.push_back(U);
478 }
479 
480 /// \brief If the unary operator is a dereference of IndexVar, include it
481 /// as a valid usage and prune the traversal.
482 ///
483 /// For example, if container.begin() and container.end() both return pointers
484 /// to int, this makes sure that the initialization for `k` is not counted as an
485 /// unconvertible use of the iterator `i`.
486 /// \code
487 /// for (int *i = container.begin(), *e = container.end(); i != e; ++i) {
488 /// int k = *i + 2;
489 /// }
490 /// \endcode
491 bool ForLoopIndexUseVisitor::TraverseUnaryDeref(UnaryOperator *Uop) {
492  // If we dereference an iterator that's actually a pointer, count the
493  // occurrence.
494  if (isDereferenceOfUop(Uop, IndexVar)) {
495  addUsage(Usage(Uop));
496  return true;
497  }
498 
499  return VisitorBase::TraverseUnaryOperator(Uop);
500 }
501 
502 /// \brief If the member expression is operator-> (overloaded or not) on
503 /// IndexVar, include it as a valid usage and prune the traversal.
504 ///
505 /// For example, given
506 /// \code
507 /// struct Foo { int bar(); int x; };
508 /// vector<Foo> v;
509 /// \endcode
510 /// the following uses will be considered convertible:
511 /// \code
512 /// for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
513 /// int b = i->bar();
514 /// int k = i->x + 1;
515 /// }
516 /// \endcode
517 /// though
518 /// \code
519 /// for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
520 /// int k = i.insert(1);
521 /// }
522 /// for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
523 /// int b = e->bar();
524 /// }
525 /// \endcode
526 /// will not.
527 bool ForLoopIndexUseVisitor::TraverseMemberExpr(MemberExpr *Member) {
528  const Expr *Base = Member->getBase();
529  const DeclRefExpr *Obj = getDeclRef(Base);
530  const Expr *ResultExpr = Member;
531  QualType ExprType;
532  if (const auto *Call =
533  dyn_cast<CXXOperatorCallExpr>(Base->IgnoreParenImpCasts())) {
534  // If operator->() is a MemberExpr containing a CXXOperatorCallExpr, then
535  // the MemberExpr does not have the expression we want. We therefore catch
536  // that instance here.
537  // For example, if vector<Foo>::iterator defines operator->(), then the
538  // example `i->bar()` at the top of this function is a CXXMemberCallExpr
539  // referring to `i->` as the member function called. We want just `i`, so
540  // we take the argument to operator->() as the base object.
541  if (Call->getOperator() == OO_Arrow) {
542  assert(Call->getNumArgs() == 1 &&
543  "Operator-> takes more than one argument");
544  Obj = getDeclRef(Call->getArg(0));
545  ResultExpr = Obj;
546  ExprType = Call->getCallReturnType(*Context);
547  }
548  }
549 
550  if (Obj && exprReferencesVariable(IndexVar, Obj)) {
551  // Member calls on the iterator with '.' are not allowed.
552  if (!Member->isArrow()) {
553  OnlyUsedAsIndex = false;
554  return true;
555  }
556 
557  if (ExprType.isNull())
558  ExprType = Obj->getType();
559 
560  if (!ExprType->isPointerType())
561  return false;
562 
563  // FIXME: This works around not having the location of the arrow operator.
564  // Consider adding OperatorLoc to MemberExpr?
565  SourceLocation ArrowLoc = Lexer::getLocForEndOfToken(
566  Base->getExprLoc(), 0, Context->getSourceManager(),
567  Context->getLangOpts());
568  // If something complicated is happening (i.e. the next token isn't an
569  // arrow), give up on making this work.
570  if (ArrowLoc.isValid()) {
571  addUsage(Usage(ResultExpr, Usage::UK_MemberThroughArrow,
572  SourceRange(Base->getExprLoc(), ArrowLoc)));
573  return true;
574  }
575  }
576  return VisitorBase::TraverseMemberExpr(Member);
577 }
578 
579 /// \brief If a member function call is the at() accessor on the container with
580 /// IndexVar as the single argument, include it as a valid usage and prune
581 /// the traversal.
582 ///
583 /// Member calls on other objects will not be permitted.
584 /// Calls on the iterator object are not permitted, unless done through
585 /// operator->(). The one exception is allowing vector::at() for pseudoarrays.
586 bool ForLoopIndexUseVisitor::TraverseCXXMemberCallExpr(
587  CXXMemberCallExpr *MemberCall) {
588  auto *Member =
589  dyn_cast<MemberExpr>(MemberCall->getCallee()->IgnoreParenImpCasts());
590  if (!Member)
591  return VisitorBase::TraverseCXXMemberCallExpr(MemberCall);
592 
593  // We specifically allow an accessor named "at" to let STL in, though
594  // this is restricted to pseudo-arrays by requiring a single, integer
595  // argument.
596  const IdentifierInfo *Ident = Member->getMemberDecl()->getIdentifier();
597  if (Ident && Ident->isStr("at") && MemberCall->getNumArgs() == 1) {
598  if (isIndexInSubscriptExpr(Context, MemberCall->getArg(0), IndexVar,
599  Member->getBase(), ContainerExpr,
600  ContainerNeedsDereference)) {
601  addUsage(Usage(MemberCall));
602  return true;
603  }
604  }
605 
606  if (containsExpr(Context, &DependentExprs, Member->getBase()))
607  ConfidenceLevel.lowerTo(Confidence::CL_Risky);
608 
609  return VisitorBase::TraverseCXXMemberCallExpr(MemberCall);
610 }
611 
612 /// \brief If an overloaded operator call is a dereference of IndexVar or
613 /// a subscript of the container with IndexVar as the single argument,
614 /// include it as a valid usage and prune the traversal.
615 ///
616 /// For example, given
617 /// \code
618 /// struct Foo { int bar(); int x; };
619 /// vector<Foo> v;
620 /// void f(Foo);
621 /// \endcode
622 /// the following uses will be considered convertible:
623 /// \code
624 /// for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
625 /// f(*i);
626 /// }
627 /// for (int i = 0; i < v.size(); ++i) {
628 /// int i = v[i] + 1;
629 /// }
630 /// \endcode
631 bool ForLoopIndexUseVisitor::TraverseCXXOperatorCallExpr(
632  CXXOperatorCallExpr *OpCall) {
633  switch (OpCall->getOperator()) {
634  case OO_Star:
635  if (isDereferenceOfOpCall(OpCall, IndexVar)) {
636  addUsage(Usage(OpCall));
637  return true;
638  }
639  break;
640 
641  case OO_Subscript:
642  if (OpCall->getNumArgs() != 2)
643  break;
644  if (isIndexInSubscriptExpr(Context, OpCall->getArg(1), IndexVar,
645  OpCall->getArg(0), ContainerExpr,
646  ContainerNeedsDereference)) {
647  addUsage(Usage(OpCall));
648  return true;
649  }
650  break;
651 
652  default:
653  break;
654  }
655  return VisitorBase::TraverseCXXOperatorCallExpr(OpCall);
656 }
657 
658 /// \brief If we encounter an array with IndexVar as the index of an
659 /// ArraySubsriptExpression, note it as a consistent usage and prune the
660 /// AST traversal.
661 ///
662 /// For example, given
663 /// \code
664 /// const int N = 5;
665 /// int arr[N];
666 /// \endcode
667 /// This is intended to permit
668 /// \code
669 /// for (int i = 0; i < N; ++i) { /* use arr[i] */ }
670 /// \endcode
671 /// but not
672 /// \code
673 /// for (int i = 0; i < N; ++i) { /* use notArr[i] */ }
674 /// \endcode
675 /// and further checking needs to be done later to ensure that exactly one array
676 /// is referenced.
677 bool ForLoopIndexUseVisitor::TraverseArraySubscriptExpr(ArraySubscriptExpr *E) {
678  Expr *Arr = E->getBase();
679  if (!isIndexInSubscriptExpr(E->getIdx(), IndexVar))
680  return VisitorBase::TraverseArraySubscriptExpr(E);
681 
682  if ((ContainerExpr &&
683  !areSameExpr(Context, Arr->IgnoreParenImpCasts(),
684  ContainerExpr->IgnoreParenImpCasts())) ||
685  !arrayMatchesBoundExpr(Context, Arr->IgnoreImpCasts()->getType(),
686  ArrayBoundExpr)) {
687  // If we have already discovered the array being indexed and this isn't it
688  // or this array doesn't match, mark this loop as unconvertible.
689  OnlyUsedAsIndex = false;
690  return VisitorBase::TraverseArraySubscriptExpr(E);
691  }
692 
693  if (!ContainerExpr)
694  ContainerExpr = Arr;
695 
696  addUsage(Usage(E));
697  return true;
698 }
699 
700 /// \brief If we encounter a reference to IndexVar in an unpruned branch of the
701 /// traversal, mark this loop as unconvertible.
702 ///
703 /// This implements the whitelist for convertible loops: any usages of IndexVar
704 /// not explicitly considered convertible by this traversal will be caught by
705 /// this function.
706 ///
707 /// Additionally, if the container expression is more complex than just a
708 /// DeclRefExpr, and some part of it is appears elsewhere in the loop, lower
709 /// our confidence in the transformation.
710 ///
711 /// For example, these are not permitted:
712 /// \code
713 /// for (int i = 0; i < N; ++i) { printf("arr[%d] = %d", i, arr[i]); }
714 /// for (vector<int>::iterator i = container.begin(), e = container.end();
715 /// i != e; ++i)
716 /// i.insert(0);
717 /// for (vector<int>::iterator i = container.begin(), e = container.end();
718 /// i != e; ++i)
719 /// if (i + 1 != e)
720 /// printf("%d", *i);
721 /// \endcode
722 ///
723 /// And these will raise the risk level:
724 /// \code
725 /// int arr[10][20];
726 /// int l = 5;
727 /// for (int j = 0; j < 20; ++j)
728 /// int k = arr[l][j] + l; // using l outside arr[l] is considered risky
729 /// for (int i = 0; i < obj.getVector().size(); ++i)
730 /// obj.foo(10); // using `obj` is considered risky
731 /// \endcode
732 bool ForLoopIndexUseVisitor::VisitDeclRefExpr(DeclRefExpr *E) {
733  const ValueDecl *TheDecl = E->getDecl();
734  if (areSameVariable(IndexVar, TheDecl) ||
735  exprReferencesVariable(IndexVar, E) || areSameVariable(EndVar, TheDecl) ||
736  exprReferencesVariable(EndVar, E))
737  OnlyUsedAsIndex = false;
738  if (containsExpr(Context, &DependentExprs, E))
739  ConfidenceLevel.lowerTo(Confidence::CL_Risky);
740  return true;
741 }
742 
743 /// \brief If the loop index is captured by a lambda, replace this capture
744 /// by the range-for loop variable.
745 ///
746 /// For example:
747 /// \code
748 /// for (int i = 0; i < N; ++i) {
749 /// auto f = [v, i](int k) {
750 /// printf("%d\n", v[i] + k);
751 /// };
752 /// f(v[i]);
753 /// }
754 /// \endcode
755 ///
756 /// Will be replaced by:
757 /// \code
758 /// for (auto & elem : v) {
759 /// auto f = [v, elem](int k) {
760 /// printf("%d\n", elem + k);
761 /// };
762 /// f(elem);
763 /// }
764 /// \endcode
765 bool ForLoopIndexUseVisitor::TraverseLambdaCapture(LambdaExpr *LE,
766  const LambdaCapture *C) {
767  if (C->capturesVariable()) {
768  const VarDecl *VDecl = C->getCapturedVar();
769  if (areSameVariable(IndexVar, cast<ValueDecl>(VDecl))) {
770  // FIXME: if the index is captured, it will count as an usage and the
771  // alias (if any) won't work, because it is only used in case of having
772  // exactly one usage.
773  addUsage(Usage(nullptr,
774  C->getCaptureKind() == LCK_ByCopy ? Usage::UK_CaptureByCopy
776  C->getLocation()));
777  }
778  }
779  return VisitorBase::TraverseLambdaCapture(LE, C);
780 }
781 
782 /// \brief If we find that another variable is created just to refer to the loop
783 /// element, note it for reuse as the loop variable.
784 ///
785 /// See the comments for isAliasDecl.
786 bool ForLoopIndexUseVisitor::VisitDeclStmt(DeclStmt *S) {
787  if (!AliasDecl && S->isSingleDecl() &&
788  isAliasDecl(Context, S->getSingleDecl(), IndexVar)) {
789  AliasDecl = S;
790  if (CurrStmtParent) {
791  if (isa<IfStmt>(CurrStmtParent) || isa<WhileStmt>(CurrStmtParent) ||
792  isa<SwitchStmt>(CurrStmtParent))
793  ReplaceWithAliasUse = true;
794  else if (isa<ForStmt>(CurrStmtParent)) {
795  if (cast<ForStmt>(CurrStmtParent)->getConditionVariableDeclStmt() == S)
796  ReplaceWithAliasUse = true;
797  else
798  // It's assumed S came the for loop's init clause.
799  AliasFromForInit = true;
800  }
801  }
802  }
803 
804  return true;
805 }
806 
807 bool ForLoopIndexUseVisitor::TraverseStmt(Stmt *S) {
808  // All this pointer swapping is a mechanism for tracking immediate parentage
809  // of Stmts.
810  const Stmt *OldNextParent = NextStmtParent;
811  CurrStmtParent = NextStmtParent;
812  NextStmtParent = S;
813  bool Result = VisitorBase::TraverseStmt(S);
814  NextStmtParent = OldNextParent;
815  return Result;
816 }
817 
819  // FIXME: Add in naming conventions to handle:
820  // - How to handle conflicts.
821  // - An interactive process for naming.
822  std::string IteratorName;
823  StringRef ContainerName;
824  if (TheContainer)
825  ContainerName = TheContainer->getName();
826 
827  size_t Len = ContainerName.size();
828  if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
829  IteratorName = ContainerName.substr(0, Len - 1);
830  // E.g.: (auto thing : things)
831  if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())
832  return IteratorName;
833  }
834 
835  if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
836  IteratorName = ContainerName.substr(0, Len - 2);
837  // E.g.: (auto thing : things_)
838  if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())
839  return IteratorName;
840  }
841 
842  return OldIndex->getName();
843 }
844 
845 /// \brief Determines whether or not the the name \a Symbol conflicts with
846 /// language keywords or defined macros. Also checks if the name exists in
847 /// LoopContext, any of its parent contexts, or any of its child statements.
848 ///
849 /// We also check to see if the same identifier was generated by this loop
850 /// converter in a loop nested within SourceStmt.
851 bool VariableNamer::declarationExists(StringRef Symbol) {
852  assert(Context != nullptr && "Expected an ASTContext");
853  IdentifierInfo &Ident = Context->Idents.get(Symbol);
854 
855  // Check if the symbol is not an identifier (ie. is a keyword or alias).
856  if (!isAnyIdentifier(Ident.getTokenID()))
857  return true;
858 
859  // Check for conflicting macro definitions.
860  if (Ident.hasMacroDefinition())
861  return true;
862 
863  // Determine if the symbol was generated in a parent context.
864  for (const Stmt *S = SourceStmt; S != nullptr; S = ReverseAST->lookup(S)) {
865  StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S);
866  if (I != GeneratedDecls->end() && I->second == Symbol)
867  return true;
868  }
869 
870  // FIXME: Rather than detecting conflicts at their usages, we should check the
871  // parent context.
872  // For some reason, lookup() always returns the pair (NULL, NULL) because its
873  // StoredDeclsMap is not initialized (i.e. LookupPtr.getInt() is false inside
874  // of DeclContext::lookup()). Why is this?
875 
876  // Finally, determine if the symbol was used in the loop or a child context.
877  DeclFinderASTVisitor DeclFinder(Symbol, GeneratedDecls);
878  return DeclFinder.findUsages(SourceStmt);
879 }
880 
881 } // namespace modernize
882 } // namespace tidy
883 } // namespace clang
const std::string Name
Definition: USRFinder.cpp:140
static const Expr * getDereferenceOperand(const Expr *E)
If the expression is a dereference or call to operator*(), return the operand.
void addUsage(const Usage &U)
Adds the Usage if it was not added before.
A class to encapsulate lowering of the tool's confidence level.
llvm::SmallVector< const clang::Expr *, 16 > ComponentVector
A vector used to store the AST subtrees of an Expr.
const Expr * digThroughConstructors(const Expr *E)
Look through conversion/copy constructors to find the explicit initialization expression, returning it is found.
const DeclRefExpr * getDeclRef(const Expr *E)
Returns the DeclRefExpr represented by E, or NULL if there isn't one.
std::string createIndexName()
Generate a new index name.
bool areSameVariable(const ValueDecl *First, const ValueDecl *Second)
Returns true when two ValueDecls are the same variable.
static bool isDereferenceOfOpCall(const CXXOperatorCallExpr *OpCall, const VarDecl *IndexVar)
Returns true when Opcall is a call a one-parameter dereference of IndexVar.
static bool isIndexInSubscriptExpr(const Expr *IndexExpr, const VarDecl *IndexVar)
Returns true when the index expression is a declaration reference to IndexVar.
bool areSameExpr(ASTContext *Context, const Expr *First, const Expr *Second)
Returns true when two Exprs are equivalent.
static bool exprReferencesVariable(const ValueDecl *Target, const Expr *E)
Determines if an expression is a declaration reference to a particular variable.
bool findAndVerifyUsages(const Stmt *Body)
Finds all uses of IndexVar in Body, placing all usages in Usages, and returns true if IndexVar was on...
The information needed to describe a valid convertible usage of an array index or iterator...
static bool isDereferenceOfUop(const UnaryOperator *Uop, const VarDecl *IndexVar)
Returns true when Uop is a dereference of IndexVar.
void addComponents(const ComponentVector &Components)
Add a set of components that we should consider relevant to the container.
void lowerTo(Confidence::Level Level)
Lower the internal confidence level to Level, but do not raise it.
ClangTidyContext & Context
Definition: ClangTidy.cpp:93
static bool isIndexInSubscriptExpr(ASTContext *Context, const Expr *IndexExpr, const VarDecl *IndexVar, const Expr *Obj, const Expr *SourceExpr, bool PermitDeref)
Returns true when the index expression is a declaration reference to IndexVar, Obj is the same expres...
static bool isAliasDecl(ASTContext *Context, const Decl *TheDecl, const VarDecl *IndexVar)
Determines whether the given Decl defines a variable initialized to the loop object.
static bool containsExpr(ASTContext *Context, const ContainerT *Container, const Expr *E)
Returns true when the Container contains an Expr equivalent to E.
static bool arrayMatchesBoundExpr(ASTContext *Context, const QualType &ArrayType, const Expr *ConditionExpr)
Determines whether the bound of a for loop condition expression is the same as the statically computa...
const NamedDecl * Result
Definition: USRFinder.cpp:137