10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_UTILS_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_UTILS_H
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/RecursiveASTVisitor.h"
15 #include "clang/ASTMatchers/ASTMatchFinder.h"
16 #include "clang/Basic/SourceLocation.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/SmallSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
33 typedef llvm::DenseMap<const clang::Stmt *, const clang::Stmt *>
StmtParentMap;
37 typedef llvm::DenseMap<const clang::VarDecl *, const clang::DeclStmt *>
42 typedef llvm::DenseMap<const clang::ForStmt *, const clang::VarDecl *>
46 typedef llvm::DenseMap<const clang::Stmt *, std::string>
55 :
public clang::RecursiveASTVisitor<StmtAncestorASTVisitor> {
63 if (StmtAncestors.empty())
64 TraverseDecl(const_cast<clang::TranslationUnitDecl *>(T));
78 llvm::SmallVector<const clang::Stmt *, 16> StmtStack;
80 bool TraverseStmt(clang::Stmt *Statement);
81 bool VisitDeclStmt(clang::DeclStmt *Statement);
87 :
public clang::RecursiveASTVisitor<ComponentFinderASTVisitor> {
93 TraverseStmt(const_cast<clang::Expr *>(SourceExpr));
104 bool VisitDeclRefExpr(clang::DeclRefExpr *E);
105 bool VisitMemberExpr(clang::MemberExpr *Member);
111 :
public clang::RecursiveASTVisitor<DependencyFinderASTVisitor> {
116 const clang::Stmt *ContainingStmt)
117 : StmtParents(StmtParents), DeclParents(DeclParents),
118 ContainingStmt(ContainingStmt), ReplacedVars(ReplacedVars) {}
151 DependsOnInsideVariable =
false;
152 TraverseStmt(const_cast<clang::Stmt *>(Body));
153 return DependsOnInsideVariable;
161 const clang::Stmt *ContainingStmt;
163 bool DependsOnInsideVariable;
165 bool VisitVarDecl(clang::VarDecl *V);
166 bool VisitDeclRefExpr(clang::DeclRefExpr *D);
174 :
public clang::RecursiveASTVisitor<DeclFinderASTVisitor> {
178 : Name(Name), GeneratedDecls(GeneratedDecls), Found(false) {}
185 TraverseStmt(const_cast<clang::Stmt *>(Body));
198 bool VisitForStmt(clang::ForStmt *F);
199 bool VisitNamedDecl(clang::NamedDecl *D);
200 bool VisitDeclRefExpr(clang::DeclRefExpr *D);
201 bool VisitTypeLoc(clang::TypeLoc TL);
239 :
Expression(E), Kind(Kind), Range(std::move(Range)) {}
260 CurrentLevel = std::min(Level, CurrentLevel);
285 :
public RecursiveASTVisitor<ForLoopIndexUseVisitor> {
288 const VarDecl *EndVar,
const Expr *ContainerExpr,
289 const Expr *ArrayBoundExpr,
290 bool ContainerNeedsDereference);
344 bool TraverseArraySubscriptExpr(ArraySubscriptExpr *E);
345 bool TraverseCXXMemberCallExpr(CXXMemberCallExpr *MemberCall);
346 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *OpCall);
347 bool TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C,
349 bool TraverseMemberExpr(MemberExpr *Member);
350 bool TraverseUnaryDeref(UnaryOperator *Uop);
351 bool VisitDeclRefExpr(DeclRefExpr *E);
352 bool VisitDeclStmt(DeclStmt *S);
353 bool TraverseStmt(Stmt *S);
357 void addComponent(
const Expr *E);
362 const VarDecl *IndexVar;
364 const VarDecl *EndVar;
366 const Expr *ContainerExpr;
368 const Expr *ArrayBoundExpr;
369 bool ContainerNeedsDereference;
375 llvm::SmallSet<SourceLocation, 8> UsageLocations;
376 bool OnlyUsedAsIndex;
378 const DeclStmt *AliasDecl;
384 llvm::SmallVector<std::pair<const Expr *, llvm::FoldingSetNodeID>, 16>
389 const Stmt *NextStmtParent;
393 const Stmt *CurrStmtParent;
396 bool ReplaceWithAliasUse;
398 bool AliasFromForInit;
412 std::unique_ptr<StmtAncestorASTVisitor> ParentFinder;
434 const StmtParentMap *ReverseAST,
const clang::Stmt *SourceStmt,
435 const clang::VarDecl *OldIndex,
436 const clang::ValueDecl *TheContainer,
437 const clang::ASTContext *Context,
NamingStyle Style)
438 : GeneratedDecls(GeneratedDecls), ReverseAST(ReverseAST),
439 SourceStmt(SourceStmt), OldIndex(OldIndex), TheContainer(TheContainer),
440 Context(Context), Style(Style) {}
452 const clang::Stmt *SourceStmt;
453 const clang::VarDecl *OldIndex;
454 const clang::ValueDecl *TheContainer;
455 const clang::ASTContext *Context;
460 bool declarationExists(llvm::StringRef Symbol);
467 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_UTILS_H
StmtAncestorASTVisitor & getParentFinder()
Discover usages of expressions consisting of index or iterator access.
Class used build the reverse AST properties needed to detect name conflicts and free variables...
TUTrackingInfo()
Reset and initialize per-TU tracking information.
llvm::SmallVector< Usage, 8 > UsageResult
ComponentFinderASTVisitor()=default
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...
llvm::DenseMap< const clang::Stmt *, std::string > StmtGeneratedVarNameMap
A map used to remember the variable names generated in a Stmt.
bool aliasFromForInit() const
Indicates if the alias declaration came from the init clause of a nested for loop.
friend class RecursiveASTVisitor< ForLoopIndexUseVisitor >
void addUsage(const Usage &U)
Adds the Usage if it was not added before.
DependencyFinderASTVisitor(const StmtParentMap *StmtParents, const DeclParentMap *DeclParents, const ReplacedVarsMap *ReplacedVars, const clang::Stmt *ContainingStmt)
A class to encapsulate lowering of the tool's confidence level.
ReplacedVarsMap & getReplacedVars()
llvm::SmallVector< const clang::Expr *, 16 > ComponentVector
A vector used to store the AST subtrees of an Expr.
Class used to determine if an expression is dependent on a variable declared inside of the loop where...
void gatherAncestors(const clang::TranslationUnitDecl *T)
Run the analysis on the TranslationUnitDecl.
const Expr * digThroughConstructors(const Expr *E)
Look through conversion/copy constructors to find the explicit initialization expression, returning it is found.
const Expr * getContainerIndexed() const
Get the container indexed by IndexVar, if any.
StmtGeneratedVarNameMap & getGeneratedDecls()
Level getLevel() const
Return the internal confidence level.
Confidence::Level getConfidenceLevel() const
Accessor for ConfidenceLevel.
const DeclRefExpr * getDeclRef(const Expr *E)
Returns the DeclRefExpr represented by E, or NULL if there isn't one.
void findExprComponents(const clang::Expr *SourceExpr)
Find the components of an expression and place them in a ComponentVector.
std::string createIndexName()
Generate a new index name.
const ComponentVector & getComponents()
Accessor for Components.
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 DeclStmt * getAliasDecl() const
Returns the statement declaring the variable created as an alias for the loop element, if any.
bool areSameVariable(const ValueDecl *First, const ValueDecl *Second)
Returns true when two ValueDecls are the same variable.
const DeclParentMap & getDeclToParentStmtMap()
Accessor for DeclParents.
Create names for generated variables within a particular statement.
Usage(const Expr *E, UsageKind Kind, SourceRange Range)
const StmtParentMap & getStmtToParentStmtMap()
Accessor for StmtAncestors.
bool areSameExpr(ASTContext *Context, const Expr *First, const Expr *Second)
Returns true when two Exprs are equivalent.
bool dependsOnInsideVariable(const clang::Stmt *Body)
Run the analysis on Body, and return true iff the expression depends on some variable declared within...
DeclFinderASTVisitor(const std::string &Name, const StmtGeneratedVarNameMap *GeneratedDecls)
const UsageResult & getUsages() const
Accessor for Usages.
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...
The information needed to describe a valid convertible usage of an array index or iterator...
void addComponents(const ComponentVector &Components)
Add a set of components that we should consider relevant to the container.
void lowerTo(Confidence::Level Level)
Lower the internal confidence level to Level, but do not raise it.
ClangTidyContext & Context
Class used to determine if any declarations used in a Stmt would conflict with a particular identifie...
llvm::DenseMap< const clang::ForStmt *, const clang::VarDecl * > ReplacedVarsMap
A map used to track which variables have been removed by a refactoring pass.
Class used to find the variables and member expressions on which an arbitrary expression depends...
ForLoopIndexUseVisitor(ASTContext *Context, const VarDecl *IndexVar, const VarDecl *EndVar, const Expr *ContainerExpr, const Expr *ArrayBoundExpr, bool ContainerNeedsDereference)
llvm::DenseMap< const clang::Stmt *, const clang::Stmt * > StmtParentMap
A map used to walk the AST in reverse: maps child Stmt to parent Stmt.
Confidence(Confidence::Level Level)
Initialize confidence level.
VariableNamer(StmtGeneratedVarNameMap *GeneratedDecls, const StmtParentMap *ReverseAST, const clang::Stmt *SourceStmt, const clang::VarDecl *OldIndex, const clang::ValueDecl *TheContainer, const clang::ASTContext *Context, NamingStyle Style)