diff options
author | Stephen Kelly <steveire@gmail.com> | 2019-05-12 21:09:32 +0100 |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2019-12-06 23:11:32 +0000 |
commit | 0a717d5b5d31fc2d5bc98ca695031fb09e65beb0 (patch) | |
tree | 86fc2295619a94015df5a4f5436cb80869c24dbb /clang/lib/AST | |
parent | b4f4e370b59a753a51f11848f54e9705f43cccaf (diff) | |
download | bcm5719-llvm-0a717d5b5d31fc2d5bc98ca695031fb09e65beb0.tar.gz bcm5719-llvm-0a717d5b5d31fc2d5bc98ca695031fb09e65beb0.zip |
Make it possible control matcher traversal kind with ASTContext
Summary:
This will eventually allow traversal of an AST while ignoring invisible
AST nodes. Currently it depends on the available enum values for
TraversalKinds. That can be extended to ignore all invisible nodes in
the future.
Reviewers: klimek, aaron.ballman
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D61837
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 10b6718c89b..d6010caa4a2 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -99,6 +99,30 @@ using namespace clang; enum FloatingRank { Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank }; +const Expr *ASTContext::traverseIgnored(const Expr *E) const { + return traverseIgnored(const_cast<Expr *>(E)); +} + +Expr *ASTContext::traverseIgnored(Expr *E) const { + if (!E) + return nullptr; + + switch (Traversal) { + case ast_type_traits::TK_AsIs: + return E; + case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses: + return E->IgnoreParenImpCasts(); + } + llvm_unreachable("Invalid Traversal type!"); +} + +ast_type_traits::DynTypedNode +ASTContext::traverseIgnored(const ast_type_traits::DynTypedNode &N) const { + if (const auto *E = N.get<Expr>()) { + return ast_type_traits::DynTypedNode::create(*traverseIgnored(E)); + } + return N; +} /// \returns location that is relevant when searching for Doc comments related /// to \p D. @@ -959,7 +983,7 @@ public: void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) { TraversalScope = TopLevelDecls; - Parents.reset(); + Parents.clear(); } void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const { @@ -10397,7 +10421,8 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) { class ASTContext::ParentMap::ASTVisitor : public RecursiveASTVisitor<ASTVisitor> { public: - ASTVisitor(ParentMap &Map) : Map(Map) {} + ASTVisitor(ParentMap &Map, ASTContext &Context) + : Map(Map), Context(Context) {} private: friend class RecursiveASTVisitor<ASTVisitor>; @@ -10467,9 +10492,12 @@ private: } bool TraverseStmt(Stmt *StmtNode) { - return TraverseNode( - StmtNode, StmtNode, [&] { return VisitorBase::TraverseStmt(StmtNode); }, - &Map.PointerParents); + Stmt *FilteredNode = StmtNode; + if (auto *ExprNode = dyn_cast_or_null<Expr>(FilteredNode)) + FilteredNode = Context.traverseIgnored(ExprNode); + return TraverseNode(FilteredNode, FilteredNode, + [&] { return VisitorBase::TraverseStmt(FilteredNode); }, + &Map.PointerParents); } bool TraverseTypeLoc(TypeLoc TypeLocNode) { @@ -10487,20 +10515,22 @@ private: } ParentMap ⤅ + ASTContext &Context; llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; }; ASTContext::ParentMap::ParentMap(ASTContext &Ctx) { - ASTVisitor(*this).TraverseAST(Ctx); + ASTVisitor(*this, Ctx).TraverseAST(Ctx); } ASTContext::DynTypedNodeList ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { - if (!Parents) + std::unique_ptr<ParentMap> &P = Parents[Traversal]; + if (!P) // We build the parent map for the traversal scope (usually whole TU), as // hasAncestor can escape any subtree. - Parents = std::make_unique<ParentMap>(*this); - return Parents->getParents(Node); + P = std::make_unique<ParentMap>(*this); + return P->getParents(Node); } bool |