This revision was automatically updated to reflect the committed changes.
Closed by commit rGf29204d38888: NFC: Implement AST node skipping in 
ParentMapContext (authored by stephenkelly).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73388/new/

https://reviews.llvm.org/D73388

Files:
  clang/include/clang/AST/ParentMapContext.h
  clang/lib/AST/ParentMapContext.cpp

Index: clang/lib/AST/ParentMapContext.cpp
===================================================================
--- clang/lib/AST/ParentMapContext.cpp
+++ clang/lib/AST/ParentMapContext.cpp
@@ -23,7 +23,7 @@
 
 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 @@
     }
   }
 
-  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 @@
 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 @@
   }
 
   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 @@
   }
 
   ParentMap &Map;
-  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);
 }
-
Index: clang/include/clang/AST/ParentMapContext.h
===================================================================
--- clang/include/clang/AST/ParentMapContext.h
+++ clang/include/clang/AST/ParentMapContext.h
@@ -69,7 +69,7 @@
   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 {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D73388: I... Stephen Kelly via Phabricator via cfe-commits
    • [PATCH] D733... Stephen Kelly via Phabricator via cfe-commits
    • [PATCH] D733... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D733... Stephen Kelly via Phabricator via cfe-commits
    • [PATCH] D733... Stephen Kelly via Phabricator via cfe-commits

Reply via email to