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" 32 typedef llvm::DenseMap<const clang::Stmt *, const clang::Stmt *>
StmtParentMap;
36 typedef llvm::DenseMap<const clang::VarDecl *, const clang::DeclStmt *>
41 typedef llvm::DenseMap<const clang::ForStmt *, const clang::VarDecl *>
45 typedef llvm::DenseMap<const clang::Stmt *, std::string>
54 :
public clang::RecursiveASTVisitor<StmtAncestorASTVisitor> {
62 if (StmtAncestors.empty())
75 StmtParentMap StmtAncestors;
77 llvm::SmallVector<const clang::Stmt *, 16> StmtStack;
79 bool TraverseStmt(clang::Stmt *Statement);
80 bool VisitDeclStmt(clang::DeclStmt *Statement);
86 :
public clang::RecursiveASTVisitor<ComponentFinderASTVisitor> {
92 TraverseStmt(const_cast<clang::Expr *>(SourceExpr));
101 ComponentVector Components;
103 bool VisitDeclRefExpr(clang::DeclRefExpr *E);
104 bool VisitMemberExpr(clang::MemberExpr *Member);
110 :
public clang::RecursiveASTVisitor<DependencyFinderASTVisitor> {
115 const clang::Stmt *ContainingStmt)
116 : StmtParents(StmtParents), DeclParents(DeclParents),
117 ContainingStmt(ContainingStmt), ReplacedVars(ReplacedVars) {}
150 DependsOnInsideVariable =
false;
151 TraverseStmt(const_cast<clang::Stmt *>(Body));
152 return DependsOnInsideVariable;
158 const StmtParentMap *StmtParents;
160 const clang::Stmt *ContainingStmt;
162 bool DependsOnInsideVariable;
164 bool VisitVarDecl(clang::VarDecl *V);
165 bool VisitDeclRefExpr(clang::DeclRefExpr *
D);
173 :
public clang::RecursiveASTVisitor<DeclFinderASTVisitor> {
177 : Name(Name), GeneratedDecls(GeneratedDecls), Found(false) {}
184 TraverseStmt(const_cast<clang::Stmt *>(Body));
197 bool VisitForStmt(clang::ForStmt *F);
198 bool VisitNamedDecl(clang::NamedDecl *
D);
199 bool VisitDeclRefExpr(clang::DeclRefExpr *
D);
200 bool VisitTypeLoc(clang::TypeLoc TL);
228 const Expr *Expression;
236 : Expression(E), Kind(UK_Default), Range(Expression->getSourceRange()) {}
238 : Expression(E), Kind(Kind), Range(std::move(Range)) {}
259 CurrentLevel = std::min(Level, CurrentLevel);
274 bool areSameExpr(ASTContext *Context,
const Expr *First,
const Expr *Second);
284 :
public RecursiveASTVisitor<ForLoopIndexUseVisitor> {
287 const VarDecl *EndVar,
const Expr *ContainerExpr,
288 const Expr *ArrayBoundExpr,
289 bool ContainerNeedsDereference);
302 bool findAndVerifyUsages(
const Stmt *Body);
306 void addComponents(
const ComponentVector &Components);
315 const Expr *getContainerIndexed()
const {
return ContainerExpr; }
323 return ConfidenceLevel.getLevel();
339 typedef RecursiveASTVisitor<ForLoopIndexUseVisitor> VisitorBase;
343 bool TraverseArraySubscriptExpr(ArraySubscriptExpr *E);
344 bool TraverseCXXMemberCallExpr(CXXMemberCallExpr *MemberCall);
345 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *OpCall);
346 bool TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C,
348 bool TraverseMemberExpr(MemberExpr *Member);
349 bool TraverseUnaryDeref(UnaryOperator *Uop);
350 bool VisitDeclRefExpr(DeclRefExpr *E);
351 bool VisitDeclStmt(DeclStmt *S);
352 bool TraverseStmt(Stmt *S);
356 void addComponent(
const Expr *E);
361 const VarDecl *IndexVar;
363 const VarDecl *EndVar;
365 const Expr *ContainerExpr;
367 const Expr *ArrayBoundExpr;
368 bool ContainerNeedsDereference;
374 llvm::SmallSet<SourceLocation, 8> UsageLocations;
375 bool OnlyUsedAsIndex;
377 const DeclStmt *AliasDecl;
383 llvm::SmallVector<std::pair<const Expr *, llvm::FoldingSetNodeID>, 16>
388 const Stmt *NextStmtParent;
392 const Stmt *CurrStmtParent;
395 bool ReplaceWithAliasUse;
397 bool AliasFromForInit;
411 std::unique_ptr<StmtAncestorASTVisitor> ParentFinder;
433 const StmtParentMap *ReverseAST,
const clang::Stmt *SourceStmt,
434 const clang::VarDecl *OldIndex,
435 const clang::ValueDecl *TheContainer,
436 const clang::ASTContext *Context,
NamingStyle Style)
437 : GeneratedDecls(GeneratedDecls), ReverseAST(ReverseAST),
438 SourceStmt(SourceStmt), OldIndex(OldIndex), TheContainer(TheContainer),
439 Context(Context), Style(Style) {}
446 std::string createIndexName();
450 const StmtParentMap *ReverseAST;
451 const clang::Stmt *SourceStmt;
452 const clang::VarDecl *OldIndex;
453 const clang::ValueDecl *TheContainer;
454 const clang::ASTContext *Context;
459 bool declarationExists(llvm::StringRef Symbol);
466 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_UTILS_H StmtAncestorASTVisitor & getParentFinder()
Confidence::Level getConfidenceLevel() const
Accessor for ConfidenceLevel.
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.
static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures, const IdentifierNamingCheck::NamingCheckId &Decl, SourceRange Range, SourceManager *SourceMgr=nullptr)
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.
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...
bool aliasUseRequired() const
Indicates if the alias declaration was in a place where it cannot simply be removed but rather replac...
const Expr * digThroughConstructors(const Expr *E)
Look through conversion/copy constructors to find the explicit initialization expression, returning it is found.
StmtGeneratedVarNameMap & getGeneratedDecls()
bool aliasFromForInit() const
Indicates if the alias declaration came from the init clause of a nested for loop.
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.
const ComponentVector & getComponents()
Accessor for Components.
Level getLevel() const
Return the internal confidence level.
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.
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.
static constexpr llvm::StringLiteral Name
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)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
The information needed to describe a valid convertible usage of an array index or iterator...
void lowerTo(Confidence::Level Level)
Lower the internal confidence level to Level, but do not raise it.
void gatherAncestors(ASTContext &Ctx)
Run the analysis on the AST.
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...
llvm::DenseMap< const clang::Stmt *, const clang::Stmt * > StmtParentMap
A map used to walk the AST in reverse: maps child Stmt to parent Stmt.
const UsageResult & getUsages() const
Accessor for Usages.
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)
const DeclStmt * getAliasDecl() const
Returns the statement declaring the variable created as an alias for the loop element, if any.