9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_UTILS_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_UTILS_H
12#include "clang/AST/ASTContext.h"
13#include "clang/AST/RecursiveASTVisitor.h"
14#include "clang/ASTMatchers/ASTMatchFinder.h"
15#include "clang/Basic/SourceLocation.h"
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/SmallSet.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringRef.h"
35using StmtParentMap = llvm::DenseMap<const clang::Stmt *, const clang::Stmt *>;
40 llvm::DenseMap<const clang::VarDecl *, const clang::DeclStmt *>;
45 llvm::DenseMap<const clang::ForStmt *, const clang::VarDecl *>;
49 llvm::DenseMap<const clang::Stmt *, std::string>;
57 :
public clang::RecursiveASTVisitor<StmtAncestorASTVisitor> {
65 if (StmtAncestors.empty())
80 llvm::SmallVector<const clang::Stmt *, 16> StmtStack;
82 bool TraverseStmt(clang::Stmt *Statement);
83 bool VisitDeclStmt(clang::DeclStmt *Statement);
89 :
public clang::RecursiveASTVisitor<ComponentFinderASTVisitor> {
95 TraverseStmt(
const_cast<clang::Expr *
>(SourceExpr));
106 bool VisitDeclRefExpr(clang::DeclRefExpr *
E);
107 bool VisitMemberExpr(clang::MemberExpr *Member);
113 :
public clang::RecursiveASTVisitor<DependencyFinderASTVisitor> {
118 const clang::Stmt *ContainingStmt)
119 : StmtParents(StmtParents), DeclParents(DeclParents),
120 ContainingStmt(ContainingStmt), ReplacedVars(ReplacedVars) {}
153 DependsOnInsideVariable =
false;
154 TraverseStmt(
const_cast<clang::Stmt *
>(Body));
155 return DependsOnInsideVariable;
163 const clang::Stmt *ContainingStmt;
165 bool DependsOnInsideVariable;
167 bool VisitVarDecl(clang::VarDecl *V);
168 bool VisitDeclRefExpr(clang::DeclRefExpr *D);
176 :
public clang::RecursiveASTVisitor<DeclFinderASTVisitor> {
180 :
Name(
Name), GeneratedDecls(GeneratedDecls) {}
187 TraverseStmt(
const_cast<clang::Stmt *
>(Body));
200 bool VisitForStmt(clang::ForStmt *);
201 bool VisitNamedDecl(clang::NamedDecl *);
202 bool VisitDeclRefExpr(clang::DeclRefExpr *);
203 bool VisitTypeLoc(clang::TypeLoc);
262 CurrentLevel = std::min(
Level, CurrentLevel);
277bool areSameExpr(ASTContext *Context,
const Expr *First,
const Expr *Second);
287 :
public RecursiveASTVisitor<ForLoopIndexUseVisitor> {
290 const VarDecl *EndVar,
const Expr *ContainerExpr,
291 const Expr *ArrayBoundExpr,
292 bool ContainerNeedsDereference);
346 bool TraverseArraySubscriptExpr(ArraySubscriptExpr *
E);
347 bool TraverseCXXMemberCallExpr(CXXMemberCallExpr *MemberCall);
348 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *OpCall);
349 bool TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *
C,
351 bool TraverseMemberExpr(MemberExpr *Member);
352 bool TraverseUnaryOperator(UnaryOperator *Uop);
353 bool VisitDeclRefExpr(DeclRefExpr *
E);
354 bool VisitDeclStmt(DeclStmt *S);
355 bool TraverseStmt(Stmt *S);
357 bool TraverseStmtImpl(Stmt *S);
361 void addComponent(
const Expr *
E);
366 const VarDecl *IndexVar;
368 const VarDecl *EndVar;
370 const Expr *ContainerExpr;
372 const Expr *ArrayBoundExpr;
373 bool ContainerNeedsDereference;
379 llvm::SmallSet<SourceLocation, 8> UsageLocations;
380 bool OnlyUsedAsIndex =
true;
382 const DeclStmt *AliasDecl =
nullptr;
388 llvm::SmallVector<std::pair<const Expr *, llvm::FoldingSetNodeID>, 16>
393 const Stmt *NextStmtParent =
nullptr;
397 const Stmt *CurrStmtParent =
nullptr;
400 bool ReplaceWithAliasUse =
false;
402 bool AliasFromForInit =
false;
416 std::unique_ptr<StmtAncestorASTVisitor> ParentFinder;
438 const StmtParentMap *ReverseAST,
const clang::Stmt *SourceStmt,
439 const clang::VarDecl *OldIndex,
440 const clang::ValueDecl *TheContainer,
441 const clang::ASTContext *Context,
NamingStyle Style)
442 : GeneratedDecls(GeneratedDecls), ReverseAST(ReverseAST),
443 SourceStmt(SourceStmt), OldIndex(OldIndex), TheContainer(TheContainer),
444 Context(Context), Style(Style) {}
456 const clang::Stmt *SourceStmt;
457 const clang::VarDecl *OldIndex;
458 const clang::ValueDecl *TheContainer;
459 const clang::ASTContext *Context;
464 bool declarationExists(llvm::StringRef Symbol);
llvm::SmallString< 256U > Name
Class used to find the variables and member expressions on which an arbitrary expression depends.
void findExprComponents(const clang::Expr *SourceExpr)
Find the components of an expression and place them in a ComponentVector.
const ComponentVector & getComponents()
Accessor for Components.
ComponentFinderASTVisitor()=default
A class to encapsulate lowering of the tool's confidence level.
Level getLevel() const
Return the internal confidence level.
Confidence(Confidence::Level Level)
Initialize confidence level.
void lowerTo(Confidence::Level Level)
Lower the internal confidence level to Level, but do not raise it.
Class used to determine if any declarations used in a Stmt would conflict with a particular identifie...
bool findUsages(const clang::Stmt *Body)
Attempts to find any usages of variables name Name in Body, returning true when it is used in Body.
DeclFinderASTVisitor(const StringRef &Name, const StmtGeneratedVarNameMap *GeneratedDecls)
Class used to determine if an expression is dependent on a variable declared inside of the loop where...
DependencyFinderASTVisitor(const StmtParentMap *StmtParents, const DeclParentMap *DeclParents, const ReplacedVarsMap *ReplacedVars, const clang::Stmt *ContainingStmt)
bool dependsOnInsideVariable(const clang::Stmt *Body)
Run the analysis on Body, and return true iff the expression depends on some variable declared within...
Discover usages of expressions consisting of index or iterator access.
const UsageResult & getUsages() const
Accessor for Usages.
bool aliasFromForInit() const
Indicates if the alias declaration came from the init clause of a nested for loop.
const DeclStmt * getAliasDecl() const
Returns the statement declaring the variable created as an alias for the loop element,...
bool aliasUseRequired() const
Indicates if the alias declaration was in a place where it cannot simply be removed but rather replac...
bool findAndVerifyUsages(const Stmt *Body)
Finds all uses of IndexVar in Body, placing all usages in Usages, and returns true if IndexVar was on...
Confidence::Level getConfidenceLevel() const
Accessor for ConfidenceLevel.
friend class RecursiveASTVisitor< ForLoopIndexUseVisitor >
void addUsage(const Usage &U)
Adds the Usage if it was not added before.
void addComponents(const ComponentVector &Components)
Add a set of components that we should consider relevant to the container.
const Expr * getContainerIndexed() const
Get the container indexed by IndexVar, if any.
Class used build the reverse AST properties needed to detect name conflicts and free variables.
void gatherAncestors(ASTContext &Ctx)
Run the analysis on the AST.
const DeclParentMap & getDeclToParentStmtMap()
Accessor for DeclParents.
const StmtParentMap & getStmtToParentStmtMap()
Accessor for StmtAncestors.
Create names for generated variables within a particular statement.
VariableNamer(StmtGeneratedVarNameMap *GeneratedDecls, const StmtParentMap *ReverseAST, const clang::Stmt *SourceStmt, const clang::VarDecl *OldIndex, const clang::ValueDecl *TheContainer, const clang::ASTContext *Context, NamingStyle Style)
std::string createIndexName()
Generate a new index name.
llvm::DenseMap< const clang::Stmt *, std::string > StmtGeneratedVarNameMap
A map used to remember the variable names generated in a Stmt.
llvm::DenseMap< const clang::VarDecl *, const clang::DeclStmt * > DeclParentMap
A map used to walk the AST in reverse: maps VarDecl to the to parent DeclStmt.
const DeclRefExpr * getDeclRef(const Expr *E)
Returns the DeclRefExpr represented by E, or NULL if there isn't one.
bool areSameVariable(const ValueDecl *First, const ValueDecl *Second)
Returns true when two ValueDecls are the same variable.
const Expr * digThroughConstructorsConversions(const Expr *E)
Look through conversion/copy constructors and member functions to find the explicit initialization ex...
llvm::DenseMap< const clang::Stmt *, const clang::Stmt * > StmtParentMap
A map used to walk the AST in reverse: maps child Stmt to parent Stmt.
llvm::SmallVector< Usage, 8 > UsageResult
bool areSameExpr(ASTContext *Context, const Expr *First, const Expr *Second)
Returns true when two Exprs are equivalent.
llvm::SmallVector< const clang::Expr *, 16 > ComponentVector
A vector used to store the AST subtrees of an Expr.
llvm::DenseMap< const clang::ForStmt *, const clang::VarDecl * > ReplacedVarsMap
A map used to track which variables have been removed by a refactoring pass.
TUTrackingInfo()
Reset and initialize per-TU tracking information.
ReplacedVarsMap & getReplacedVars()
StmtGeneratedVarNameMap & getGeneratedDecls()
StmtAncestorASTVisitor & getParentFinder()
The information needed to describe a valid convertible usage of an array index or iterator.
Usage(const Expr *E, UsageKind Kind, SourceRange Range)