1 //===- unittests/Tooling/RecursiveASTVisitorPostOrderASTVisitor.cpp -------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains tests for the post-order traversing functionality
10 // of RecursiveASTVisitor.
12 //===----------------------------------------------------------------------===//
14 #include "TestVisitor.h"
16 using namespace clang
;
20 class RecordingVisitor
: public TestVisitor
<RecordingVisitor
> {
25 explicit RecordingVisitor(bool VisitPostOrder
)
26 : VisitPostOrder(VisitPostOrder
) {}
28 // List of visited nodes during traversal.
29 std::vector
<std::string
> VisitedNodes
;
31 bool shouldTraversePostOrder() const { return VisitPostOrder
; }
33 bool VisitUnaryOperator(UnaryOperator
*Op
) {
34 VisitedNodes
.push_back(std::string(Op
->getOpcodeStr(Op
->getOpcode())));
38 bool VisitBinaryOperator(BinaryOperator
*Op
) {
39 VisitedNodes
.push_back(std::string(Op
->getOpcodeStr()));
43 bool VisitIntegerLiteral(IntegerLiteral
*Lit
) {
44 VisitedNodes
.push_back(toString(Lit
->getValue(), 10, false));
48 bool VisitVarDecl(VarDecl
*D
) {
49 VisitedNodes
.push_back(D
->getNameAsString());
53 bool VisitCXXMethodDecl(CXXMethodDecl
*D
) {
54 VisitedNodes
.push_back(D
->getQualifiedNameAsString());
58 bool VisitReturnStmt(ReturnStmt
*S
) {
59 VisitedNodes
.push_back("return");
63 bool VisitCXXRecordDecl(CXXRecordDecl
*D
) {
65 VisitedNodes
.push_back(D
->getQualifiedNameAsString());
69 bool VisitTemplateTypeParmType(TemplateTypeParmType
*T
) {
70 VisitedNodes
.push_back(T
->getDecl()->getQualifiedNameAsString());
76 TEST(RecursiveASTVisitor
, PostOrderTraversal
) {
77 // We traverse the translation unit and store all visited nodes.
78 RecordingVisitor
Visitor(true);
79 Visitor
.runOver("class A {\n"
82 " while(4) { int i = 9; int j = -5; }\n"
83 " return (1 + 3) + 2; }\n"
87 std::vector
<std::string
> expected
= {"4", "9", "i", "5", "-",
88 "j", "1", "3", "+", "2",
89 "+", "return", "A::B::foo", "A::B", "A"};
90 // Compare the list of actually visited nodes with the expected list of
92 ASSERT_EQ(expected
.size(), Visitor
.VisitedNodes
.size());
93 for (std::size_t I
= 0; I
< expected
.size(); I
++) {
94 ASSERT_EQ(expected
[I
], Visitor
.VisitedNodes
[I
]);
98 TEST(RecursiveASTVisitor
, NoPostOrderTraversal
) {
99 // We traverse the translation unit and store all visited nodes.
100 RecordingVisitor
Visitor(false);
101 Visitor
.runOver("class A {\n"
103 " int foo() { return 1 + 2; }\n"
107 std::vector
<std::string
> expected
= {"A", "A::B", "A::B::foo", "return",
109 // Compare the list of actually visited nodes with the expected list of
111 ASSERT_EQ(expected
.size(), Visitor
.VisitedNodes
.size());
112 for (std::size_t I
= 0; I
< expected
.size(); I
++) {
113 ASSERT_EQ(expected
[I
], Visitor
.VisitedNodes
[I
]);