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 @@ -543,10 +543,10 @@ ? (std::next(It)->first - It->first) : A.tokenBuffer().expandedTokens().end() - It->first; - R += std::string( - formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->kind(), - It->first->text(A.sourceManager()), CoveredTokens)); - R += It->second->dump(A); + 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.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 @@ -133,46 +133,45 @@ } namespace { -static void dumpTokens(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 void dumpLeaf(llvm::raw_ostream &OS, 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) + OS << ""; + else + OS << Token->text(SM); } -static void dumpTree(raw_ostream &OS, const syntax::Node *N, - const syntax::Arena &A, 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 = dyn_cast(N)) { - dumpTokens(OS, *L->token(), A.sourceManager()); +static void dumpNode(llvm::raw_ostream &OS, const syntax::Node *N, + const SourceManager &SM, std::vector IndentMask) { + auto dumpExtraInfo = [&OS](const syntax::Node *N) { + if (N->role() != syntax::NodeRole::Unknown) + OS << " " << N->role(); + if (!N->isOriginal()) + OS << " synthesized"; + if (!N->canModify()) + OS << " unmodifiable"; + }; + + assert(N); + if (auto *L = llvm::dyn_cast(N)) { + OS << "'"; + dumpLeaf(OS, L, SM); + OS << "'"; + dumpExtraInfo(N); OS << "\n"; return; } - auto *T = cast(N); - OS << T->kind() << "\n"; + auto *T = llvm::cast(N); + OS << T->kind(); + dumpExtraInfo(N); + OS << "\n"; - for (auto It = T->firstChild(); It != nullptr; It = It->nextSibling()) { + for (const auto *It = T->firstChild(); It; It = It->nextSibling()) { for (bool Filled : IndentMask) { if (Filled) OS << "| "; @@ -186,28 +185,27 @@ 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 = dyn_cast(N); - if (!L) - return; - ::dumpTokens(OS, *L->token(), A.sourceManager()); - OS << " "; + if (auto *L = llvm::dyn_cast(N)) { + dumpLeaf(OS, L, SM); + OS << " "; + } }); return OS.str(); } diff --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp --- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp @@ -24,27 +24,27 @@ void foo() {} )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached |-SimpleDeclaration -| |-int -| |-SimpleDeclarator -| | |-main +| |-'int' +| |-SimpleDeclarator SimpleDeclaration_declarator +| | |-'main' | | `-ParametersAndQualifiers -| | |-( -| | `-) +| | |-'(' OpenParen +| | `-')' CloseParen | `-CompoundStatement -| |-{ -| `-} +| |-'{' OpenParen +| `-'}' CloseParen `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-foo + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'foo' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - `-} + |-'{' OpenParen + `-'}' CloseParen )txt")); } @@ -55,20 +55,20 @@ int b = 42; )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached |-SimpleDeclaration -| |-int -| |-SimpleDeclarator -| | `-a -| `-; +| |-'int' +| |-SimpleDeclarator SimpleDeclaration_declarator +| | `-'a' +| `-';' `-SimpleDeclaration - |-int - |-SimpleDeclarator - | |-b - | |-= + |-'int' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'b' + | |-'=' | `-IntegerLiteralExpression - | `-42 - `-; + | `-'42' LiteralToken + `-';' )txt")); } @@ -78,26 +78,26 @@ void foo(int a, int b) {} )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-foo + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'foo' | `-ParametersAndQualifiers - | |-( - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-a - | |-, - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-b - | `-) + | |-'(' OpenParen + | |-SimpleDeclaration ParametersAndQualifiers_parameter + | | |-'int' + | | `-SimpleDeclarator SimpleDeclaration_declarator + | | `-'a' + | |-',' + | |-SimpleDeclaration ParametersAndQualifiers_parameter + | | |-'int' + | | `-SimpleDeclarator SimpleDeclaration_declarator + | | `-'b' + | `-')' CloseParen `-CompoundStatement - |-{ - `-} + |-'{' OpenParen + `-'}' CloseParen )txt")); } @@ -110,45 +110,45 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-int - |-SimpleDeclarator - | |-main + |-'int' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'main' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-IfStatement - | |-if - | |-( + |-'{' OpenParen + |-IfStatement CompoundStatement_statement + | |-'if' IntroducerKeyword + | |-'(' | |-IntegerLiteralExpression - | | `-1 - | |-) - | `-CompoundStatement - | |-{ - | `-} - |-IfStatement - | |-if - | |-( + | | `-'1' LiteralToken + | |-')' + | `-CompoundStatement IfStatement_thenStatement + | |-'{' OpenParen + | `-'}' CloseParen + |-IfStatement CompoundStatement_statement + | |-'if' IntroducerKeyword + | |-'(' | |-IntegerLiteralExpression - | | `-1 - | |-) - | |-CompoundStatement - | | |-{ - | | `-} - | |-else - | `-IfStatement - | |-if - | |-( + | | `-'1' LiteralToken + | |-')' + | |-CompoundStatement IfStatement_thenStatement + | | |-'{' OpenParen + | | `-'}' CloseParen + | |-'else' IfStatement_elseKeyword + | `-IfStatement IfStatement_elseStatement + | |-'if' IntroducerKeyword + | |-'(' | |-IntegerLiteralExpression - | | `-0 - | |-) - | `-CompoundStatement - | |-{ - | `-} - `-} + | | `-'0' LiteralToken + | |-')' + | `-CompoundStatement IfStatement_thenStatement + | |-'{' OpenParen + | `-'}' CloseParen + `-'}' CloseParen )txt")); } @@ -160,26 +160,26 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-test + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'test' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-ForStatement - | |-for - | |-( - | |-; - | |-; - | |-) - | `-CompoundStatement - | |-{ - | `-} - `-} + |-'{' OpenParen + |-ForStatement CompoundStatement_statement + | |-'for' IntroducerKeyword + | |-'(' + | |-';' + | |-';' + | |-')' + | `-CompoundStatement BodyStatement + | |-'{' OpenParen + | `-'}' CloseParen + `-'}' CloseParen )txt")); } @@ -196,42 +196,42 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-test + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'test' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-DeclarationStatement + |-'{' OpenParen + |-DeclarationStatement CompoundStatement_statement | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | |-a + | | |-'int' + | | `-SimpleDeclarator SimpleDeclaration_declarator + | | |-'a' | | `-ArraySubscript - | | |-[ - | | |-IntegerLiteralExpression - | | | `-3 - | | `-] - | `-; - |-RangeBasedForStatement - | |-for - | |-( + | | |-'[' OpenParen + | | |-IntegerLiteralExpression ArraySubscript_sizeExpression + | | | `-'3' LiteralToken + | | `-']' CloseParen + | `-';' + |-RangeBasedForStatement CompoundStatement_statement + | |-'for' IntroducerKeyword + | |-'(' | |-SimpleDeclaration - | | |-int - | | |-SimpleDeclarator - | | | `-x - | | `-: + | | |-'int' + | | |-SimpleDeclarator SimpleDeclaration_declarator + | | | `-'x' + | | `-':' | |-IdExpression - | | `-UnqualifiedId - | | `-a - | |-) - | `-EmptyStatement - | `-; - `-} + | | `-UnqualifiedId IdExpression_id + | | `-'a' + | |-')' + | `-EmptyStatement BodyStatement + | `-';' + `-'}' CloseParen )txt")); } @@ -243,26 +243,26 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-test + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'test' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-DeclarationStatement + |-'{' OpenParen + |-DeclarationStatement CompoundStatement_statement | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | |-a - | | |-= + | | |-'int' + | | `-SimpleDeclarator SimpleDeclaration_declarator + | | |-'a' + | | |-'=' | | `-IntegerLiteralExpression - | | `-10 - | `-; - `-} + | | `-'10' LiteralToken + | `-';' + `-'}' CloseParen )txt")); } @@ -277,36 +277,36 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-test + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'test' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-SwitchStatement - | |-switch - | |-( + |-'{' OpenParen + |-SwitchStatement CompoundStatement_statement + | |-'switch' IntroducerKeyword + | |-'(' | |-IntegerLiteralExpression - | | `-1 - | |-) - | `-CompoundStatement - | |-{ - | |-CaseStatement - | | |-case - | | |-IntegerLiteralExpression - | | | `-0 - | | |-: - | | `-DefaultStatement - | | |-default - | | |-: - | | `-EmptyStatement - | | `-; - | `-} - `-} + | | `-'1' LiteralToken + | |-')' + | `-CompoundStatement BodyStatement + | |-'{' OpenParen + | |-CaseStatement CompoundStatement_statement + | | |-'case' IntroducerKeyword + | | |-IntegerLiteralExpression CaseStatement_value + | | | `-'0' LiteralToken + | | |-':' + | | `-DefaultStatement BodyStatement + | | |-'default' IntroducerKeyword + | | |-':' + | | `-EmptyStatement BodyStatement + | | `-';' + | `-'}' CloseParen + `-'}' CloseParen )txt")); } @@ -318,32 +318,32 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-test + |-'void' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'test' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-WhileStatement - | |-while - | |-( + |-'{' OpenParen + |-WhileStatement CompoundStatement_statement + | |-'while' IntroducerKeyword + | |-'(' | |-IntegerLiteralExpression - | | `-1 - | |-) - | `-CompoundStatement - | |-{ - | |-ContinueStatement - | | |-continue - | | `-; - | |-BreakStatement - | | |-break - | | `-; - | `-} - `-} + | | `-'1' LiteralToken + | |-')' + | `-CompoundStatement BodyStatement + | |-'{' OpenParen + | |-ContinueStatement CompoundStatement_statement + | | |-'continue' IntroducerKeyword + | | `-';' + | |-BreakStatement CompoundStatement_statement + | | |-'break' IntroducerKeyword + | | `-';' + | `-'}' CloseParen + `-'}' CloseParen )txt")); } @@ -358,25 +358,25 @@ } )cpp", R"txt( -*: TranslationUnit +TranslationUnit Detached `-SimpleDeclaration - |-int - |-SimpleDeclarator - | |-main + |-'int' + |-SimpleDeclarator SimpleDeclaration_declarator + | |-'main' | `-ParametersAndQualifiers - | |-( - | `-) + | |-'(' OpenParen + | `-')' CloseParen `-CompoundStatement - |-{ - |-UnknownStatement - | |-foo - | |-: + |-'{' OpenParen + |-UnknownStatement CompoundStatement_statement + | |-'foo' + | |-':' | `-ReturnStatement - | |-return - | |-IntegerLiteralExpression - | | `-100 - | `-; - `-} + | |-'return' IntroducerKeyword + | |-IntegerLiteralExpression ReturnStatement_value + | | `-'100' LiteralToken + | `-';' + `-'}' CloseParen )txt")); } diff --git a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp --- a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp @@ -171,7 +171,7 @@ << "Source file has syntax errors, they were printed to the test " "log"; } - auto Actual = StringRef(Root->dump(*Arena)).trim().str(); + auto Actual = StringRef(Root->dump(Arena->sourceManager())).trim().str(); // EXPECT_EQ shows the diff between the two strings if they are different. EXPECT_EQ(Tree.trim().str(), Actual); if (Actual != Tree.trim().str()) { @@ -205,7 +205,7 @@ auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], Root); assert(AnnotatedNode); auto AnnotatedNodeDump = - StringRef(AnnotatedNode->dump(*Arena)).trim().str(); + StringRef(AnnotatedNode->dump(Arena->sourceManager())).trim().str(); // EXPECT_EQ shows the diff between the two strings if they are different. EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump) << "Dumps diverged for the code:\n"