Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/AST/ParentMapContext.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ParentMapContext.cpp - Map of parents using DynTypedNode -*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Similar to ParentMap.cpp, but generalizes to non-Stmt nodes, which can have
10
// multiple parents.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/ParentMapContext.h"
15
#include "clang/AST/RecursiveASTVisitor.h"
16
#include "clang/AST/Decl.h"
17
#include "clang/AST/Expr.h"
18
#include "clang/AST/TemplateBase.h"
19
20
using namespace clang;
21
22
0
ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}
23
24
0
ParentMapContext::~ParentMapContext() = default;
25
26
0
void ParentMapContext::clear() { Parents.reset(); }
27
28
0
const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
29
0
  return traverseIgnored(const_cast<Expr *>(E));
30
0
}
31
32
0
Expr *ParentMapContext::traverseIgnored(Expr *E) const {
33
0
  if (!E)
34
0
    return nullptr;
35
36
0
  switch (Traversal) {
37
0
  case TK_AsIs:
38
0
    return E;
39
0
  case TK_IgnoreUnlessSpelledInSource:
40
0
    return E->IgnoreUnlessSpelledInSource();
41
0
  }
42
0
  llvm_unreachable("Invalid Traversal type!");
43
0
}
44
45
0
DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
46
0
  if (const auto *E = N.get<Expr>()) {
47
0
    return DynTypedNode::create(*traverseIgnored(E));
48
0
  }
49
0
  return N;
50
0
}
51
52
template <typename T, typename... U>
53
std::tuple<bool, DynTypedNodeList, const T *, const U *...>
54
matchParents(const DynTypedNodeList &NodeList,
55
             ParentMapContext::ParentMap *ParentMap);
56
57
template <typename, typename...> struct MatchParents;
58
59
class ParentMapContext::ParentMap {
60
61
  template <typename, typename...> friend struct ::MatchParents;
62
63
  /// Contains parents of a node.
64
  using ParentVector = llvm::SmallVector<DynTypedNode, 2>;
65
66
  /// Maps from a node to its parents. This is used for nodes that have
67
  /// pointer identity only, which are more common and we can save space by
68
  /// only storing a unique pointer to them.
69
  using ParentMapPointers =
70
      llvm::DenseMap<const void *,
71
                     llvm::PointerUnion<const Decl *, const Stmt *,
72
                                        DynTypedNode *, ParentVector *>>;
73
74
  /// Parent map for nodes without pointer identity. We store a full
75
  /// DynTypedNode for all keys.
76
  using ParentMapOtherNodes =
77
      llvm::DenseMap<DynTypedNode,
78
                     llvm::PointerUnion<const Decl *, const Stmt *,
79
                                        DynTypedNode *, ParentVector *>>;
80
81
  ParentMapPointers PointerParents;
82
  ParentMapOtherNodes OtherParents;
83
  class ASTVisitor;
84
85
  static DynTypedNode
86
0
  getSingleDynTypedNodeFromParentMap(ParentMapPointers::mapped_type U) {
87
0
    if (const auto *D = U.dyn_cast<const Decl *>())
88
0
      return DynTypedNode::create(*D);
89
0
    if (const auto *S = U.dyn_cast<const Stmt *>())
90
0
      return DynTypedNode::create(*S);
91
0
    return *U.get<DynTypedNode *>();
92
0
  }
93
94
  template <typename NodeTy, typename MapTy>
95
  static DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
96
0
                                                        const MapTy &Map) {
97
0
    auto I = Map.find(Node);
98
0
    if (I == Map.end()) {
99
0
      return llvm::ArrayRef<DynTypedNode>();
100
0
    }
101
0
    if (const auto *V = I->second.template dyn_cast<ParentVector *>()) {
102
0
      return llvm::ArrayRef(*V);
103
0
    }
104
0
    return getSingleDynTypedNodeFromParentMap(I->second);
105
0
  }
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<void const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(void const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::Stmt const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::Stmt const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::DeclStmt const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::DeclStmt const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::CXXForRangeStmt const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::CXXForRangeStmt const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::VarDecl const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::VarDecl const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::CXXMethodDecl const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::CXXMethodDecl const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::CXXRecordDecl const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::CXXRecordDecl const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::LambdaExpr const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::LambdaExpr const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::FunctionTemplateDecl const*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::FunctionTemplateDecl const* const&, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
Unexecuted instantiation: clang::DynTypedNodeList clang::ParentMapContext::ParentMap::getDynNodeFromMap<clang::DynTypedNode, llvm::DenseMap<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<clang::DynTypedNode, void>, llvm::detail::DenseMapPair<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::DynTypedNode const&, llvm::DenseMap<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<clang::DynTypedNode, void>, llvm::detail::DenseMapPair<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > const&)
106
107
public:
108
  ParentMap(ASTContext &Ctx);
