LoopConvertUtils.cpp 31 KB

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