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