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->IgnoreParenImpCasts();
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 
453 bool ForLoopIndexUseVisitor::findAndVerifyUsages(const Stmt *Body) {
454   TraverseStmt(const_cast<Stmt *>(Body));
455   return OnlyUsedAsIndex && ContainerExpr;
456 }
457 
458 void ForLoopIndexUseVisitor::addComponents(const ComponentVector &Components) {
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 
471 void ForLoopIndexUseVisitor::addUsage(const Usage &U) {
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
775                                                        : Usage::UK_CaptureByRef,
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 
818 std::string VariableNamer::createIndexName() {
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 std::string VariableNamer::AppendWithStyle(StringRef Str,
882                                            StringRef Suffix) const {
883   std::string Name = Str;
884   if (!Suffix.empty()) {
885     if (Style == NS_LowerCase || Style == NS_UpperCase)
886       Name += "_";
887     int SuffixStart = Name.size();
888     Name += Suffix;
889     if (Style == NS_CamelBack)
890       Name[SuffixStart] = toupper(Name[SuffixStart]);
891   }
892   return Name;
893 }
894 
895 } // namespace modernize
896 } // namespace tidy
897 } // namespace clang
898