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/Lex/Lexer.h"
17 #include "clang/Tooling/Refactoring.h"
26 typedef llvm::DenseMap<const clang::Stmt *, const clang::Stmt *>
StmtParentMap;
30 typedef llvm::DenseMap<const clang::VarDecl *, const clang::DeclStmt *>
35 typedef llvm::DenseMap<const clang::ForStmt *, const clang::VarDecl *>
39 typedef llvm::DenseMap<const clang::Stmt *, std::string>
48 :
public clang::RecursiveASTVisitor<StmtAncestorASTVisitor> {
56 if (StmtAncestors.empty())
57 TraverseDecl(const_cast<clang::TranslationUnitDecl *>(T));
71 llvm::SmallVector<const clang::Stmt *, 16> StmtStack;
73 bool TraverseStmt(clang::Stmt *Statement);
74 bool VisitDeclStmt(clang::DeclStmt *Statement);
80 :
public clang::RecursiveASTVisitor<ComponentFinderASTVisitor> {
86 TraverseStmt(const_cast<clang::Expr *>(SourceExpr));
97 bool VisitDeclRefExpr(clang::DeclRefExpr *E);
98 bool VisitMemberExpr(clang::MemberExpr *Member);
104 :
public clang::RecursiveASTVisitor<DependencyFinderASTVisitor> {
109 const clang::Stmt *ContainingStmt)
110 : StmtParents(StmtParents), DeclParents(DeclParents),
111 ContainingStmt(ContainingStmt), ReplacedVars(ReplacedVars) {}
144 DependsOnInsideVariable =
false;
145 TraverseStmt(const_cast<clang::Stmt *>(Body));
146 return DependsOnInsideVariable;
154 const clang::Stmt *ContainingStmt;
156 bool DependsOnInsideVariable;
158 bool VisitVarDecl(clang::VarDecl *V);
159 bool VisitDeclRefExpr(clang::DeclRefExpr *D);
167 :
public clang::RecursiveASTVisitor<DeclFinderASTVisitor> {
171 : Name(Name), GeneratedDecls(GeneratedDecls), Found(false) {}
178 TraverseStmt(const_cast<clang::Stmt *>(Body));
191 bool VisitForStmt(clang::ForStmt *F);
192 bool VisitNamedDecl(clang::NamedDecl *D);
193 bool VisitDeclRefExpr(clang::DeclRefExpr *D);
194 bool VisitTypeLoc(clang::TypeLoc TL);
232 :
Expression(E), Kind(Kind), Range(std::move(Range)) {}
253 CurrentLevel = std::min(Level, CurrentLevel);
278 :
public RecursiveASTVisitor<ForLoopIndexUseVisitor> {
281 const VarDecl *EndVar,
const Expr *ContainerExpr,
282 const Expr *ArrayBoundExpr,
283 bool ContainerNeedsDereference);
337 bool TraverseArraySubscriptExpr(ArraySubscriptExpr *E);
338 bool TraverseCXXMemberCallExpr(CXXMemberCallExpr *MemberCall);
339 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *OpCall);
340 bool TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C);
341 bool TraverseMemberExpr(MemberExpr *Member);
342 bool TraverseUnaryDeref(UnaryOperator *Uop);
343 bool VisitDeclRefExpr(DeclRefExpr *E);
344 bool VisitDeclStmt(DeclStmt *S);
345 bool TraverseStmt(Stmt *S);
349 void addComponent(
const Expr *E);
354 const VarDecl *IndexVar;
356 const VarDecl *EndVar;
358 const Expr *ContainerExpr;
360 const Expr *ArrayBoundExpr;
361 bool ContainerNeedsDereference;
367 llvm::SmallSet<SourceLocation, 8> UsageLocations;
368 bool OnlyUsedAsIndex;
370 const DeclStmt *AliasDecl;
376 llvm::SmallVector<std::pair<const Expr *, llvm::FoldingSetNodeID>, 16>
381 const Stmt *NextStmtParent;
385 const Stmt *CurrStmtParent;
388 bool ReplaceWithAliasUse;
390 bool AliasFromForInit;
404 std::unique_ptr<StmtAncestorASTVisitor> ParentFinder;
426 const StmtParentMap *ReverseAST,
const clang::Stmt *SourceStmt,
427 const clang::VarDecl *OldIndex,
428 const clang::ValueDecl *TheContainer,
429 const clang::ASTContext *Context,
NamingStyle Style)
430 : GeneratedDecls(GeneratedDecls), ReverseAST(ReverseAST),
431 SourceStmt(SourceStmt), OldIndex(OldIndex), TheContainer(TheContainer),
432 Context(Context), Style(Style) {}
444 const clang::Stmt *SourceStmt;
445 const clang::VarDecl *OldIndex;
446 const clang::ValueDecl *TheContainer;
447 const clang::ASTContext *Context;
452 bool declarationExists(llvm::StringRef Symbol);
455 std::string AppendWithStyle(StringRef Str, StringRef Suffix)
const;
462 #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
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...
ComponentFinderASTVisitor()
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)