109
0
  ~ParentMap() {
110
0
    for (const auto &Entry : PointerParents) {
111
0
      if (Entry.second.is<DynTypedNode *>()) {
112
0
        delete Entry.second.get<DynTypedNode *>();
113
0
      } else if (Entry.second.is<ParentVector *>()) {
114
0
        delete Entry.second.get<ParentVector *>();
115
0
      }
116
0
    }
117
0
    for (const auto &Entry : OtherParents) {
118
0
      if (Entry.second.is<DynTypedNode *>()) {
119
0
        delete Entry.second.get<DynTypedNode *>();
120
0
      } else if (Entry.second.is<ParentVector *>()) {
121
0
        delete Entry.second.get<ParentVector *>();
122
0
      }
123
0
    }
124
0
  }
125
126
0
  DynTypedNodeList getParents(TraversalKind TK, const DynTypedNode &Node) {
127
0
    if (Node.getNodeKind().hasPointerIdentity()) {
128
0
      auto ParentList =
129
0
          getDynNodeFromMap(Node.getMemoizationData(), PointerParents);
130
0
      if (ParentList.size() > 0 && TK == TK_IgnoreUnlessSpelledInSource) {
131
132
0
        const auto *ChildExpr = Node.get<Expr>();
133
134
0
        {
135
          // Don't match explicit node types because different stdlib
136
          // implementations implement this in different ways and have
137
          // different intermediate nodes.
138
          // Look up 4 levels for a cxxRewrittenBinaryOperator as that is
139
          // enough for the major stdlib implementations.
140
0
          auto RewrittenBinOpParentsList = ParentList;
141
0
          int I = 0;
142
0
          while (ChildExpr && RewrittenBinOpParentsList.size() == 1 &&
143
0
                 I++ < 4) {
144
0
            const auto *S = RewrittenBinOpParentsList[0].get<Stmt>();
145
0
            if (!S)
146
0
              break;
147
148
0
            const auto *RWBO = dyn_cast<CXXRewrittenBinaryOperator>(S);
149
0
            if (!RWBO) {
150
0
              RewrittenBinOpParentsList = getDynNodeFromMap(S, PointerParents);
151
0
              continue;
152
0
            }
153
0
            if (RWBO->getLHS()->IgnoreUnlessSpelledInSource() != ChildExpr &&
154
0
                RWBO->getRHS()->IgnoreUnlessSpelledInSource() != ChildExpr)
155
0
              break;
156
0
            return DynTypedNode::create(*RWBO);
157
0
          }
158
0
        }
159
160
0
        const auto *ParentExpr = ParentList[0].get<Expr>();
161
0
        if (ParentExpr && ChildExpr)
162
0
          return AscendIgnoreUnlessSpelledInSource(ParentExpr, ChildExpr);
163
164
0
        {
165
0
          auto AncestorNodes =
166
0
              matchParents<DeclStmt, CXXForRangeStmt>(ParentList, this);
167
0
          if (std::get<bool>(AncestorNodes) &&
168
0
              std::get<const CXXForRangeStmt *>(AncestorNodes)
169
0
                      ->getLoopVarStmt() ==
170
0
                  std::get<const DeclStmt *>(AncestorNodes))
171
0
            return std::get<DynTypedNodeList>(AncestorNodes);
172
0
        }
173
0
        {
174
0
          auto AncestorNodes = matchParents<VarDecl, DeclStmt, CXXForRangeStmt>(
175
0
              ParentList, this);
176
0
          if (std::get<bool>(AncestorNodes) &&
177
0
              std::get<const CXXForRangeStmt *>(AncestorNodes)
178
0
                      ->getRangeStmt() ==
179
0
                  std::get<const DeclStmt *>(AncestorNodes))
180
0
            return std::get<DynTypedNodeList>(AncestorNodes);
181
0
        }
182
0
        {
183
0
          auto AncestorNodes =
184
0
              matchParents<CXXMethodDecl, CXXRecordDecl, LambdaExpr>(ParentList,
185
0
                                                                     this);
186
0
          if (std::get<bool>(AncestorNodes))
187
0
            return std::get<DynTypedNodeList>(AncestorNodes);
188
0
        }
189
0
        {
190
0
          auto AncestorNodes =
191
0
              matchParents<FunctionTemplateDecl, CXXRecordDecl, LambdaExpr>(
192
0
                  ParentList, this);
193
0
          if (std::get<bool>(AncestorNodes))
194
0
            return std::get<DynTypedNodeList>(AncestorNodes);
195
0
        }
196
0
      }
197
0
      return ParentList;
198
0
    }
199
0
    return getDynNodeFromMap(Node, OtherParents);
200
0
  }
