File indexing completed on 2026-05-10 08:36:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_PARENTMAPCONTEXT_H
0015 #define LLVM_CLANG_AST_PARENTMAPCONTEXT_H
0016
0017 #include "clang/AST/ASTContext.h"
0018 #include "clang/AST/ASTTypeTraits.h"
0019
0020 namespace clang {
0021 class DynTypedNodeList;
0022
0023 class ParentMapContext {
0024 public:
0025 ParentMapContext(ASTContext &Ctx);
0026
0027 ~ParentMapContext();
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);
0054
0055 DynTypedNodeList getParents(const DynTypedNode &Node);
0056
0057
0058 void clear();
0059
0060 TraversalKind getTraversalKind() const { return Traversal; }
0061 void setTraversalKind(TraversalKind TK) { Traversal = TK; }
0062
0063 const Expr *traverseIgnored(const Expr *E) const;
0064 Expr *traverseIgnored(Expr *E) const;
0065 DynTypedNode traverseIgnored(const DynTypedNode &N) const;
0066
0067 class ParentMap;
0068
0069 private:
0070 ASTContext &ASTCtx;
0071 TraversalKind Traversal = TK_AsIs;
0072 std::unique_ptr<ParentMap> Parents;
0073 };
0074
0075 class TraversalKindScope {
0076 ParentMapContext &Ctx;
0077 TraversalKind TK = TK_AsIs;
0078
0079 public:
0080 TraversalKindScope(ASTContext &ASTCtx, std::optional<TraversalKind> ScopeTK)
0081 : Ctx(ASTCtx.getParentMapContext()) {
0082 TK = Ctx.getTraversalKind();
0083 if (ScopeTK)
0084 Ctx.setTraversalKind(*ScopeTK);
0085 }
0086
0087 ~TraversalKindScope() { Ctx.setTraversalKind(TK); }
0088 };
0089
0090
0091
0092 class DynTypedNodeList {
0093 union {
0094 DynTypedNode SingleNode;
0095 ArrayRef<DynTypedNode> Nodes;
0096 };
0097 bool IsSingleNode;
0098
0099 public:
0100 DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
0101 new (&SingleNode) DynTypedNode(N);
0102 }
0103
0104 DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
0105 new (&Nodes) ArrayRef<DynTypedNode>(A);
0106 }
0107
0108 const DynTypedNode *begin() const {
0109 return !IsSingleNode ? Nodes.begin() : &SingleNode;
0110 }
0111
0112 const DynTypedNode *end() const {
0113 return !IsSingleNode ? Nodes.end() : &SingleNode + 1;
0114 }
0115
0116 size_t size() const { return end() - begin(); }
0117 bool empty() const { return begin() == end(); }
0118
0119 const DynTypedNode &operator[](size_t N) const {
0120 assert(N < size() && "Out of bounds!");
0121 return *(begin() + N);
0122 }
0123 };
0124
0125 template <typename NodeT>
0126 inline DynTypedNodeList ParentMapContext::getParents(const NodeT &Node) {
0127 return getParents(DynTypedNode::create(Node));
0128 }
0129
0130 template <typename NodeT>
0131 inline DynTypedNodeList ASTContext::getParents(const NodeT &Node) {
0132 return getParentMapContext().getParents(Node);
0133 }
0134
0135 template <>
0136 inline DynTypedNodeList ASTContext::getParents(const DynTypedNode &Node) {
0137 return getParentMapContext().getParents(Node);
0138 }
0139
0140 }
0141
0142 #endif