diff options
Diffstat (limited to 'clang/lib/Tooling/Syntax')
-rw-r--r-- | clang/lib/Tooling/Syntax/BuildTree.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/ComputeReplacements.cpp | 37 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/Mutations.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/Nodes.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/Synthesis.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/TokenBufferTokenManager.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/Tree.cpp | 52 |
7 files changed, 115 insertions, 97 deletions
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index 484cf61664fe..041cc4f939d9 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -27,6 +27,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Tooling/Syntax/Nodes.h" +#include "clang/Tooling/Syntax/TokenBufferTokenManager.h" #include "clang/Tooling/Syntax/Tokens.h" #include "clang/Tooling/Syntax/Tree.h" #include "llvm/ADT/ArrayRef.h" @@ -365,21 +366,24 @@ private: /// Call finalize() to finish building the tree and consume the root node. class syntax::TreeBuilder { public: - TreeBuilder(syntax::Arena &Arena) : Arena(Arena), Pending(Arena) { - for (const auto &T : Arena.getTokenBuffer().expandedTokens()) + TreeBuilder(syntax::Arena &Arena, TokenBufferTokenManager& TBTM) + : Arena(Arena), + TBTM(TBTM), + Pending(Arena, TBTM.tokenBuffer()) { + for (const auto &T : TBTM.tokenBuffer().expandedTokens()) LocationToToken.insert({T.location(), &T}); } llvm::BumpPtrAllocator &allocator() { return Arena.getAllocator(); } const SourceManager &sourceManager() const { - return Arena.getSourceManager(); + return TBTM.sourceManager(); } /// Populate children for \p New node, assuming it covers tokens from \p /// Range. void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, ASTPtr From) { assert(New); - Pending.foldChildren(Arena, Range, New); + Pending.foldChildren(TBTM.tokenBuffer(), Range, New); if (From) Mapping.add(From, New); } @@ -392,7 +396,7 @@ public: void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New, NestedNameSpecifierLoc From) { assert(New); - Pending.foldChildren(Arena, Range, New); + Pending.foldChildren(TBTM.tokenBuffer(), Range, New); if (From) Mapping.add(From, New); } @@ -403,7 +407,7 @@ public: ASTPtr From) { assert(New); auto ListRange = Pending.shrinkToFitList(SuperRange); - Pending.foldChildren(Arena, ListRange, New); + Pending.foldChildren(TBTM.tokenBuffer(), ListRange, New); if (From) Mapping.add(From, New); } @@ -434,12 +438,12 @@ public: /// Finish building the tree and consume the root node. syntax::TranslationUnit *finalize() && { - auto Tokens = Arena.getTokenBuffer().expandedTokens(); + auto Tokens = TBTM.tokenBuffer().expandedTokens(); assert(!Tokens.empty()); assert(Tokens.back().kind() == tok::eof); // Build the root of the tree, consuming all the children. - Pending.foldChildren(Arena, Tokens.drop_back(), + Pending.foldChildren(TBTM.tokenBuffer(), Tokens.drop_back(), new (Arena.getAllocator()) syntax::TranslationUnit); auto *TU = cast<syntax::TranslationUnit>(std::move(Pending).finalize()); @@ -464,7 +468,7 @@ public: assert(First.isValid()); assert(Last.isValid()); assert(First == Last || - Arena.getSourceManager().isBeforeInTranslationUnit(First, Last)); + TBTM.sourceManager().isBeforeInTranslationUnit(First, Last)); return llvm::makeArrayRef(findToken(First), std::next(findToken(Last))); } @@ -564,15 +568,16 @@ private: /// /// Ensures that added nodes properly nest and cover the whole token stream. struct Forest { - Forest(syntax::Arena &A) { - assert(!A.getTokenBuffer().expandedTokens().empty()); - assert(A.getTokenBuffer().expandedTokens().back().kind() == tok::eof); + Forest(syntax::Arena &A, const syntax::TokenBuffer &TB) { + assert(!TB.expandedTokens().empty()); + assert(TB.expandedTokens().back().kind() == tok::eof); // Create all leaf nodes. // Note that we do not have 'eof' in the tree. - for (const auto &T : A.getTokenBuffer().expandedTokens().drop_back()) { - auto *L = new (A.getAllocator()) syntax::Leaf(&T); + for (const auto &T : TB.expandedTokens().drop_back()) { + auto *L = new (A.getAllocator()) + syntax::Leaf(reinterpret_cast<TokenManager::Key>(&T)); L->Original = true; - L->CanModify = A.getTokenBuffer().spelledForExpanded(T).has_value(); + L->CanModify = TB.spelledForExpanded(T).has_value(); Trees.insert(Trees.end(), {&T, L}); } } @@ -620,8 +625,8 @@ private: } /// Add \p Node to the forest and attach child nodes based on \p Tokens. - void foldChildren(const syntax::Arena &A, ArrayRef<syntax::Token> Tokens, - syntax::Tree *Node) { + void foldChildren(const syntax::TokenBuffer &TB, + ArrayRef<syntax::Token> Tokens, syntax::Tree *Node) { // Attach children to `Node`. assert(Node->getFirstChild() == nullptr && "node already has children"); @@ -646,7 +651,7 @@ private: // Mark that this node came from the AST and is backed by the source code. Node->Original = true; Node->CanModify = - A.getTokenBuffer().spelledForExpanded(Tokens).has_value(); + TB.spelledForExpanded(Tokens).has_value(); Trees.erase(BeginChildren, EndChildren); Trees.insert({FirstToken, Node}); @@ -660,18 +665,18 @@ private: return Root; } - std::string str(const syntax::Arena &A) const { + std::string str(const syntax::TokenBufferTokenManager &STM) const { std::string R; for (auto It = Trees.begin(); It != Trees.end(); ++It) { unsigned CoveredTokens = It != Trees.end() ? (std::next(It)->first - It->first) - : A.getTokenBuffer().expandedTokens().end() - It->first; + : STM.tokenBuffer().expandedTokens().end() - It->first; R += std::string( formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(), - It->first->text(A.getSourceManager()), CoveredTokens)); - R += It->second->dump(A.getSourceManager()); + It->first->text(STM.sourceManager()), CoveredTokens)); + R += It->second->dump(STM); } return R; } @@ -684,9 +689,10 @@ private: }; /// For debugging purposes. - std::string str() { return Pending.str(Arena); } + std::string str() { return Pending.str(TBTM); } syntax::Arena &Arena; + TokenBufferTokenManager& TBTM; /// To quickly find tokens by their start location. llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken; Forest Pending; @@ -1718,7 +1724,7 @@ void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) { markExprChild(ChildExpr, NodeRole::Expression); ChildNode = new (allocator()) syntax::ExpressionStatement; // (!) 'getStmtRange()' ensures this covers a trailing semicolon. - Pending.foldChildren(Arena, getStmtRange(Child), ChildNode); + Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode); } else { ChildNode = Mapping.find(Child); } @@ -1745,8 +1751,9 @@ const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const { } syntax::TranslationUnit *syntax::buildSyntaxTree(Arena &A, + TokenBufferTokenManager& TBTM, ASTContext &Context) { - TreeBuilder Builder(A); + TreeBuilder Builder(A, TBTM); BuildTreeVisitor(Context, Builder).TraverseAST(Context); return std::move(Builder).finalize(); } diff --git a/clang/lib/Tooling/Syntax/ComputeReplacements.cpp b/clang/lib/Tooling/Syntax/ComputeReplacements.cpp index 31e1a40c74b6..08e09e4ebdbf 100644 --- a/clang/lib/Tooling/Syntax/ComputeReplacements.cpp +++ b/clang/lib/Tooling/Syntax/ComputeReplacements.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Syntax/Mutations.h" +#include "clang/Tooling/Syntax/TokenBufferTokenManager.h" #include "clang/Tooling/Syntax/Tokens.h" +#include "clang/Tooling/Syntax/Tree.h" #include "llvm/Support/Error.h" using namespace clang; @@ -16,10 +18,13 @@ namespace { using ProcessTokensFn = llvm::function_ref<void(llvm::ArrayRef<syntax::Token>, bool /*IsOriginal*/)>; /// Enumerates spans of tokens from the tree consecutively laid out in memory. -void enumerateTokenSpans(const syntax::Tree *Root, ProcessTokensFn Callback) { +void enumerateTokenSpans(const syntax::Tree *Root, + const syntax::TokenBufferTokenManager &STM, + ProcessTokensFn Callback) { struct Enumerator { - Enumerator(ProcessTokensFn Callback) - : SpanBegin(nullptr), SpanEnd(nullptr), SpanIsOriginal(false), + Enumerator(const syntax::TokenBufferTokenManager &STM, + ProcessTokensFn Callback) + : STM(STM), SpanBegin(nullptr), SpanEnd(nullptr), SpanIsOriginal(false), Callback(Callback) {} void run(const syntax::Tree *Root) { @@ -39,7 +44,8 @@ void enumerateTokenSpans(const syntax::Tree *Root, ProcessTokensFn Callback) { } auto *L = cast<syntax::Leaf>(N); - if (SpanEnd == L->getToken() && SpanIsOriginal == L->isOriginal()) { + if (SpanEnd == STM.getToken(L->getTokenKey()) && + SpanIsOriginal == L->isOriginal()) { // Extend the current span. ++SpanEnd; return; @@ -48,24 +54,25 @@ void enumerateTokenSpans(const syntax::Tree *Root, ProcessTokensFn Callback) { if (SpanBegin) Callback(llvm::makeArrayRef(SpanBegin, SpanEnd), SpanIsOriginal); // Start recording a new span. - SpanBegin = L->getToken(); + SpanBegin = STM.getToken(L->getTokenKey()); SpanEnd = SpanBegin + 1; SpanIsOriginal = L->isOriginal(); } + const syntax::TokenBufferTokenManager &STM; const syntax::Token *SpanBegin; const syntax::Token *SpanEnd; bool SpanIsOriginal; ProcessTokensFn Callback; }; - return Enumerator(Callback).run(Root); + return Enumerator(STM, Callback).run(Root); } -syntax::FileRange rangeOfExpanded(const syntax::Arena &A, +syntax::FileRange rangeOfExpanded(const syntax::TokenBufferTokenManager &STM, llvm::ArrayRef<syntax::Token> Expanded) { - const auto &Buffer = A.getTokenBuffer(); - const auto &SM = A.getSourceManager(); + const auto &Buffer = STM.tokenBuffer(); + const auto &SM = STM.sourceManager(); // Check that \p Expanded actually points into expanded tokens. assert(Buffer.expandedTokens().begin() <= Expanded.begin()); @@ -83,10 +90,10 @@ syntax::FileRange rangeOfExpanded(const syntax::Arena &A, } // namespace tooling::Replacements -syntax::computeReplacements(const syntax::Arena &A, +syntax::computeReplacements(const TokenBufferTokenManager &TBTM, const syntax::TranslationUnit &TU) { - const auto &Buffer = A.getTokenBuffer(); - const auto &SM = A.getSourceManager(); + const auto &Buffer = TBTM.tokenBuffer(); + const auto &SM = TBTM.sourceManager(); tooling::Replacements Replacements; // Text inserted by the replacement we are building now. @@ -95,13 +102,13 @@ syntax::computeReplacements(const syntax::Arena &A, if (ReplacedRange.empty() && Replacement.empty()) return; llvm::cantFail(Replacements.add(tooling::Replacement( - SM, rangeOfExpanded(A, ReplacedRange).toCharRange(SM), Replacement))); + SM, rangeOfExpanded(TBTM, ReplacedRange).toCharRange(SM), + Replacement))); Replacement = ""; }; - const syntax::Token *NextOriginal = Buffer.expandedTokens().begin(); enumerateTokenSpans( - &TU, [&](llvm::ArrayRef<syntax::Token> Tokens, bool IsOriginal) { + &TU, TBTM, [&](llvm::ArrayRef<syntax::Token> Tokens, bool IsOriginal) { if (!IsOriginal) { Replacement += syntax::Token::range(SM, Tokens.front(), Tokens.back()).text(SM); diff --git a/clang/lib/Tooling/Syntax/Mutations.cpp b/clang/lib/Tooling/Syntax/Mutations.cpp index f8a652219b22..824f1942532d 100644 --- a/clang/lib/Tooling/Syntax/Mutations.cpp +++ b/clang/lib/Tooling/Syntax/Mutations.cpp @@ -77,7 +77,8 @@ public: } }; -void syntax::removeStatement(syntax::Arena &A, syntax::Statement *S) { +void syntax::removeStatement(syntax::Arena &A, TokenBufferTokenManager &TBTM, + syntax::Statement *S) { assert(S); assert(S->canModify()); @@ -90,5 +91,5 @@ void syntax::removeStatement(syntax::Arena &A, syntax::Statement *S) { if (isa<EmptyStatement>(S)) return; // already an empty statement, nothing to do. - MutationsImpl::replace(S, createEmptyStatement(A)); + MutationsImpl::replace(S, createEmptyStatement(A, TBTM)); } diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp index fc6f8ef1a82c..d0c1e9297cfa 100644 --- a/clang/lib/Tooling/Syntax/Nodes.cpp +++ b/clang/lib/Tooling/Syntax/Nodes.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// #include "clang/Tooling/Syntax/Nodes.h" -#include "clang/Basic/TokenKinds.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; diff --git a/clang/lib/Tooling/Syntax/Synthesis.cpp b/clang/lib/Tooling/Syntax/Synthesis.cpp index ef6492882be6..39c19951ae76 100644 --- a/clang/lib/Tooling/Syntax/Synthesis.cpp +++ b/clang/lib/Tooling/Syntax/Synthesis.cpp @@ -8,6 +8,8 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Tooling/Syntax/BuildTree.h" #include "clang/Tooling/Syntax/Tree.h" +#include "clang/Tooling/Syntax/Tokens.h" +#include "clang/Tooling/Syntax/TokenBufferTokenManager.h" using namespace clang; @@ -27,35 +29,40 @@ public: } static std::pair<FileID, ArrayRef<Token>> - lexBuffer(syntax::Arena &A, std::unique_ptr<llvm::MemoryBuffer> Buffer) { - return A.lexBuffer(std::move(Buffer)); + lexBuffer(TokenBufferTokenManager &TBTM, + std::unique_ptr<llvm::MemoryBuffer> Buffer) { + return TBTM.lexBuffer(std::move(Buffer)); } }; // FIXME: `createLeaf` is based on `syntax::tokenize` internally, as such it // doesn't support digraphs or line continuations. -syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K, - StringRef Spelling) { +syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, + TokenBufferTokenManager &TBTM, + tok::TokenKind K, StringRef Spelling) { auto Tokens = - FactoryImpl::lexBuffer(A, llvm::MemoryBuffer::getMemBufferCopy(Spelling)) + FactoryImpl::lexBuffer(TBTM, llvm::MemoryBuffer::getMemBufferCopy(Spelling)) .second; assert(Tokens.size() == 1); assert(Tokens.front().kind() == K && "spelling is not lexed into the expected kind of token"); - auto *Leaf = new (A.getAllocator()) syntax::Leaf(Tokens.begin()); + auto *Leaf = new (A.getAllocator()) syntax::Leaf( + reinterpret_cast<TokenManager::Key>(Tokens.begin())); syntax::FactoryImpl::setCanModify(Leaf); Leaf->assertInvariants(); return Leaf; } -syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K) { +syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, + TokenBufferTokenManager &TBTM, + tok::TokenKind K) { const auto *Spelling = tok::getPunctuatorSpelling(K); if (!Spelling) Spelling = tok::getKeywordSpelling(K); assert(Spelling && "Cannot infer the spelling of the token from its token kind."); - return createLeaf(A, K, Spelling); + return createLeaf(A, TBTM, K, Spelling); } namespace { @@ -208,24 +215,25 @@ syntax::Tree *clang::syntax::createTree( } syntax::Node *clang::syntax::deepCopyExpandingMacros(syntax::Arena &A, + TokenBufferTokenManager &TBTM, const syntax::Node *N) { if (const auto *L = dyn_cast<syntax::Leaf>(N)) // `L->getToken()` gives us the expanded token, thus we implicitly expand // any macros here. - return createLeaf(A, L->getToken()->kind(), - L->getToken()->text(A.getSourceManager())); + return createLeaf(A, TBTM, TBTM.getToken(L->getTokenKey())->kind(), + TBTM.getText(L->getTokenKey())); const auto *T = cast<syntax::Tree>(N); std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children; for (const auto *Child = T->getFirstChild(); Child; Child = Child->getNextSibling()) - Children.push_back({deepCopyExpandingMacros(A, Child), Child->getRole()}); + Children.push_back({deepCopyExpandingMacros(A, TBTM, Child), Child->getRole()}); return createTree(A, Children, N->getKind()); } -syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) { +syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A, TokenBufferTokenManager &TBTM) { return cast<EmptyStatement>( - createTree(A, {{createLeaf(A, tok::semi), NodeRole::Unknown}}, + createTree(A, {{createLeaf(A, TBTM, tok::semi), NodeRole::Unknown}}, NodeKind::EmptyStatement)); } diff --git a/clang/lib/Tooling/Syntax/TokenBufferTokenManager.cpp b/clang/lib/Tooling/Syntax/TokenBufferTokenManager.cpp new file mode 100644 index 000000000000..a06f7e2900d4 --- /dev/null +++ b/clang/lib/Tooling/Syntax/TokenBufferTokenManager.cpp @@ -0,0 +1,25 @@ +//===- TokenBufferTokenManager.cpp ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/Syntax/TokenBufferTokenManager.h" + +namespace clang { +namespace syntax { +constexpr llvm::StringLiteral syntax::TokenBufferTokenManager::Kind; + +std::pair<FileID, ArrayRef<syntax::Token>> +syntax::TokenBufferTokenManager::lexBuffer( + std::unique_ptr<llvm::MemoryBuffer> Input) { + auto FID = SM.createFileID(std::move(Input)); + auto It = ExtraTokens.try_emplace(FID, tokenize(FID, SM, LangOpts)); + assert(It.second && "duplicate FileID"); + return {FID, It.first->second}; +} + +} // namespace syntax +} // namespace clang diff --git a/clang/lib/Tooling/Syntax/Tree.cpp b/clang/lib/Tooling/Syntax/Tree.cpp index 981bac508f73..20f7bd087aa0 100644 --- a/clang/lib/Tooling/Syntax/Tree.cpp +++ b/clang/lib/Tooling/Syntax/Tree.cpp @@ -8,9 +8,8 @@ #include "clang/Tooling/Syntax/Tree.h" #include "clang/Basic/TokenKinds.h" #include "clang/Tooling/Syntax/Nodes.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Casting.h" #include <cassert> @@ -33,25 +32,7 @@ static void traverse(syntax::Node *N, } } // namespace -syntax::Arena::Arena(SourceManager &SourceMgr, const LangOptions &LangOpts, - const TokenBuffer &Tokens) - : SourceMgr(SourceMgr), LangOpts(LangOpts), Tokens(Tokens) {} - -const syntax::TokenBuffer &syntax::Arena::getTokenBuffer() const { - return Tokens; -} - -std::pair<FileID, ArrayRef<syntax::Token>> -syntax::Arena::lexBuffer(std::unique_ptr<llvm::MemoryBuffer> Input) { - auto FID = SourceMgr.createFileID(std::move(Input)); - auto It = ExtraTokens.try_emplace(FID, tokenize(FID, SourceMgr, LangOpts)); - assert(It.second && "duplicate FileID"); - return {FID, It.first->second}; -} - -syntax::Leaf::Leaf(const syntax::Token *Tok) : Node(NodeKind::Leaf), Tok(Tok) { - assert(Tok != nullptr); -} +syntax::Leaf::Leaf(syntax::TokenManager::Key K) : Node(NodeKind::Leaf), K(K) {} syntax::Node::Node(NodeKind Kind) : Parent(nullptr), NextSibling(nullptr), PreviousSibling(nullptr), @@ -190,20 +171,8 @@ void syntax::Tree::replaceChildRangeLowLevel(Node *Begin, Node *End, } namespace { -static void dumpLeaf(raw_ostream &OS, const syntax::Leaf *L, - const SourceManager &SM) { - assert(L); - const auto *Token = L->getToken(); - assert(Token); - // Handle 'eof' separately, calling text() on it produces an empty string. - if (Token->kind() == tok::eof) - OS << "<eof>"; - else - OS << Token->text(SM); -} - static void dumpNode(raw_ostream &OS, const syntax::Node *N, - const SourceManager &SM, llvm::BitVector IndentMask) { + const syntax::TokenManager &TM, llvm::BitVector IndentMask) { auto DumpExtraInfo = [&OS](const syntax::Node *N) { if (N->getRole() != syntax::NodeRole::Unknown) OS << " " << N->getRole(); @@ -216,7 +185,7 @@ static void dumpNode(raw_ostream &OS, const syntax::Node *N, assert(N); if (const auto *L = dyn_cast<syntax::Leaf>(N)) { OS << "'"; - dumpLeaf(OS, L, SM); + OS << TM.getText(L->getTokenKey()); OS << "'"; DumpExtraInfo(N); OS << "\n"; @@ -242,25 +211,25 @@ static void dumpNode(raw_ostream &OS, const syntax::Node *N, OS << "|-"; IndentMask.push_back(true); } - dumpNode(OS, &It, SM, IndentMask); + dumpNode(OS, &It, TM, IndentMask); IndentMask.pop_back(); } } } // namespace -std::string syntax::Node::dump(const SourceManager &SM) const { +std::string syntax::Node::dump(const TokenManager &TM) const { std::string Str; llvm::raw_string_ostream OS(Str); - dumpNode(OS, this, SM, /*IndentMask=*/{}); + dumpNode(OS, this, TM, /*IndentMask=*/{}); return std::move(OS.str()); } -std::string syntax::Node::dumpTokens(const SourceManager &SM) const { +std::string syntax::Node::dumpTokens(const TokenManager &TM) const { std::string Storage; llvm::raw_string_ostream OS(Storage); traverse(this, [&](const syntax::Node *N) { if (const auto *L = dyn_cast<syntax::Leaf>(N)) { - dumpLeaf(OS, L, SM); + OS << TM.getText(L->getTokenKey()); OS << " "; } }); @@ -297,7 +266,8 @@ void syntax::Node::assertInvariants() const { C.getRole() == NodeRole::ListDelimiter); if (C.getRole() == NodeRole::ListDelimiter) { assert(isa<Leaf>(C)); - assert(cast<Leaf>(C).getToken()->kind() == L->getDelimiterTokenKind()); + // FIXME: re-enable it when there is way to retrieve token kind in Leaf. + // assert(cast<Leaf>(C).getToken()->kind() == L->getDelimiterTokenKind()); } } |