201
202
  DynTypedNodeList AscendIgnoreUnlessSpelledInSource(const Expr *E,
203
0
                                                     const Expr *Child) {
204
205
0
    auto ShouldSkip = [](const Expr *E, const Expr *Child) {
206
0
      if (isa<ImplicitCastExpr>(E))
207
0
        return true;
208
209
0
      if (isa<FullExpr>(E))
210
0
        return true;
211
212
0
      if (isa<MaterializeTemporaryExpr>(E))
213
0
        return true;
214
215
0
      if (isa<CXXBindTemporaryExpr>(E))
216
0
        return true;
217
218
0
      if (isa<ParenExpr>(E))
219
0
        return true;
220
221
0
      if (isa<ExprWithCleanups>(E))
222
0
        return true;
223
224
0
      auto SR = Child->getSourceRange();
225
226
0
      if (const auto *C = dyn_cast<CXXFunctionalCastExpr>(E)) {
227
0
        if (C->getSourceRange() == SR)
228
0
          return true;
229
0
      }
230
231
0
      if (const auto *C = dyn_cast<CXXConstructExpr>(E)) {
232
0
        if (C->getSourceRange() == SR || C->isElidable())
233
0
          return true;
234
0
      }
235
236
0
      if (const auto *C = dyn_cast<CXXMemberCallExpr>(E)) {
237
0
        if (C->getSourceRange() == SR)
238
0
          return true;
239
0
      }
240
241
0
      if (const auto *C = dyn_cast<MemberExpr>(E)) {
242
0
        if (C->getSourceRange() == SR)
243
0
          return true;
244
0
      }
245
0
      return false;
246
0
    };
247
248
0
    while (ShouldSkip(E, Child)) {
249
0
      auto It = PointerParents.find(E);
250
0
      if (It == PointerParents.end())
251
0
        break;
252
0
      const auto *S = It->second.dyn_cast<const Stmt *>();
253
0
      if (!S) {
254
0
        if (auto *Vec = It->second.dyn_cast<ParentVector *>())
255
0
          return llvm::ArrayRef(*Vec);
256
0
        return getSingleDynTypedNodeFromParentMap(It->second);
257
0
      }
258
0
      const auto *P = dyn_cast<Expr>(S);
259
0
      if (!P)
260
0
        return DynTypedNode::create(*S);
261
0
      Child = E;
262
0
      E = P;
263
0
    }
264
0
    return DynTypedNode::create(*E);
265
0
  }
266
};
267
268
template <typename T, typename... U> struct MatchParents {
269
  static std::tuple<bool, DynTypedNodeList, const T *, const U *...>
270
  match(const DynTypedNodeList &NodeList,
271
0
        ParentMapContext::ParentMap *ParentMap) {
272
0
    if (const auto *TypedNode = NodeList[0].get<T>()) {
273
0
      auto NextParentList =
274
0
          ParentMap->getDynNodeFromMap(TypedNode, ParentMap->PointerParents);
275
0
      if (NextParentList.size() == 1) {
276
0
        auto TailTuple = MatchParents<U...>::match(NextParentList, ParentMap);
277
0
        if (std::get<bool>(TailTuple)) {
278
0
          return std::apply(
279
0
              [TypedNode](bool, DynTypedNodeList NodeList, auto... TupleTail) {
280
0
                return std::make_tuple(true, NodeList, TypedNode, TupleTail...);
281
0
              },
Unexecuted instantiation: _ZZN12MatchParentsIN5clang8DeclStmtEJNS0_15CXXForRangeStmtEEE5matchERKNS0_16DynTypedNodeListEPNS0_16ParentMapContext9ParentMapEENKUlbS4_DpT_E_clIJPKS2_EEEDabS4_SB_
Unexecuted instantiation: _ZZN12MatchParentsIN5clang7VarDeclEJNS0_8DeclStmtENS0_15CXXForRangeStmtEEE5matchERKNS0_16DynTypedNodeListEPNS0_16ParentMapContext9ParentMapEENKUlbS5_DpT_E_clIJPKS2_PKS3_EEEDabS5_SC_
Unexecuted instantiation: _ZZN12MatchParentsIN5clang13CXXRecordDeclEJNS0_10LambdaExprEEE5matchERKNS0_16DynTypedNodeListEPNS0_16ParentMapContext9ParentMapEENKUlbS4_DpT_E_clIJPKS2_EEEDabS4_SB_
Unexecuted instantiation: _ZZN12MatchParentsIN5clang13CXXMethodDeclEJNS0_13CXXRecordDeclENS0_10LambdaExprEEE5matchERKNS0_16DynTypedNodeListEPNS0_16ParentMapContext9ParentMapEENKUlbS5_DpT_E_clIJPKS2_PKS3_EEEDabS5_SC_
Unexecuted instantiation: _ZZN12MatchParentsIN5clang20FunctionTemplateDeclEJNS0_13CXXRecordDeclENS0_10LambdaExprEEE5matchERKNS0_16DynTypedNodeListEPNS0_16ParentMapContext9ParentMapEENKUlbS5_DpT_E_clIJPKS2_PKS3_EEEDabS5_SC_
282
0
              TailTuple);
283
0
        }
284
0
      }
285
0
    }
286
0
    return std::tuple_cat(std::make_tuple(false, NodeList),
287
0
                          std::tuple<const T *, const U *...>());
288
0
  }
Unexecuted instantiation: MatchParents<clang::DeclStmt, clang::CXXForRangeStmt>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: MatchParents<clang::VarDecl, clang::DeclStmt, clang::CXXForRangeStmt>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: MatchParents<clang::CXXMethodDecl, clang::CXXRecordDecl, clang::LambdaExpr>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: MatchParents<clang::CXXRecordDecl, clang::LambdaExpr>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: MatchParents<clang::FunctionTemplateDecl, clang::CXXRecordDecl, clang::LambdaExpr>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
289
};
290
291
template <typename T> struct MatchParents<T> {
292
  static std::tuple<bool, DynTypedNodeList, const T *>
293
  match(const DynTypedNodeList &NodeList,
294
0
        ParentMapContext::ParentMap *ParentMap) {
295
0
    if (const auto *TypedNode = NodeList[0].get<T>()) {
296
0
      auto NextParentList =
297
0
          ParentMap->getDynNodeFromMap(TypedNode, ParentMap->PointerParents);
298
0
      if (NextParentList.size() == 1)
299
0
        return std::make_tuple(true, NodeList, TypedNode);
300
0
    }
301
0
    return std::make_tuple(false, NodeList, nullptr);
302
0
  }
Unexecuted instantiation: MatchParents<clang::CXXForRangeStmt>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: MatchParents<clang::LambdaExpr>::match(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
303
};
304
305
template <typename T, typename... U>
306
std::tuple<bool, DynTypedNodeList, const T *, const U *...>
307
matchParents(const DynTypedNodeList &NodeList,
308
0
             ParentMapContext::ParentMap *ParentMap) {
309
0
  return MatchParents<T, U...>::match(NodeList, ParentMap);
310
0
}
Unexecuted instantiation: std::__1::tuple<bool, clang::DynTypedNodeList, clang::DeclStmt const*, clang::CXXForRangeStmt const*> matchParents<clang::DeclStmt, clang::CXXForRangeStmt>(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: std::__1::tuple<bool, clang::DynTypedNodeList, clang::VarDecl const*, clang::DeclStmt const*, clang::CXXForRangeStmt const*> matchParents<clang::VarDecl, clang::DeclStmt, clang::CXXForRangeStmt>(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: std::__1::tuple<bool, clang::DynTypedNodeList, clang::CXXMethodDecl const*, clang::CXXRecordDecl const*, clang::LambdaExpr const*> matchParents<clang::CXXMethodDecl, clang::CXXRecordDecl, clang::LambdaExpr>(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
Unexecuted instantiation: std::__1::tuple<bool, clang::DynTypedNodeList, clang::FunctionTemplateDecl const*, clang::CXXRecordDecl const*, clang::LambdaExpr const*> matchParents<clang::FunctionTemplateDecl, clang::CXXRecordDecl, clang::LambdaExpr>(clang::DynTypedNodeList const&, clang::ParentMapContext::ParentMap*)
311
312
/// Template specializations to abstract away from pointers and TypeLocs.
313
/// @{
314
0
template <typename T> static DynTypedNode createDynTypedNode(const T &Node) {
315
0
  return DynTypedNode::create(*Node);
316
0
}
Unexecuted instantiation: ParentMapContext.cpp:clang::DynTypedNode createDynTypedNode<clang::Decl*>(clang::Decl* const&)
Unexecuted instantiation: ParentMapContext.cpp:clang::DynTypedNode createDynTypedNode<clang::Attr*>(clang::Attr* const&)
317
0
template <> DynTypedNode createDynTypedNode(const TypeLoc &Node) {
318
0
  return DynTypedNode::create(Node);
319
0
}
320
template <>
321
0
DynTypedNode createDynTypedNode(const NestedNameSpecifierLoc &Node) {
322
0
  return DynTypedNode::create(Node);
323
0
}
324
0
template <> DynTypedNode createDynTypedNode(const ObjCProtocolLoc &Node) {
325
0
  return DynTypedNode::create(Node);
326
0
}
327
/// @}
328
329
/// A \c RecursiveASTVisitor that builds a map from nodes to their
330
/// parents as defined by the \c RecursiveASTVisitor.
331
///
332
/// Note that the relationship described here is purely in terms of AST
333
/// traversal - there are other relationships (for example declaration context)
334
/// in the AST that are better modeled by special matchers.
335
class ParentMapContext::ParentMap::ASTVisitor
336
    : public RecursiveASTVisitor<ASTVisitor> {
337
public:
338
0
  ASTVisitor(ParentMap &Map) : Map(Map) {}
339
340
private:
341
  friend class RecursiveASTVisitor<ASTVisitor>;
342
343
  using VisitorBase = RecursiveASTVisitor<ASTVisitor>;
344
345
0
  bool shouldVisitTemplateInstantiations() const { return true; }
346
347
0
  bool shouldVisitImplicitCode() const { return true; }
348
349
  /// Record the parent of the node we're visiting.
350
  /// MapNode is the child, the parent is on top of ParentStack.
351
  /// Parents is the parent storage (either PointerParents or OtherParents).
352
  template <typename MapNodeTy, typename MapTy>
353
0
  void addParent(MapNodeTy MapNode, MapTy *Parents) {
354
0
    if (ParentStack.empty())
355
0
      return;
356
357
    // FIXME: Currently we add the same parent multiple times, but only
358
    // when no memoization data is available for the type.
359
    // For example when we visit all subexpressions of template
360
    // instantiations; this is suboptimal, but benign: the only way to
361
    // visit those is with hasAncestor / hasParent, and those do not create
362
    // new matches.
363
    // The plan is to enable DynTypedNode to be storable in a map or hash
364
    // map. The main problem there is to implement hash functions /
365
    // comparison operators for all types that DynTypedNode supports that
366
    // do not have pointer identity.
367
0
    auto &NodeOrVector = (*Parents)[MapNode];
368
0
    if (NodeOrVector.isNull()) {
369
0
      if (const auto *D = ParentStack.back().get<Decl>())
370
0
        NodeOrVector = D;
371
0
      else if (const auto *S = ParentStack.back().get<Stmt>())
372
0
        NodeOrVector = S;
373
0
      else
374
0
        NodeOrVector = new DynTypedNode(ParentStack.back());
375
0
    } else {
376
0
      if (!NodeOrVector.template is<ParentVector *>()) {
377
0
        auto *Vector = new ParentVector(
378
0
            1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
379
0
        delete NodeOrVector.template dyn_cast<DynTypedNode *>();
380
0
        NodeOrVector = Vector;
381
0
      }
382
383
0
      auto *Vector = NodeOrVector.template get<ParentVector *>();
384
      // Skip duplicates for types that have memoization data.
385
      // We must check that the type has memoization data before calling
386
      // llvm::is_contained() because DynTypedNode::operator== can't compare all
387
      // types.
388
0
      bool Found = ParentStack.back().getMemoizationData() &&
389
0
                   llvm::is_contained(*Vector, ParentStack.back());
390
0
      if (!Found)
391
0
        Vector->push_back(ParentStack.back());
392
0
    }
393
0
  }
Unexecuted instantiation: void clang::ParentMapContext::ParentMap::ASTVisitor::addParent<clang::Decl*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::Decl*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > >*)
Unexecuted instantiation: void clang::ParentMapContext::ParentMap::ASTVisitor::addParent<clang::DynTypedNode, llvm::DenseMap<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<clang::DynTypedNode, void>, llvm::detail::DenseMapPair<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::DynTypedNode, llvm::DenseMap<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<clang::DynTypedNode, void>, llvm::detail::DenseMapPair<clang::DynTypedNode, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > >*)
Unexecuted instantiation: void clang::ParentMapContext::ParentMap::ASTVisitor::addParent<clang::Stmt*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::Stmt*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > >*)
Unexecuted instantiation: void clang::ParentMapContext::ParentMap::ASTVisitor::addParent<clang::Attr*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > > >(clang::Attr*, llvm::DenseMap<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*>, llvm::DenseMapInfo<void const*, void>, llvm::detail::DenseMapPair<void const*, llvm::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, llvm::SmallVector<clang::DynTypedNode, 2u>*> > >*)
394
395
0
  template <typename T> static bool isNull(T Node) { return !Node; }
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::isNull<clang::Decl*>(clang::Decl*)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::isNull<clang::NestedNameSpecifierLoc>(clang::NestedNameSpecifierLoc)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::isNull<clang::TypeLoc>(clang::TypeLoc)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::isNull<clang::Attr*>(clang::Attr*)
396
0
  static bool isNull(ObjCProtocolLoc Node) { return false; }
397
398
  template <typename T, typename MapNodeTy, typename BaseTraverseFn,
399
            typename MapTy>
400
  bool TraverseNode(T Node, MapNodeTy MapNode, BaseTraverseFn BaseTraverse,
401
0
                    MapTy *Parents) {
402
0
    if (isNull(Node))
403
0
      return true;
404
0
    addParent(MapNode, Parents);
405
0
    ParentStack.push_back(createDynTypedNode(Node));
406
0
    bool Result = BaseTraverse();
407
0
    ParentStack.pop_back();
408
0
    return Result;
409
0
  }
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNode<clang::Decl*, clang::Decl*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}, llvm::DenseMap<void const*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::DenseMapInfo<void const, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::detail::DenseMapPair<void const, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*> > >(clang::Decl*, clang::Decl*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}, llvm::DenseMap<void const*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::DenseMapInfo<void const, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::detail::DenseMapPair<void const, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseDecl(clang::Decl*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*> >*)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNode<clang::NestedNameSpecifierLoc, clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}, llvm::DenseMap<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::DenseMapInfo<clang::DynTypedNode, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::detail::DenseMapPair<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*> > >(clang::NestedNameSpecifierLoc, clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}, llvm::DenseMap<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::DenseMapInfo<clang::DynTypedNode, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::detail::DenseMapPair<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*> >*)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNode<clang::TypeLoc, clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}, llvm::DenseMap<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::DenseMapInfo<clang::DynTypedNode, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::detail::DenseMapPair<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*> > >(clang::TypeLoc, clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}, llvm::DenseMap<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::DenseMapInfo<clang::DynTypedNode, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::detail::DenseMapPair<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseTypeLoc(clang::TypeLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*> >*)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNode<clang::ObjCProtocolLoc, clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}, llvm::DenseMap<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::DenseMapInfo<clang::DynTypedNode, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::detail::DenseMapPair<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*> > >(clang::ObjCProtocolLoc, clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}, llvm::DenseMap<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::DenseMapInfo<clang::DynTypedNode, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::detail::DenseMapPair<clang::DynTypedNode, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseObjCProtocolLoc(clang::ObjCProtocolLoc)::{lambda()#1}::SmallVector<clang::DynTypedNode, 2u>*> >*)
Unexecuted instantiation: bool clang::ParentMapContext::ParentMap::ASTVisitor::TraverseNode<clang::Attr*, clang::Attr*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}, llvm::DenseMap<void const*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::DenseMapInfo<void const, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::detail::DenseMapPair<void const, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*> > >(clang::Attr*, clang::Attr*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}, llvm::DenseMap<void const*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::PointerUnion<clang::Decl const*, clang::Stmt const*, clang::DynTypedNode*, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::DenseMapInfo<void const, void>, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::detail::DenseMapPair<void const, clang::ParentMapContext::ParentMap::ASTVisitor::TraverseAttr(clang::Attr*)::{lambda()#1}::SmallVector<clang::Stmt const*, 2u>*> >*)
410
411
0
  bool TraverseDecl(Decl *DeclNode) {
412
0
    return TraverseNode(
413
0
        DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); },
414
0
        &Map.PointerParents);
415
0
  }
416
0
  bool TraverseTypeLoc(TypeLoc TypeLocNode) {
417
0
    return TraverseNode(
418
0
        TypeLocNode, DynTypedNode::create(TypeLocNode),
419
0
        [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
420
0
        &Map.OtherParents);
421
0
  }
422
0
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
423
0
    return TraverseNode(
424
0
        NNSLocNode, DynTypedNode::create(NNSLocNode),
425
0
        [&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
426
0
        &Map.OtherParents);
427
0
  }
428
0
  bool TraverseAttr(Attr *AttrNode) {
429
0
    return TraverseNode(
430
0
        AttrNode, AttrNode, [&] { return VisitorBase::TraverseAttr(AttrNode); },
431
0
        &Map.PointerParents);
432
0
  }
433
0
  bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLocNode) {
434
0
    return TraverseNode(
435
0
        ProtocolLocNode, DynTypedNode::create(ProtocolLocNode),
436
0
        [&] { return VisitorBase::TraverseObjCProtocolLoc(ProtocolLocNode); },
437
0
        &Map.OtherParents);
438
0
  }
439
440
  // Using generic TraverseNode for Stmt would prevent data-recursion.
441
0
  bool dataTraverseStmtPre(Stmt *StmtNode) {
442
0
    addParent(StmtNode, &Map.PointerParents);
443
0
    ParentStack.push_back(DynTypedNode::create(*StmtNode));
444
0
    return true;
445
0
  }
446
0
  bool dataTraverseStmtPost(Stmt *StmtNode) {
447
0
    ParentStack.pop_back();
448
0
    return true;
449
0
  }
450
451
  ParentMap &Map;
452
  llvm::SmallVector<DynTypedNode, 16> ParentStack;
453
};
454
455
0
ParentMapContext::ParentMap::ParentMap(ASTContext &Ctx) {
456
0
  ASTVisitor(*this).TraverseAST(Ctx);
457
0
}
458
459
0
DynTypedNodeList ParentMapContext::getParents(const DynTypedNode &Node) {
460
0
  if (!Parents)
461
    // We build the parent map for the traversal scope (usually whole TU), as
462
    // hasAncestor can escape any subtree.
463
0
    Parents = std::make_unique<ParentMap>(ASTCtx);
464
0
  return Parents->getParents(getTraversalKind(), Node);
465
0
}