diff --git a/clang/include/clang/Tooling/Syntax/Tree.h b/clang/include/clang/Tooling/Syntax/Tree.h --- a/clang/include/clang/Tooling/Syntax/Tree.h +++ b/clang/include/clang/Tooling/Syntax/Tree.h @@ -106,9 +106,9 @@ Node *nextSibling() { return NextSibling; } /// Dumps the structure of a subtree. For debugging and testing purposes. - std::string dump(const Arena &A) const; + std::string dump(const SourceManager &SM) const; /// Dumps the tokens forming this subtree. - std::string dumpTokens(const Arena &A) const; + std::string dumpTokens(const SourceManager &SM) const; /// Asserts invariants on this node of the tree and its immediate children. /// Will not recurse into the subtree. No-op if NDEBUG is set. diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -526,7 +526,7 @@ R += std::string(llvm::formatv( "- '{0}' covers '{1}'+{2} tokens\n", It->second->kind(), It->first->text(A.sourceManager()), CoveredTokens)); - R += It->second->dump(A); + R += It->second->dump(A.sourceManager()); } return R; } diff --git a/clang/lib/Tooling/Syntax/Tree.cpp b/clang/lib/Tooling/Syntax/Tree.cpp --- a/clang/lib/Tooling/Syntax/Tree.cpp +++ b/clang/lib/Tooling/Syntax/Tree.cpp @@ -135,46 +135,43 @@ } namespace { -static void dumpTokens(llvm::raw_ostream &OS, ArrayRef Tokens, - const SourceManager &SM) { - assert(!Tokens.empty()); - bool First = true; - for (const auto &T : Tokens) { - if (!First) - OS << " "; - else - First = false; - // Handle 'eof' separately, calling text() on it produces an empty string. - if (T.kind() == tok::eof) { - OS << ""; - continue; - } - OS << T.text(SM); - } +static llvm::StringRef strOfLeaf(const syntax::Leaf *L, + const SourceManager &SM) { + assert(L); + const auto *Token = L->token(); + assert(Token); + // Handle 'eof' separately, calling text() on it produces an empty string. + if (Token->kind() == tok::eof) + return ""; + return Token->text(SM); } -static void dumpTree(llvm::raw_ostream &OS, const syntax::Node *N, - const syntax::Arena &A, std::vector IndentMask) { +static void dumpNode(llvm::raw_ostream &OS, const syntax::Node *N, + const SourceManager &SM, std::vector IndentMask) { std::string Marks; if (!N->isOriginal()) Marks += "M"; - if (N->role() == syntax::NodeRole::Detached) - Marks += "*"; // FIXME: find a nice way to print other roles. if (!N->canModify()) Marks += "I"; if (!Marks.empty()) OS << Marks << ": "; if (auto *L = llvm::dyn_cast(N)) { - dumpTokens(OS, *L->token(), A.sourceManager()); + OS << "'" << strOfLeaf(L, SM) << "'"; + if (L->role() != syntax::NodeRole::Unknown) + OS << " " << L->role(); OS << "\n"; return; } auto *T = llvm::cast(N); - OS << T->kind() << "\n"; + OS << T->kind(); + if (T->role() != syntax::NodeRole::Unknown) + OS << " " << T->role(); + OS << "\n"; - for (auto It = T->firstChild(); It != nullptr; It = It->nextSibling()) { + for (const auto *It = T->firstChild(); It != nullptr; + It = It->nextSibling()) { for (bool Filled : IndentMask) { if (Filled) OS << "| "; @@ -188,28 +185,26 @@ OS << "|-"; IndentMask.push_back(true); } - dumpTree(OS, It, A, IndentMask); + dumpNode(OS, It, SM, IndentMask); IndentMask.pop_back(); } } } // namespace -std::string syntax::Node::dump(const Arena &A) const { +std::string syntax::Node::dump(const SourceManager &SM) const { std::string Str; llvm::raw_string_ostream OS(Str); - dumpTree(OS, this, A, /*IndentMask=*/{}); + dumpNode(OS, this, SM, /*IndentMask=*/{}); return std::move(OS.str()); } -std::string syntax::Node::dumpTokens(const Arena &A) const { +std::string syntax::Node::dumpTokens(const SourceManager &SM) const { std::string Storage; llvm::raw_string_ostream OS(Storage); traverse(this, [&](const syntax::Node *N) { - auto *L = llvm::dyn_cast(N); - if (!L) - return; - ::dumpTokens(OS, *L->token(), A.sourceManager()); - OS << " "; + if (auto *L = llvm::dyn_cast(N)) { + OS << strOfLeaf(L, SM) << " "; + } }); return OS.str(); } diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -159,7 +159,8 @@ << "Source file has syntax errors, they were printed to the test " "log"; } - std::string Actual = std::string(StringRef(Root->dump(*Arena)).trim()); + std::string Actual = + std::string(StringRef(Root->dump(Arena->sourceManager())).trim()); // EXPECT_EQ shows the diff between the two strings if they are different. EXPECT_EQ(Tree.trim().str(), Actual); if (Actual != Tree.trim().str()) {