File indexing completed on 2026-05-10 08:37:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef LLVM_CLANG_TOOLING_SYNTAX_TREE_H
0022 #define LLVM_CLANG_TOOLING_SYNTAX_TREE_H
0023
0024 #include "clang/Basic/TokenKinds.h"
0025 #include "clang/Tooling/Syntax/TokenManager.h"
0026 #include "llvm/ADT/iterator.h"
0027 #include "llvm/Support/Allocator.h"
0028 #include <cstdint>
0029 #include <vector>
0030
0031 namespace clang {
0032 namespace syntax {
0033
0034
0035
0036 class Arena {
0037 public:
0038 llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
0039 private:
0040
0041 llvm::BumpPtrAllocator Allocator;
0042 };
0043
0044 class Tree;
0045 class TreeBuilder;
0046 class FactoryImpl;
0047 class MutationsImpl;
0048
0049 enum class NodeKind : uint16_t;
0050 enum class NodeRole : uint8_t;
0051
0052
0053
0054 class Node {
0055 protected:
0056
0057
0058 Node(NodeKind Kind);
0059
0060 ~Node() = default;
0061
0062 public:
0063
0064 Node(const Node &) = delete;
0065 Node &operator=(const Node &) = delete;
0066
0067 Node(Node &&) = delete;
0068 Node &operator=(Node &&) = delete;
0069
0070 NodeKind getKind() const { return static_cast<NodeKind>(Kind); }
0071 NodeRole getRole() const { return static_cast<NodeRole>(Role); }
0072
0073
0074 bool isDetached() const;
0075
0076
0077
0078
0079
0080
0081 bool isOriginal() const { return Original; }
0082
0083
0084
0085
0086
0087
0088 bool canModify() const { return CanModify; }
0089
0090 const Tree *getParent() const { return Parent; }
0091 Tree *getParent() { return Parent; }
0092
0093 const Node *getNextSibling() const { return NextSibling; }
0094 Node *getNextSibling() { return NextSibling; }
0095 const Node *getPreviousSibling() const { return PreviousSibling; }
0096 Node *getPreviousSibling() { return PreviousSibling; }
0097
0098
0099 std::string dump(const TokenManager &SM) const;
0100
0101 std::string dumpTokens(const TokenManager &SM) const;
0102
0103
0104
0105 void assertInvariants() const;
0106
0107 void assertInvariantsRecursive() const;
0108
0109 private:
0110
0111 friend class Tree;
0112
0113 friend class TreeBuilder;
0114
0115 friend class MutationsImpl;
0116
0117 friend class FactoryImpl;
0118
0119 void setRole(NodeRole NR);
0120
0121 Tree *Parent;
0122 Node *NextSibling;
0123 Node *PreviousSibling;
0124 unsigned Kind : 16;
0125 unsigned Role : 8;
0126 unsigned Original : 1;
0127 unsigned CanModify : 1;
0128 };
0129
0130
0131
0132 class Leaf final : public Node {
0133 public:
0134 Leaf(TokenManager::Key K);
0135 static bool classof(const Node *N);
0136
0137 TokenManager::Key getTokenKey() const { return K; }
0138
0139 private:
0140 TokenManager::Key K;
0141 };
0142
0143
0144 class Tree : public Node {
0145
0146
0147 template <typename DerivedT, typename NodeT>
0148 class ChildIteratorBase
0149 : public llvm::iterator_facade_base<DerivedT, std::forward_iterator_tag,
0150 NodeT> {
0151 protected:
0152 NodeT *N = nullptr;
0153 using Base = ChildIteratorBase;
0154
0155 public:
0156 ChildIteratorBase() = default;
0157 explicit ChildIteratorBase(NodeT *N) : N(N) {}
0158
0159 friend bool operator==(const DerivedT &LHS, const DerivedT &RHS) {
0160 return LHS.N == RHS.N;
0161 }
0162
0163 NodeT &operator*() const { return *N; }
0164 DerivedT &operator++() {
0165 N = N->getNextSibling();
0166 return *static_cast<DerivedT *>(this);
0167 }
0168
0169
0170
0171 explicit operator bool() const { return N != nullptr; }
0172
0173 NodeT *asPointer() const { return N; }
0174 };
0175
0176 public:
0177 static bool classof(const Node *N);
0178
0179 Node *getFirstChild() { return FirstChild; }
0180 const Node *getFirstChild() const { return FirstChild; }
0181 Node *getLastChild() { return LastChild; }
0182 const Node *getLastChild() const { return LastChild; }
0183
0184 const Leaf *findFirstLeaf() const;
0185 Leaf *findFirstLeaf() {
0186 return const_cast<Leaf *>(const_cast<const Tree *>(this)->findFirstLeaf());
0187 }
0188
0189 const Leaf *findLastLeaf() const;
0190 Leaf *findLastLeaf() {
0191 return const_cast<Leaf *>(const_cast<const Tree *>(this)->findLastLeaf());
0192 }
0193
0194
0195 struct ChildIterator : ChildIteratorBase<ChildIterator, Node> {
0196 using Base::ChildIteratorBase;
0197 };
0198 struct ConstChildIterator
0199 : ChildIteratorBase<ConstChildIterator, const Node> {
0200 using Base::ChildIteratorBase;
0201 ConstChildIterator() = default;
0202 ConstChildIterator(const ChildIterator &I) : Base(I.asPointer()) {}
0203 };
0204
0205 llvm::iterator_range<ChildIterator> getChildren() {
0206 return {ChildIterator(getFirstChild()), ChildIterator()};
0207 }
0208 llvm::iterator_range<ConstChildIterator> getChildren() const {
0209 return {ConstChildIterator(getFirstChild()), ConstChildIterator()};
0210 }
0211
0212
0213 const Node *findChild(NodeRole R) const;
0214 Node *findChild(NodeRole R) {
0215 return const_cast<Node *>(const_cast<const Tree *>(this)->findChild(R));
0216 }
0217
0218 protected:
0219 using Node::Node;
0220
0221 private:
0222
0223
0224
0225
0226 void appendChildLowLevel(Node *Child, NodeRole Role);
0227
0228 void prependChildLowLevel(Node *Child, NodeRole Role);
0229
0230
0231
0232 void appendChildLowLevel(Node *Child);
0233 void prependChildLowLevel(Node *Child);
0234 friend class TreeBuilder;
0235 friend class FactoryImpl;
0236
0237
0238
0239
0240
0241
0242
0243 void replaceChildRangeLowLevel(Node *Begin, Node *End, Node *New);
0244 friend class MutationsImpl;
0245
0246 Node *FirstChild = nullptr;
0247 Node *LastChild = nullptr;
0248 };
0249
0250
0251
0252
0253
0254 class List : public Tree {
0255 public:
0256 template <typename Element> struct ElementAndDelimiter {
0257 Element *element;
0258 Leaf *delimiter;
0259 };
0260
0261 enum class TerminationKind {
0262 Terminated,
0263 MaybeTerminated,
0264 Separated,
0265 };
0266
0267 using Tree::Tree;
0268 static bool classof(const Node *N);
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 std::vector<ElementAndDelimiter<Node>> getElementsAsNodesAndDelimiters();
0284
0285
0286
0287
0288 std::vector<Node *> getElementsAsNodes();
0289
0290
0291
0292
0293
0294
0295
0296 clang::tok::TokenKind getDelimiterTokenKind() const;
0297
0298 TerminationKind getTerminationKind() const;
0299
0300
0301
0302
0303
0304
0305 bool canBeEmpty() const;
0306 };
0307
0308 }
0309 }
0310
0311 #endif