[clang] f29204d - NFC: Implement AST node skipping in ParentMapContext

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 26 10:35:53 PST 2020


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);
 }
-


        


More information about the cfe-commits mailing list