steveire created this revision.
steveire added a reviewer: aaron.ballman.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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 
<https://reviews.llvm.org/rG0a717d5b5d31fc2d5bc98ca695031fb09e65beb0> (Make it 
possible
control matcher traversal kind with ASTContext, 2019-12-06).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73029

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ExprTraversal.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ExprTraversal.cpp

Index: clang/lib/AST/ExprTraversal.cpp
===================================================================
--- clang/lib/AST/ExprTraversal.cpp
+++ clang/lib/AST/ExprTraversal.cpp
@@ -253,3 +253,41 @@
 
   return E;
 }
+
+bool ExprTraversal::AscendSkipUnlessSpelledInSource(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 (auto *C = dyn_cast<CXXConstructExpr>(E)) {
+    if (C->getSourceRange() == SR || !isa<CXXTemporaryObjectExpr>(C))
+      return true;
+  }
+
+  if (auto *C = dyn_cast<CXXMemberCallExpr>(E)) {
+    if (C->getSourceRange() == SR)
+      return true;
+  }
+
+  if (auto *C = dyn_cast<MemberExpr>(E)) {
+    if (C->getSourceRange() == SR)
+      return true;
+  }
+  return false;
+}
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -31,6 +31,7 @@
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprTraversal.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/MangleNumberingContext.h"
@@ -1059,16 +1060,42 @@
     }
   }
 
-  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 Expr* E = ParentList[0].get<Expr>();
+        const Expr* 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)
+  {
+    while (ExprTraversal::AscendSkipUnlessSpelledInSource(E, Child)) {
+      auto It = PointerParents.find(E);
+      if (It == PointerParents.end())
+        break;
+      auto *S = It->second.dyn_cast<const Stmt *>();
+      if (!S)
+        return getSingleDynTypedNodeFromParentMap(It->second);
+      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);
+  }
 };
 
 void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {
   TraversalScope = TopLevelDecls;
-  Parents.clear();
+  Parents.reset();
 }
 
 void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {
@@ -10536,8 +10563,8 @@
 class ASTContext::ParentMap::ASTVisitor
     : public RecursiveASTVisitor<ASTVisitor> {
 public:
-  ASTVisitor(ParentMap &Map, ASTContext &Context)
-      : Map(Map), Context(Context) {}
+  ASTVisitor(ParentMap &Map)
+      : Map(Map) {}
 
 private:
   friend class RecursiveASTVisitor<ASTVisitor>;
@@ -10607,11 +10634,8 @@
   }
 
   bool TraverseStmt(Stmt *StmtNode) {
-    Stmt *FilteredNode = StmtNode;
-    if (auto *ExprNode = dyn_cast_or_null<Expr>(FilteredNode))
-      FilteredNode = Context.traverseIgnored(ExprNode);
-    return TraverseNode(FilteredNode, FilteredNode,
-                        [&] { return VisitorBase::TraverseStmt(FilteredNode); },
+    return TraverseNode(StmtNode, StmtNode,
+                        [&] { return VisitorBase::TraverseStmt(StmtNode); },
                         &Map.PointerParents);
   }
 
@@ -10630,22 +10654,20 @@
   }
 
   ParentMap &Map;
-  ASTContext &Context;
   llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
 };
 
 ASTContext::ParentMap::ParentMap(ASTContext &Ctx) {
-  ASTVisitor(*this, Ctx).TraverseAST(Ctx);
+  ASTVisitor(*this).TraverseAST(Ctx);
 }
 
 ASTContext::DynTypedNodeList
 ASTContext::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>(*this);
-  return P->getParents(Node);
+    Parents = std::make_unique<ParentMap>(*this);
+  return Parents->getParents(getTraversalKind(), Node);
 }
 
 bool
Index: clang/include/clang/AST/ExprTraversal.h
===================================================================
--- clang/include/clang/AST/ExprTraversal.h
+++ clang/include/clang/AST/ExprTraversal.h
@@ -33,6 +33,8 @@
   static Expr *DescendIgnoreParenBaseCasts(Expr *E);
   static Expr *DescendIgnoreParenNoopCasts(const ASTContext &Ctx, Expr *E);
   static Expr *DescendIgnoreUnlessSpelledInSource(Expr *E);
+
+  static bool AscendSkipUnlessSpelledInSource(const Expr *E, const Expr *Child);
 };
 
 }
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -3024,7 +3024,7 @@
 
   std::vector<Decl *> TraversalScope;
   class ParentMap;
-  std::map<ast_type_traits::TraversalKind, std::unique_ptr<ParentMap>> Parents;
+  std::unique_ptr<ParentMap> Parents;
 
   std::unique_ptr<VTableContextBase> VTContext;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D73029: E... Stephen Kelly via Phabricator via cfe-commits

Reply via email to