11 #include "llvm/ADT/ArrayRef.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/Support/Casting.h" 16 using namespace clang;
21 if (
auto *T = dyn_cast<syntax::Tree>(N)) {
22 for (
auto *C = T->firstChild();
C;
C =
C->nextSibling())
30 Visit(const_cast<syntax::Node *>(N));
37 : SourceMgr(SourceMgr), LangOpts(LangOpts), Tokens(
std::move(Tokens)) {}
43 std::pair<FileID, llvm::ArrayRef<syntax::Token>>
46 auto It = ExtraTokens.try_emplace(FID,
tokenize(FID, SourceMgr, LangOpts));
47 assert(It.second &&
"duplicate FileID");
48 return {FID, It.first->second};
52 assert(Tok !=
nullptr);
60 :
Parent(nullptr), NextSibling(nullptr), Kind(static_cast<unsigned>(Kind)),
68 void syntax::Tree::prependChildLowLevel(
Node *Child,
NodeRole Role) {
69 assert(Child->Parent ==
nullptr);
70 assert(Child->NextSibling ==
nullptr);
75 Child->NextSibling = this->FirstChild;
76 Child->Role =
static_cast<unsigned>(Role);
77 this->FirstChild = Child;
80 void syntax::Tree::replaceChildRangeLowLevel(
Node *BeforeBegin,
Node *
End,
82 assert(!BeforeBegin || BeforeBegin->Parent ==
this);
86 assert(N->Parent ==
nullptr);
93 for (
auto *N = !BeforeBegin ? FirstChild : BeforeBegin->
nextSibling();
95 auto *Next = N->NextSibling;
99 N->NextSibling =
nullptr;
108 BeforeBegin->NextSibling = New ? New :
End;
110 FirstChild = New ? New :
End;
114 for (
auto *N = New; N !=
nullptr; N = N->
nextSibling()) {
122 for (
auto *T =
this; T && T->Original; T = T->Parent)
129 assert(!Tokens.empty());
131 for (
const auto &T : Tokens) {
145 static void dumpTree(llvm::raw_ostream &OS,
const syntax::Node *N,
157 if (
auto *L = llvm::dyn_cast<syntax::Leaf>(N)) {
163 auto *T = llvm::cast<syntax::Tree>(N);
164 OS << T->kind() <<
"\n";
166 for (
auto It = T->firstChild(); It !=
nullptr; It = It->nextSibling()) {
167 for (
bool Filled : IndentMask) {
173 if (!It->nextSibling()) {
175 IndentMask.push_back(
false);
178 IndentMask.push_back(
true);
180 dumpTree(OS, It, A, IndentMask);
181 IndentMask.pop_back();
188 llvm::raw_string_ostream OS(Str);
189 dumpTree(OS,
this, A, {});
190 return std::move(OS.str());
195 llvm::raw_string_ostream OS(Storage);
209 assert(
parent() ==
nullptr);
211 assert(
parent() !=
nullptr);
213 auto *T = dyn_cast<
Tree>(
this);
216 for (
auto *C = T->firstChild(); C; C = C->nextSibling()) {
218 assert(C->isOriginal());
219 assert(!C->isDetached());
220 assert(C->parent() == T);
233 while (
auto *C = T->firstChild()) {
234 if (
auto *L = dyn_cast<syntax::Leaf>(C))
236 T = cast<syntax::Tree>(C);
243 while (
auto *C = T->firstChild()) {
245 while (
auto *Next = C->nextSibling())
248 if (
auto *L = dyn_cast<syntax::Leaf>(C))
250 T = cast<syntax::Tree>(C);
256 for (
auto *C = FirstChild; C; C = C->nextSibling()) {
std::pair< FileID, llvm::ArrayRef< syntax::Token > > lexBuffer(std::unique_ptr< llvm::MemoryBuffer > Buffer)
Add Buffer to the underlying source manager, tokenize it and store the resulting tokens.
std::string dump(const Arena &A) const
Dumps the structure of a subtree. For debugging and testing purposes.
A token coming directly from a file or from a macro invocation.
static bool classof(const Node *N)
static bool classof(const Node *N)
Node(NodeKind Kind)
Newly created nodes are detached from a tree, parent and sibling links are set when the node is added...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const SourceManager & sourceManager() const
bool isDetached() const
Whether the node is detached from a tree, i.e. does not have a parent.
const TokenBuffer & tokenBuffer() const
A memory arena for syntax trees.
bool canModify() const
If this function return false, the tree cannot be modified because there is no reasonable way to prod...
const Node * nextSibling() const
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, unsigned LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
A node that has children and represents a syntactic language construct.
NodeKind
A kind of a syntax node, used for implementing casts.
const Tree * parent() const
ast_type_traits::DynTypedNode Node
NodeRole
A relation between a parent and child node, e.g.
Dataflow Directional Tag Classes.
Arena(SourceManager &SourceMgr, const LangOptions &LangOpts, TokenBuffer Tokens)
A leaf node points to a single token inside the expanded token stream.
bool isOriginal() const
Whether the node was created from the AST backed by the source code rather than added later through m...
std::vector< syntax::Token > tokenize(FileID FID, const SourceManager &SM, const LangOptions &LO)
Lex the text buffer, corresponding to FID, in raw mode and record the resulting spelled tokens...
Defines the clang::TokenKind enum and support functions.
void assertInvariants() const
Asserts invariants on this node of the tree and its immediate children.
internal::Matcher< T > traverse(ast_type_traits::TraversalKind TK, const internal::Matcher< T > &InnerMatcher)
Causes all nested matchers to be matched with the specified traversal kind.
Leaf(const syntax::Token *T)
void assertInvariantsRecursive() const
Runs checkInvariants on all nodes in the subtree. No-op if NDEBUG is set.
std::string dumpTokens(const Arena &A) const
Dumps the tokens forming this subtree.
A list of tokens obtained by preprocessing a text buffer and operations to map between the expanded a...
This class handles loading and caching of source files into memory.
syntax::Node * findChild(NodeRole R)
Find the first node with a corresponding role.