diff options
Diffstat (limited to 'clang/lib/Tooling/Syntax/Tree.cpp')
| -rw-r--r-- | clang/lib/Tooling/Syntax/Tree.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/clang/lib/Tooling/Syntax/Tree.cpp b/clang/lib/Tooling/Syntax/Tree.cpp index d7436ae9513..5282857df5a 100644 --- a/clang/lib/Tooling/Syntax/Tree.cpp +++ b/clang/lib/Tooling/Syntax/Tree.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Casting.h" +#include <cassert> using namespace clang; @@ -91,8 +92,10 @@ void syntax::Tree::replaceChildRangeLowLevel(Node *BeforeBegin, Node *End, if (New) { auto *Last = New; - while (auto *Next = Last->nextSibling()) - Last = Next; + for (auto *N = New; N != nullptr; N = N->nextSibling()) { + Last = N; + N->Parent = this; + } Last->NextSibling = End; } @@ -189,6 +192,31 @@ std::string syntax::Node::dumpTokens(const Arena &A) const { return OS.str(); } +void syntax::Node::assertInvariants() const { +#ifndef NDEBUG + if (isDetached()) + assert(parent() == nullptr); + else + assert(parent() != nullptr); + + auto *T = dyn_cast<Tree>(this); + if (!T) + return; + for (auto *C = T->firstChild(); C; C = C->nextSibling()) { + if (T->isOriginal()) + assert(C->isOriginal()); + assert(!C->isDetached()); + assert(C->parent() == T); + } +#endif +} + +void syntax::Node::assertInvariantsRecursive() const { +#ifndef NDEBUG + traverse(this, [&](const syntax::Node *N) { N->assertInvariants(); }); +#endif +} + syntax::Leaf *syntax::Tree::firstLeaf() { auto *T = this; while (auto *C = T->firstChild()) { |

