Author: Stephen Kelly Date: 2020-01-26T18:35:44Z New Revision: f29204d3888897dc5b6fec83df5f2a77aff17173
URL: https://github.com/llvm/llvm-project/commit/f29204d3888897dc5b6fec83df5f2a77aff17173 DIFF: https://github.com/llvm/llvm-project/commit/f29204d3888897dc5b6fec83df5f2a77aff17173.diff LOG: NFC: Implement AST node skipping in ParentMapContext Summary: This allows ASTContext to store only one parent map, rather than storing an entire parent map for each traversal mode used. This is therefore a partial revert of commit 0a717d5b (Make it possible control matcher traversal kind with ASTContext, 2019-12-06). Reviewers: aaron.ballman, rsmith, rnk Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73388 Added: Modified: clang/include/clang/AST/ParentMapContext.h clang/lib/AST/ParentMapContext.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ParentMapContext.h b/clang/include/clang/AST/ParentMapContext.h index de1f054be168..c0fc5e286a59 100644 --- a/clang/include/clang/AST/ParentMapContext.h +++ b/clang/include/clang/AST/ParentMapContext.h @@ -69,7 +69,7 @@ class ParentMapContext { ASTContext &ASTCtx; class ParentMap; ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs; - std::map<ast_type_traits::TraversalKind, std::unique_ptr<ParentMap>> Parents; + std::unique_ptr<ParentMap> Parents; }; class TraversalKindScope { diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp index 6287bc8c1d72..6a22e687ff57 100644 --- a/clang/lib/AST/ParentMapContext.cpp +++ b/clang/lib/AST/ParentMapContext.cpp @@ -23,7 +23,7 @@ ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {} ParentMapContext::~ParentMapContext() = default; -void ParentMapContext::clear() { Parents.clear(); } +void ParentMapContext::clear() { Parents.reset(); } const Expr *ParentMapContext::traverseIgnored(const Expr *E) const { return traverseIgnored(const_cast<Expr *>(E)); @@ -116,11 +116,79 @@ class ParentMapContext::ParentMap { } } - DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node) { - if (Node.getNodeKind().hasPointerIdentity()) - return getDynNodeFromMap(Node.getMemoizationData(), PointerParents); + DynTypedNodeList getParents(ast_type_traits::TraversalKind TK, + const ast_type_traits::DynTypedNode &Node) { + if (Node.getNodeKind().hasPointerIdentity()) { + auto ParentList = + getDynNodeFromMap(Node.getMemoizationData(), PointerParents); + if (ParentList.size() == 1 && + TK == ast_type_traits::TK_IgnoreUnlessSpelledInSource) { + const auto *E = ParentList[0].get<Expr>(); + const auto *Child = Node.get<Expr>(); + if (E && Child) + return AscendIgnoreUnlessSpelledInSource(E, Child); + } + return ParentList; + } return getDynNodeFromMap(Node, OtherParents); } + + ast_type_traits::DynTypedNode + AscendIgnoreUnlessSpelledInSource(const Expr *E, const Expr *Child) { + + auto ShouldSkip = [](const Expr *E, const Expr *Child) { + if (isa<ImplicitCastExpr>(E)) + return true; + + if (isa<FullExpr>(E)) + return true; + + if (isa<MaterializeTemporaryExpr>(E)) + return true; + + if (isa<CXXBindTemporaryExpr>(E)) + return true; + + if (isa<ParenExpr>(E)) + return true; + + if (isa<ExprWithCleanups>(E)) + return true; + + auto SR = Child->getSourceRange(); + + if (const auto *C = dyn_cast<CXXConstructExpr>(E)) { + if (C->getSourceRange() == SR || !isa<CXXTemporaryObjectExpr>(C)) + return true; + } + + if (const auto *C = dyn_cast<CXXMemberCallExpr>(E)) { + if (C->getSourceRange() == SR) + return true; + } + + if (const auto *C = dyn_cast<MemberExpr>(E)) { + if (C->getSourceRange() == SR) + return true; + } + return false; + }; + + while (ShouldSkip(E, Child)) { + auto It = PointerParents.find(E); + if (It == PointerParents.end()) + break; + const auto *S = It->second.dyn_cast<const Stmt *>(); + if (!S) + return getSingleDynTypedNodeFromParentMap(It->second); + const auto *P = dyn_cast<Expr>(S); + if (!P) + return ast_type_traits::DynTypedNode::create(*S); + Child = E; + E = P; + } + return ast_type_traits::DynTypedNode::create(*E); + } }; /// Template specializations to abstract away from pointers and TypeLocs. @@ -151,8 +219,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) { class ParentMapContext::ParentMap::ASTVisitor : public RecursiveASTVisitor<ASTVisitor> { public: - ASTVisitor(ParentMap &Map, ParentMapContext &MapCtx) - : Map(Map), MapCtx(MapCtx) {} + ASTVisitor(ParentMap &Map) : Map(Map) {} private: friend class RecursiveASTVisitor<ASTVisitor>; @@ -222,11 +289,8 @@ class ParentMapContext::ParentMap::ASTVisitor } bool TraverseStmt(Stmt *StmtNode) { - Stmt *FilteredNode = StmtNode; - if (auto *ExprNode = dyn_cast_or_null<Expr>(FilteredNode)) - FilteredNode = MapCtx.traverseIgnored(ExprNode); - return TraverseNode(FilteredNode, FilteredNode, - [&] { return VisitorBase::TraverseStmt(FilteredNode); }, + return TraverseNode(StmtNode, StmtNode, + [&] { return VisitorBase::TraverseStmt(StmtNode); }, &Map.PointerParents); } @@ -245,21 +309,18 @@ class ParentMapContext::ParentMap::ASTVisitor } ParentMap ⤅ - ParentMapContext &MapCtx; llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; }; ParentMapContext::ParentMap::ParentMap(ASTContext &Ctx) { - ASTVisitor(*this, Ctx.getParentMapContext()).TraverseAST(Ctx); + ASTVisitor(*this).TraverseAST(Ctx); } DynTypedNodeList ParentMapContext::getParents(const ast_type_traits::DynTypedNode &Node) { - std::unique_ptr<ParentMap> &P = Parents[Traversal]; - if (!P) + if (!Parents) // We build the parent map for the traversal scope (usually whole TU), as // hasAncestor can escape any subtree. - P = std::make_unique<ParentMap>(ASTCtx); - return P->getParents(Node); + Parents = std::make_unique<ParentMap>(ASTCtx); + return Parents->getParents(getTraversalKind(), Node); } - _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits