clang  13.0.0git
ParentMapContext.h
Go to the documentation of this file.
1 //===- ParentMapContext.h - 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.h, but generalizes to non-Stmt nodes, which can have
10 // multiple parents.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_PARENTMAPCONTEXT_H
15 #define LLVM_CLANG_AST_PARENTMAPCONTEXT_H
16 
17 #include "clang/AST/ASTContext.h"
19 
20 namespace clang {
21 class DynTypedNodeList;
22 
24 public:
26 
28 
29  /// Returns the parents of the given node (within the traversal scope).
30  ///
31  /// Note that this will lazily compute the parents of all nodes
32  /// and store them for later retrieval. Thus, the first call is O(n)
33  /// in the number of AST nodes.
34  ///
35  /// Caveats and FIXMEs:
36  /// Calculating the parent map over all AST nodes will need to load the
37  /// full AST. This can be undesirable in the case where the full AST is
38  /// expensive to create (for example, when using precompiled header
39  /// preambles). Thus, there are good opportunities for optimization here.
40  /// One idea is to walk the given node downwards, looking for references
41  /// to declaration contexts - once a declaration context is found, compute
42  /// the parent map for the declaration context; if that can satisfy the
43  /// request, loading the whole AST can be avoided. Note that this is made
44  /// more complex by statements in templates having multiple parents - those
45  /// problems can be solved by building closure over the templated parts of
46  /// the AST, which also avoids touching large parts of the AST.
47  /// Additionally, we will want to add an interface to already give a hint
48  /// where to search for the parents, for example when looking at a statement
49  /// inside a certain function.
50  ///
51  /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
52  /// NestedNameSpecifier or NestedNameSpecifierLoc.
53  template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);
54 
56 
57  /// Clear parent maps.
58  void clear();
59 
60  TraversalKind getTraversalKind() const { return Traversal; }
61  void setTraversalKind(TraversalKind TK) { Traversal = TK; }
62 
63  const Expr *traverseIgnored(const Expr *E) const;
64  Expr *traverseIgnored(Expr *E) const;
66 
67  class ParentMap;
68 
69 private:
70  ASTContext &ASTCtx;
72  std::unique_ptr<ParentMap> Parents;
73 };
74 
76  ParentMapContext &Ctx;
78 
79 public:
81  : Ctx(ASTCtx.getParentMapContext()) {
82  TK = Ctx.getTraversalKind();
83  if (ScopeTK)
84  Ctx.setTraversalKind(*ScopeTK);
85  }
86 
88 };
89 
90 /// Container for either a single DynTypedNode or for an ArrayRef to
91 /// DynTypedNode. For use with ParentMap.
93  llvm::AlignedCharArrayUnion<DynTypedNode, ArrayRef<DynTypedNode>> Storage;
94  bool IsSingleNode;
95 
96 public:
97  DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
98  new (&Storage) DynTypedNode(N);
99  }
100 
102  new (&Storage) ArrayRef<DynTypedNode>(A);
103  }
104 
105  const DynTypedNode *begin() const {
106  if (!IsSingleNode)
107  return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)
108  ->begin();
109  return reinterpret_cast<const DynTypedNode *>(&Storage);
110  }
111 
112  const DynTypedNode *end() const {
113  if (!IsSingleNode)
114  return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)->end();
115  return reinterpret_cast<const DynTypedNode *>(&Storage) + 1;
116  }
117 
118  size_t size() const { return end() - begin(); }
119  bool empty() const { return begin() == end(); }
120 
121  const DynTypedNode &operator[](size_t N) const {
122  assert(N < size() && "Out of bounds!");
123  return *(begin() + N);
124  }
125 };
126 
127 template <typename NodeT>
130 }
131 
132 template <typename NodeT>
135 }
136 
137 template <>
140 }
141 
142 } // namespace clang
143 
144 #endif
clang::TraversalKind
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
Definition: ASTTypeTraits.h:39
clang::DynTypedNodeList
Container for either a single DynTypedNode or for an ArrayRef to DynTypedNode.
Definition: ParentMapContext.h:92
clang::ParentMapContext::setTraversalKind
void setTraversalKind(TraversalKind TK)
Definition: ParentMapContext.h:61
clang::ASTContext::getParents
DynTypedNodeList getParents(const NodeT &Node)
Forwards to get node parents from the ParentMapContext.
Definition: ParentMapContext.h:133
clang::DynTypedNode::create
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
Definition: ASTTypeTraits.h:237
llvm::Optional
Definition: LLVM.h:37
clang::ParentMapContext::traverseIgnored
const Expr * traverseIgnored(const Expr *E) const
Definition: ParentMapContext.cpp:28
clang::DynTypedNodeList::DynTypedNodeList
DynTypedNodeList(const DynTypedNode &N)
Definition: ParentMapContext.h:97
clang::ParentMapContext::ParentMapContext
ParentMapContext(ASTContext &Ctx)
Definition: ParentMapContext.cpp:22
clang::TraversalKindScope::~TraversalKindScope
~TraversalKindScope()
Definition: ParentMapContext.h:87
Node
DynTypedNode Node
Definition: ASTMatchFinder.cpp:67
Traversal
TraversalKind Traversal
Definition: ASTMatchFinder.cpp:69
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
clang::DynTypedNodeList::DynTypedNodeList
DynTypedNodeList(ArrayRef< DynTypedNode > A)
Definition: ParentMapContext.h:101
clang::DynTypedNodeList::size
size_t size() const
Definition: ParentMapContext.h:118
clang::diff::DynTypedNode
DynTypedNode DynTypedNode
Definition: ASTDiffInternal.h:18
ASTContext.h
clang::DynTypedNodeList::end
const DynTypedNode * end() const
Definition: ParentMapContext.h:112
clang::DynTypedNodeList::empty
bool empty() const
Definition: ParentMapContext.h:119
clang::ParentMapContext
Definition: ParentMapContext.h:23
clang::ParentMap
Definition: ParentMap.h:20
false
#define false
Definition: stdbool.h:17
clang::ASTContext::getParentMapContext
ParentMapContext & getParentMapContext()
Returns the dynamic AST node parent map context.
Definition: ASTContext.cpp:911
clang::TK_AsIs
@ TK_AsIs
Will traverse all child nodes.
Definition: ASTTypeTraits.h:41
llvm::ArrayRef
Definition: LLVM.h:31
clang::TraversalKindScope::TraversalKindScope
TraversalKindScope(ASTContext &ASTCtx, llvm::Optional< TraversalKind > ScopeTK)
Definition: ParentMapContext.h:80
clang::ParentMapContext::~ParentMapContext
~ParentMapContext()
clang::ParentMapContext::getParents
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
Definition: ParentMapContext.h:128
ASTTypeTraits.h
clang::DynTypedNodeList::operator[]
const DynTypedNode & operator[](size_t N) const
Definition: ParentMapContext.h:121
clang::ParentMapContext::clear
void clear()
Clear parent maps.
Definition: ParentMapContext.cpp:26
clang
Dataflow Directional Tag Classes.
Definition: CalledOnceCheck.h:17
clang::ParentMapContext::getTraversalKind
TraversalKind getTraversalKind() const
Definition: ParentMapContext.h:60
clang::DynTypedNode
A dynamically typed AST node container.
Definition: ASTTypeTraits.h:233
true
#define true
Definition: stdbool.h:16
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::DynTypedNodeList::begin
const DynTypedNode * begin() const
Definition: ParentMapContext.h:105
clang::TraversalKindScope
Definition: ParentMapContext.h:75