xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/ParentMapContext.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
15ffd83dbSDimitry Andric //===- ParentMapContext.cpp - Map of parents using DynTypedNode -*- C++ -*-===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric //
95ffd83dbSDimitry Andric // Similar to ParentMap.cpp, but generalizes to non-Stmt nodes, which can have
105ffd83dbSDimitry Andric // multiple parents.
115ffd83dbSDimitry Andric //
125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
135ffd83dbSDimitry Andric 
145ffd83dbSDimitry Andric #include "clang/AST/ParentMapContext.h"
155ffd83dbSDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
165ffd83dbSDimitry Andric #include "clang/AST/Decl.h"
175ffd83dbSDimitry Andric #include "clang/AST/Expr.h"
185ffd83dbSDimitry Andric #include "clang/AST/TemplateBase.h"
195ffd83dbSDimitry Andric 
205ffd83dbSDimitry Andric using namespace clang;
215ffd83dbSDimitry Andric 
225ffd83dbSDimitry Andric ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}
235ffd83dbSDimitry Andric 
245ffd83dbSDimitry Andric ParentMapContext::~ParentMapContext() = default;
255ffd83dbSDimitry Andric 
265ffd83dbSDimitry Andric void ParentMapContext::clear() { Parents.reset(); }
275ffd83dbSDimitry Andric 
285ffd83dbSDimitry Andric const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
295ffd83dbSDimitry Andric   return traverseIgnored(const_cast<Expr *>(E));
305ffd83dbSDimitry Andric }
315ffd83dbSDimitry Andric 
325ffd83dbSDimitry Andric Expr *ParentMapContext::traverseIgnored(Expr *E) const {
335ffd83dbSDimitry Andric   if (!E)
345ffd83dbSDimitry Andric     return nullptr;
355ffd83dbSDimitry Andric 
365ffd83dbSDimitry Andric   switch (Traversal) {
375ffd83dbSDimitry Andric   case TK_AsIs:
385ffd83dbSDimitry Andric     return E;
395ffd83dbSDimitry Andric   case TK_IgnoreUnlessSpelledInSource:
405ffd83dbSDimitry Andric     return E->IgnoreUnlessSpelledInSource();
415ffd83dbSDimitry Andric   }
425ffd83dbSDimitry Andric   llvm_unreachable("Invalid Traversal type!");
435ffd83dbSDimitry Andric }
445ffd83dbSDimitry Andric 
455ffd83dbSDimitry Andric DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
465ffd83dbSDimitry Andric   if (const auto *E = N.get<Expr>()) {
475ffd83dbSDimitry Andric     return DynTypedNode::create(*traverseIgnored(E));
485ffd83dbSDimitry Andric   }
495ffd83dbSDimitry Andric   return N;
505ffd83dbSDimitry Andric }
515ffd83dbSDimitry Andric 
525ffd83dbSDimitry Andric class ParentMapContext::ParentMap {
535ffd83dbSDimitry Andric   /// Contains parents of a node.
545ffd83dbSDimitry Andric   using ParentVector = llvm::SmallVector<DynTypedNode, 2>;
555ffd83dbSDimitry Andric 
565ffd83dbSDimitry Andric   /// Maps from a node to its parents. This is used for nodes that have
575ffd83dbSDimitry Andric   /// pointer identity only, which are more common and we can save space by
585ffd83dbSDimitry Andric   /// only storing a unique pointer to them.
595ffd83dbSDimitry Andric   using ParentMapPointers =
605ffd83dbSDimitry Andric       llvm::DenseMap<const void *,
615ffd83dbSDimitry Andric                      llvm::PointerUnion<const Decl *, const Stmt *,
625ffd83dbSDimitry Andric                                         DynTypedNode *, ParentVector *>>;
635ffd83dbSDimitry Andric 
645ffd83dbSDimitry Andric   /// Parent map for nodes without pointer identity. We store a full
655ffd83dbSDimitry Andric   /// DynTypedNode for all keys.
665ffd83dbSDimitry Andric   using ParentMapOtherNodes =
675ffd83dbSDimitry Andric       llvm::DenseMap<DynTypedNode,
685ffd83dbSDimitry Andric                      llvm::PointerUnion<const Decl *, const Stmt *,
695ffd83dbSDimitry Andric                                         DynTypedNode *, ParentVector *>>;
705ffd83dbSDimitry Andric 
715ffd83dbSDimitry Andric   ParentMapPointers PointerParents;
725ffd83dbSDimitry Andric   ParentMapOtherNodes OtherParents;
735ffd83dbSDimitry Andric   class ASTVisitor;
745ffd83dbSDimitry Andric 
755ffd83dbSDimitry Andric   static DynTypedNode
765ffd83dbSDimitry Andric   getSingleDynTypedNodeFromParentMap(ParentMapPointers::mapped_type U) {
775ffd83dbSDimitry Andric     if (const auto *D = U.dyn_cast<const Decl *>())
785ffd83dbSDimitry Andric       return DynTypedNode::create(*D);
795ffd83dbSDimitry Andric     if (const auto *S = U.dyn_cast<const Stmt *>())
805ffd83dbSDimitry Andric       return DynTypedNode::create(*S);
815ffd83dbSDimitry Andric     return *U.get<DynTypedNode *>();
825ffd83dbSDimitry Andric   }
835ffd83dbSDimitry Andric 
845ffd83dbSDimitry Andric   template <typename NodeTy, typename MapTy>
855ffd83dbSDimitry Andric   static DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
865ffd83dbSDimitry Andric                                                         const MapTy &Map) {
875ffd83dbSDimitry Andric     auto I = Map.find(Node);
885ffd83dbSDimitry Andric     if (I == Map.end()) {
895ffd83dbSDimitry Andric       return llvm::ArrayRef<DynTypedNode>();
905ffd83dbSDimitry Andric     }
915ffd83dbSDimitry Andric     if (const auto *V = I->second.template dyn_cast<ParentVector *>()) {
925ffd83dbSDimitry Andric       return llvm::makeArrayRef(*V);
935ffd83dbSDimitry Andric     }
945ffd83dbSDimitry Andric     return getSingleDynTypedNodeFromParentMap(I->second);
955ffd83dbSDimitry Andric   }
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric public:
985ffd83dbSDimitry Andric   ParentMap(ASTContext &Ctx);
995ffd83dbSDimitry Andric   ~ParentMap() {
1005ffd83dbSDimitry Andric     for (const auto &Entry : PointerParents) {
1015ffd83dbSDimitry Andric       if (Entry.second.is<DynTypedNode *>()) {
1025ffd83dbSDimitry Andric         delete Entry.second.get<DynTypedNode *>();
1035ffd83dbSDimitry Andric       } else if (Entry.second.is<ParentVector *>()) {
1045ffd83dbSDimitry Andric         delete Entry.second.get<ParentVector *>();
1055ffd83dbSDimitry Andric       }
1065ffd83dbSDimitry Andric     }
1075ffd83dbSDimitry Andric     for (const auto &Entry : OtherParents) {
1085ffd83dbSDimitry Andric       if (Entry.second.is<DynTypedNode *>()) {
1095ffd83dbSDimitry Andric         delete Entry.second.get<DynTypedNode *>();
1105ffd83dbSDimitry Andric       } else if (Entry.second.is<ParentVector *>()) {
1115ffd83dbSDimitry Andric         delete Entry.second.get<ParentVector *>();
1125ffd83dbSDimitry Andric       }
1135ffd83dbSDimitry Andric     }
1145ffd83dbSDimitry Andric   }
1155ffd83dbSDimitry Andric 
1165ffd83dbSDimitry Andric   DynTypedNodeList getParents(TraversalKind TK, const DynTypedNode &Node) {
1175ffd83dbSDimitry Andric     if (Node.getNodeKind().hasPointerIdentity()) {
1185ffd83dbSDimitry Andric       auto ParentList =
1195ffd83dbSDimitry Andric           getDynNodeFromMap(Node.getMemoizationData(), PointerParents);
1205ffd83dbSDimitry Andric       if (ParentList.size() == 1 && TK == TK_IgnoreUnlessSpelledInSource) {
1215ffd83dbSDimitry Andric         const auto *E = ParentList[0].get<Expr>();
1225ffd83dbSDimitry Andric         const auto *Child = Node.get<Expr>();
1235ffd83dbSDimitry Andric         if (E && Child)
1245ffd83dbSDimitry Andric           return AscendIgnoreUnlessSpelledInSource(E, Child);
1255ffd83dbSDimitry Andric       }
1265ffd83dbSDimitry Andric       return ParentList;
1275ffd83dbSDimitry Andric     }
1285ffd83dbSDimitry Andric     return getDynNodeFromMap(Node, OtherParents);
1295ffd83dbSDimitry Andric   }
1305ffd83dbSDimitry Andric 
1315ffd83dbSDimitry Andric   DynTypedNodeList AscendIgnoreUnlessSpelledInSource(const Expr *E,
1325ffd83dbSDimitry Andric                                                      const Expr *Child) {
1335ffd83dbSDimitry Andric 
1345ffd83dbSDimitry Andric     auto ShouldSkip = [](const Expr *E, const Expr *Child) {
1355ffd83dbSDimitry Andric       if (isa<ImplicitCastExpr>(E))
1365ffd83dbSDimitry Andric         return true;
1375ffd83dbSDimitry Andric 
1385ffd83dbSDimitry Andric       if (isa<FullExpr>(E))
1395ffd83dbSDimitry Andric         return true;
1405ffd83dbSDimitry Andric 
1415ffd83dbSDimitry Andric       if (isa<MaterializeTemporaryExpr>(E))
1425ffd83dbSDimitry Andric         return true;
1435ffd83dbSDimitry Andric 
1445ffd83dbSDimitry Andric       if (isa<CXXBindTemporaryExpr>(E))
1455ffd83dbSDimitry Andric         return true;
1465ffd83dbSDimitry Andric 
1475ffd83dbSDimitry Andric       if (isa<ParenExpr>(E))
1485ffd83dbSDimitry Andric         return true;
1495ffd83dbSDimitry Andric 
1505ffd83dbSDimitry Andric       if (isa<ExprWithCleanups>(E))
1515ffd83dbSDimitry Andric         return true;
1525ffd83dbSDimitry Andric 
1535ffd83dbSDimitry Andric       auto SR = Child->getSourceRange();
1545ffd83dbSDimitry Andric 
155*e8d8bef9SDimitry Andric       if (const auto *C = dyn_cast<CXXFunctionalCastExpr>(E)) {
156*e8d8bef9SDimitry Andric         if (C->getSourceRange() == SR)
157*e8d8bef9SDimitry Andric           return true;
158*e8d8bef9SDimitry Andric       }
159*e8d8bef9SDimitry Andric 
1605ffd83dbSDimitry Andric       if (const auto *C = dyn_cast<CXXConstructExpr>(E)) {
161*e8d8bef9SDimitry Andric         if (C->getSourceRange() == SR || C->isElidable())
1625ffd83dbSDimitry Andric           return true;
1635ffd83dbSDimitry Andric       }
1645ffd83dbSDimitry Andric 
1655ffd83dbSDimitry Andric       if (const auto *C = dyn_cast<CXXMemberCallExpr>(E)) {
1665ffd83dbSDimitry Andric         if (C->getSourceRange() == SR)
1675ffd83dbSDimitry Andric           return true;
1685ffd83dbSDimitry Andric       }
1695ffd83dbSDimitry Andric 
1705ffd83dbSDimitry Andric       if (const auto *C = dyn_cast<MemberExpr>(E)) {
1715ffd83dbSDimitry Andric         if (C->getSourceRange() == SR)
1725ffd83dbSDimitry Andric           return true;
1735ffd83dbSDimitry Andric       }
1745ffd83dbSDimitry Andric       return false;
1755ffd83dbSDimitry Andric     };
1765ffd83dbSDimitry Andric 
1775ffd83dbSDimitry Andric     while (ShouldSkip(E, Child)) {
1785ffd83dbSDimitry Andric       auto It = PointerParents.find(E);
1795ffd83dbSDimitry Andric       if (It == PointerParents.end())
1805ffd83dbSDimitry Andric         break;
1815ffd83dbSDimitry Andric       const auto *S = It->second.dyn_cast<const Stmt *>();
1825ffd83dbSDimitry Andric       if (!S) {
1835ffd83dbSDimitry Andric         if (auto *Vec = It->second.dyn_cast<ParentVector *>())
1845ffd83dbSDimitry Andric           return llvm::makeArrayRef(*Vec);
1855ffd83dbSDimitry Andric         return getSingleDynTypedNodeFromParentMap(It->second);
1865ffd83dbSDimitry Andric       }
1875ffd83dbSDimitry Andric       const auto *P = dyn_cast<Expr>(S);
1885ffd83dbSDimitry Andric       if (!P)
1895ffd83dbSDimitry Andric         return DynTypedNode::create(*S);
1905ffd83dbSDimitry Andric       Child = E;
1915ffd83dbSDimitry Andric       E = P;
1925ffd83dbSDimitry Andric     }
1935ffd83dbSDimitry Andric     return DynTypedNode::create(*E);
1945ffd83dbSDimitry Andric   }
1955ffd83dbSDimitry Andric };
1965ffd83dbSDimitry Andric 
1975ffd83dbSDimitry Andric /// Template specializations to abstract away from pointers and TypeLocs.
1985ffd83dbSDimitry Andric /// @{
1995ffd83dbSDimitry Andric template <typename T> static DynTypedNode createDynTypedNode(const T &Node) {
2005ffd83dbSDimitry Andric   return DynTypedNode::create(*Node);
2015ffd83dbSDimitry Andric }
2025ffd83dbSDimitry Andric template <> DynTypedNode createDynTypedNode(const TypeLoc &Node) {
2035ffd83dbSDimitry Andric   return DynTypedNode::create(Node);
2045ffd83dbSDimitry Andric }
2055ffd83dbSDimitry Andric template <>
2065ffd83dbSDimitry Andric DynTypedNode createDynTypedNode(const NestedNameSpecifierLoc &Node) {
2075ffd83dbSDimitry Andric   return DynTypedNode::create(Node);
2085ffd83dbSDimitry Andric }
2095ffd83dbSDimitry Andric /// @}
2105ffd83dbSDimitry Andric 
2115ffd83dbSDimitry Andric /// A \c RecursiveASTVisitor that builds a map from nodes to their
2125ffd83dbSDimitry Andric /// parents as defined by the \c RecursiveASTVisitor.
2135ffd83dbSDimitry Andric ///
2145ffd83dbSDimitry Andric /// Note that the relationship described here is purely in terms of AST
2155ffd83dbSDimitry Andric /// traversal - there are other relationships (for example declaration context)
2165ffd83dbSDimitry Andric /// in the AST that are better modeled by special matchers.
2175ffd83dbSDimitry Andric class ParentMapContext::ParentMap::ASTVisitor
2185ffd83dbSDimitry Andric     : public RecursiveASTVisitor<ASTVisitor> {
2195ffd83dbSDimitry Andric public:
2205ffd83dbSDimitry Andric   ASTVisitor(ParentMap &Map) : Map(Map) {}
2215ffd83dbSDimitry Andric 
2225ffd83dbSDimitry Andric private:
2235ffd83dbSDimitry Andric   friend class RecursiveASTVisitor<ASTVisitor>;
2245ffd83dbSDimitry Andric 
2255ffd83dbSDimitry Andric   using VisitorBase = RecursiveASTVisitor<ASTVisitor>;
2265ffd83dbSDimitry Andric 
2275ffd83dbSDimitry Andric   bool shouldVisitTemplateInstantiations() const { return true; }
2285ffd83dbSDimitry Andric 
2295ffd83dbSDimitry Andric   bool shouldVisitImplicitCode() const { return true; }
2305ffd83dbSDimitry Andric 
231*e8d8bef9SDimitry Andric   /// Record the parent of the node we're visiting.
232*e8d8bef9SDimitry Andric   /// MapNode is the child, the parent is on top of ParentStack.
233*e8d8bef9SDimitry Andric   /// Parents is the parent storage (either PointerParents or OtherParents).
234*e8d8bef9SDimitry Andric   template <typename MapNodeTy, typename MapTy>
235*e8d8bef9SDimitry Andric   void addParent(MapNodeTy MapNode, MapTy *Parents) {
236*e8d8bef9SDimitry Andric     if (ParentStack.empty())
237*e8d8bef9SDimitry Andric       return;
238*e8d8bef9SDimitry Andric 
2395ffd83dbSDimitry Andric     // FIXME: Currently we add the same parent multiple times, but only
2405ffd83dbSDimitry Andric     // when no memoization data is available for the type.
2415ffd83dbSDimitry Andric     // For example when we visit all subexpressions of template
2425ffd83dbSDimitry Andric     // instantiations; this is suboptimal, but benign: the only way to
2435ffd83dbSDimitry Andric     // visit those is with hasAncestor / hasParent, and those do not create
2445ffd83dbSDimitry Andric     // new matches.
2455ffd83dbSDimitry Andric     // The plan is to enable DynTypedNode to be storable in a map or hash
2465ffd83dbSDimitry Andric     // map. The main problem there is to implement hash functions /
2475ffd83dbSDimitry Andric     // comparison operators for all types that DynTypedNode supports that
2485ffd83dbSDimitry Andric     // do not have pointer identity.
2495ffd83dbSDimitry Andric     auto &NodeOrVector = (*Parents)[MapNode];
2505ffd83dbSDimitry Andric     if (NodeOrVector.isNull()) {
2515ffd83dbSDimitry Andric       if (const auto *D = ParentStack.back().get<Decl>())
2525ffd83dbSDimitry Andric         NodeOrVector = D;
2535ffd83dbSDimitry Andric       else if (const auto *S = ParentStack.back().get<Stmt>())
2545ffd83dbSDimitry Andric         NodeOrVector = S;
2555ffd83dbSDimitry Andric       else
2565ffd83dbSDimitry Andric         NodeOrVector = new DynTypedNode(ParentStack.back());
2575ffd83dbSDimitry Andric     } else {
2585ffd83dbSDimitry Andric       if (!NodeOrVector.template is<ParentVector *>()) {
2595ffd83dbSDimitry Andric         auto *Vector = new ParentVector(
2605ffd83dbSDimitry Andric             1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
2615ffd83dbSDimitry Andric         delete NodeOrVector.template dyn_cast<DynTypedNode *>();
2625ffd83dbSDimitry Andric         NodeOrVector = Vector;
2635ffd83dbSDimitry Andric       }
2645ffd83dbSDimitry Andric 
2655ffd83dbSDimitry Andric       auto *Vector = NodeOrVector.template get<ParentVector *>();
2665ffd83dbSDimitry Andric       // Skip duplicates for types that have memoization data.
2675ffd83dbSDimitry Andric       // We must check that the type has memoization data before calling
2685ffd83dbSDimitry Andric       // std::find() because DynTypedNode::operator== can't compare all
2695ffd83dbSDimitry Andric       // types.
2705ffd83dbSDimitry Andric       bool Found = ParentStack.back().getMemoizationData() &&
2715ffd83dbSDimitry Andric                    std::find(Vector->begin(), Vector->end(),
2725ffd83dbSDimitry Andric                              ParentStack.back()) != Vector->end();
2735ffd83dbSDimitry Andric       if (!Found)
2745ffd83dbSDimitry Andric         Vector->push_back(ParentStack.back());
2755ffd83dbSDimitry Andric     }
2765ffd83dbSDimitry Andric   }
277*e8d8bef9SDimitry Andric 
278*e8d8bef9SDimitry Andric   template <typename T, typename MapNodeTy, typename BaseTraverseFn,
279*e8d8bef9SDimitry Andric             typename MapTy>
280*e8d8bef9SDimitry Andric   bool TraverseNode(T Node, MapNodeTy MapNode, BaseTraverseFn BaseTraverse,
281*e8d8bef9SDimitry Andric                     MapTy *Parents) {
282*e8d8bef9SDimitry Andric     if (!Node)
283*e8d8bef9SDimitry Andric       return true;
284*e8d8bef9SDimitry Andric     addParent(MapNode, Parents);
2855ffd83dbSDimitry Andric     ParentStack.push_back(createDynTypedNode(Node));
2865ffd83dbSDimitry Andric     bool Result = BaseTraverse();
2875ffd83dbSDimitry Andric     ParentStack.pop_back();
2885ffd83dbSDimitry Andric     return Result;
2895ffd83dbSDimitry Andric   }
2905ffd83dbSDimitry Andric 
2915ffd83dbSDimitry Andric   bool TraverseDecl(Decl *DeclNode) {
2925ffd83dbSDimitry Andric     return TraverseNode(
2935ffd83dbSDimitry Andric         DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); },
2945ffd83dbSDimitry Andric         &Map.PointerParents);
2955ffd83dbSDimitry Andric   }
2965ffd83dbSDimitry Andric   bool TraverseTypeLoc(TypeLoc TypeLocNode) {
2975ffd83dbSDimitry Andric     return TraverseNode(
2985ffd83dbSDimitry Andric         TypeLocNode, DynTypedNode::create(TypeLocNode),
2995ffd83dbSDimitry Andric         [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
3005ffd83dbSDimitry Andric         &Map.OtherParents);
3015ffd83dbSDimitry Andric   }
3025ffd83dbSDimitry Andric   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
3035ffd83dbSDimitry Andric     return TraverseNode(
3045ffd83dbSDimitry Andric         NNSLocNode, DynTypedNode::create(NNSLocNode),
3055ffd83dbSDimitry Andric         [&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
3065ffd83dbSDimitry Andric         &Map.OtherParents);
3075ffd83dbSDimitry Andric   }
3085ffd83dbSDimitry Andric 
309*e8d8bef9SDimitry Andric   // Using generic TraverseNode for Stmt would prevent data-recursion.
310*e8d8bef9SDimitry Andric   bool dataTraverseStmtPre(Stmt *StmtNode) {
311*e8d8bef9SDimitry Andric     addParent(StmtNode, &Map.PointerParents);
312*e8d8bef9SDimitry Andric     ParentStack.push_back(DynTypedNode::create(*StmtNode));
313*e8d8bef9SDimitry Andric     return true;
314*e8d8bef9SDimitry Andric   }
315*e8d8bef9SDimitry Andric   bool dataTraverseStmtPost(Stmt *StmtNode) {
316*e8d8bef9SDimitry Andric     ParentStack.pop_back();
317*e8d8bef9SDimitry Andric     return true;
318*e8d8bef9SDimitry Andric   }
319*e8d8bef9SDimitry Andric 
3205ffd83dbSDimitry Andric   ParentMap &Map;
3215ffd83dbSDimitry Andric   llvm::SmallVector<DynTypedNode, 16> ParentStack;
3225ffd83dbSDimitry Andric };
3235ffd83dbSDimitry Andric 
3245ffd83dbSDimitry Andric ParentMapContext::ParentMap::ParentMap(ASTContext &Ctx) {
3255ffd83dbSDimitry Andric   ASTVisitor(*this).TraverseAST(Ctx);
3265ffd83dbSDimitry Andric }
3275ffd83dbSDimitry Andric 
3285ffd83dbSDimitry Andric DynTypedNodeList ParentMapContext::getParents(const DynTypedNode &Node) {
3295ffd83dbSDimitry Andric   if (!Parents)
3305ffd83dbSDimitry Andric     // We build the parent map for the traversal scope (usually whole TU), as
3315ffd83dbSDimitry Andric     // hasAncestor can escape any subtree.
3325ffd83dbSDimitry Andric     Parents = std::make_unique<ParentMap>(ASTCtx);
3335ffd83dbSDimitry Andric   return Parents->getParents(getTraversalKind(), Node);
3345ffd83dbSDimitry Andric }
335