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 "CRTPTestVisitor.h"
16 using namespace clang
;
19 class RecordingVisitor
: public CRTPTestVisitor
<RecordingVisitor
> {
23 explicit RecordingVisitor(bool VisitPostOrder
)
24 : VisitPostOrder(VisitPostOrder
) {}
26 // List of visited nodes during traversal.
27 std::vector
<std::string
> VisitedNodes
;
29 bool shouldTraversePostOrder() const { return VisitPostOrder
; }
31 bool VisitUnaryOperator(UnaryOperator
*Op
) {
32 VisitedNodes
.push_back(std::string(Op
->getOpcodeStr(Op
->getOpcode())));
36 bool VisitBinaryOperator(BinaryOperator
*Op
) {
37 VisitedNodes
.push_back(std::string(Op
->getOpcodeStr()));
41 bool VisitIntegerLiteral(IntegerLiteral
*Lit
) {
42 VisitedNodes
.push_back(toString(Lit
->getValue(), 10, false));
46 bool VisitVarDecl(VarDecl
*D
) {
47 VisitedNodes
.push_back(D
->getNameAsString());
51 bool VisitCXXMethodDecl(CXXMethodDecl
*D
) {
52 VisitedNodes
.push_back(D
->getQualifiedNameAsString());
56 bool VisitReturnStmt(ReturnStmt
*S
) {
57 VisitedNodes
.push_back("return");
61 bool VisitCXXRecordDecl(CXXRecordDecl
*D
) {
63 VisitedNodes
.push_back(D
->getQualifiedNameAsString());
67 bool VisitTemplateTypeParmType(TemplateTypeParmType
*T
) {
68 VisitedNodes
.push_back(T
->getDecl()->getQualifiedNameAsString());
74 TEST(RecursiveASTVisitor
, PostOrderTraversal
) {
75 // We traverse the translation unit and store all visited nodes.
76 RecordingVisitor
Visitor(true);
77 Visitor
.runOver("class A {\n"
80 " while(4) { int i = 9; int j = -5; }\n"
81 " return (1 + 3) + 2; }\n"
85 std::vector
<std::string
> expected
= {"4", "9", "i", "5", "-",
86 "j", "1", "3", "+", "2",
87 "+", "return", "A::B::foo", "A::B", "A"};
88 // Compare the list of actually visited nodes with the expected list of
90 ASSERT_EQ(expected
.size(), Visitor
.VisitedNodes
.size());
91 for (std::size_t I
= 0; I
< expected
.size(); I
++) {
92 ASSERT_EQ(expected
[I
], Visitor
.VisitedNodes
[I
]);
96 TEST(RecursiveASTVisitor
, NoPostOrderTraversal
) {
97 // We traverse the translation unit and store all visited nodes.
98 RecordingVisitor
Visitor(false);
99 Visitor
.runOver("class A {\n"
101 " int foo() { return 1 + 2; }\n"
105 std::vector
<std::string
> expected
= {"A", "A::B", "A::B::foo", "return",
107 // Compare the list of actually visited nodes with the expected list of
109 ASSERT_EQ(expected
.size(), Visitor
.VisitedNodes
.size());
110 for (std::size_t I
= 0; I
< expected
.size(); I
++) {
111 ASSERT_EQ(expected
[I
], Visitor
.VisitedNodes
[I
]);