1 //===--- clang/unittests/Tooling/RecursiveASTVisitorTests/Callbacks.cpp ---===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TestVisitor.h"
10 
11 using namespace clang;
12 
13 namespace {
14 
15 enum class ShouldTraversePostOrder : bool {
16   No = false,
17   Yes = true,
18 };
19 
20 /// Base class for tests for RecursiveASTVisitor tests that validate the
21 /// sequence of calls to user-defined callbacks like Traverse*(), WalkUp*(),
22 /// Visit*().
23 template <typename Derived>
24 class RecordingVisitorBase : public TestVisitor<Derived> {
25   ShouldTraversePostOrder ShouldTraversePostOrderValue;
26 
27 public:
RecordingVisitorBase(ShouldTraversePostOrder ShouldTraversePostOrderValue)28   RecordingVisitorBase(ShouldTraversePostOrder ShouldTraversePostOrderValue)
29       : ShouldTraversePostOrderValue(ShouldTraversePostOrderValue) {}
30 
shouldTraversePostOrder() const31   bool shouldTraversePostOrder() const {
32     return static_cast<bool>(ShouldTraversePostOrderValue);
33   }
34 
35   // Callbacks received during traversal.
36   std::string CallbackLog;
37   unsigned CallbackLogIndent = 0;
38 
stmtToString(Stmt * S)39   std::string stmtToString(Stmt *S) {
40     StringRef ClassName = S->getStmtClassName();
41     if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(S)) {
42       return (ClassName + "(" + IL->getValue().toString(10, false) + ")").str();
43     }
44     if (UnaryOperator *UO = dyn_cast<UnaryOperator>(S)) {
45       return (ClassName + "(" + UnaryOperator::getOpcodeStr(UO->getOpcode()) +
46               ")")
47           .str();
48     }
49     if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
50       return (ClassName + "(" + BinaryOperator::getOpcodeStr(BO->getOpcode()) +
51               ")")
52           .str();
53     }
54     if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
55       if (FunctionDecl *Callee = CE->getDirectCallee()) {
56         if (Callee->getIdentifier()) {
57           return (ClassName + "(" + Callee->getName() + ")").str();
58         }
59       }
60     }
61     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
62       if (NamedDecl *ND = DRE->getFoundDecl()) {
63         if (ND->getIdentifier()) {
64           return (ClassName + "(" + ND->getName() + ")").str();
65         }
66       }
67     }
68     return ClassName.str();
69   }
70 
71   /// Record the fact that the user-defined callback member function
72   /// \p CallbackName was called with the argument \p S. Then, record the
73   /// effects of calling the default implementation \p CallDefaultFn.
74   template <typename CallDefault>
recordCallback(StringRef CallbackName,Stmt * S,CallDefault CallDefaultFn)75   void recordCallback(StringRef CallbackName, Stmt *S,
76                       CallDefault CallDefaultFn) {
77     for (unsigned i = 0; i != CallbackLogIndent; ++i) {
78       CallbackLog += "  ";
79     }
80     CallbackLog += (CallbackName + " " + stmtToString(S) + "\n").str();
81     ++CallbackLogIndent;
82     CallDefaultFn();
83     --CallbackLogIndent;
84   }
85 };
86 
87 template <typename VisitorTy>
visitorCallbackLogEqual(VisitorTy Visitor,StringRef Code,StringRef ExpectedLog)88 ::testing::AssertionResult visitorCallbackLogEqual(VisitorTy Visitor,
89                                                    StringRef Code,
90                                                    StringRef ExpectedLog) {
91   Visitor.runOver(Code);
92   // EXPECT_EQ shows the diff between the two strings if they are different.
93   EXPECT_EQ(ExpectedLog.trim().str(),
94             StringRef(Visitor.CallbackLog).trim().str());
95   if (ExpectedLog.trim() != StringRef(Visitor.CallbackLog).trim()) {
96     return ::testing::AssertionFailure();
97   }
98   return ::testing::AssertionSuccess();
99 }
100 
101 } // namespace
102 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseLeaf)103 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseLeaf) {
104   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
105   public:
106     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
107         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
108 
109     bool TraverseIntegerLiteral(IntegerLiteral *IL) {
110       recordCallback(__func__, IL, [&]() {
111         RecordingVisitorBase::TraverseIntegerLiteral(IL);
112       });
113       return true;
114     }
115 
116     bool WalkUpFromStmt(Stmt *S) {
117       recordCallback(__func__, S,
118                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
119       return true;
120     }
121   };
122 
123   StringRef Code = R"cpp(
124 void add(int, int);
125 void test() {
126   1;
127   2 + 3;
128   add(4, 5);
129 }
130 )cpp";
131 
132   EXPECT_TRUE(visitorCallbackLogEqual(
133       RecordingVisitor(ShouldTraversePostOrder::No), Code,
134       R"txt(
135 WalkUpFromStmt CompoundStmt
136 TraverseIntegerLiteral IntegerLiteral(1)
137   WalkUpFromStmt IntegerLiteral(1)
138 WalkUpFromStmt BinaryOperator(+)
139 TraverseIntegerLiteral IntegerLiteral(2)
140   WalkUpFromStmt IntegerLiteral(2)
141 TraverseIntegerLiteral IntegerLiteral(3)
142   WalkUpFromStmt IntegerLiteral(3)
143 WalkUpFromStmt CallExpr(add)
144 WalkUpFromStmt ImplicitCastExpr
145 WalkUpFromStmt DeclRefExpr(add)
146 TraverseIntegerLiteral IntegerLiteral(4)
147   WalkUpFromStmt IntegerLiteral(4)
148 TraverseIntegerLiteral IntegerLiteral(5)
149   WalkUpFromStmt IntegerLiteral(5)
150 )txt"));
151 
152   EXPECT_TRUE(visitorCallbackLogEqual(
153       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
154       R"txt(
155 TraverseIntegerLiteral IntegerLiteral(1)
156   WalkUpFromStmt IntegerLiteral(1)
157 TraverseIntegerLiteral IntegerLiteral(2)
158   WalkUpFromStmt IntegerLiteral(2)
159 TraverseIntegerLiteral IntegerLiteral(3)
160   WalkUpFromStmt IntegerLiteral(3)
161 WalkUpFromStmt BinaryOperator(+)
162 WalkUpFromStmt DeclRefExpr(add)
163 WalkUpFromStmt ImplicitCastExpr
164 TraverseIntegerLiteral IntegerLiteral(4)
165   WalkUpFromStmt IntegerLiteral(4)
166 TraverseIntegerLiteral IntegerLiteral(5)
167   WalkUpFromStmt IntegerLiteral(5)
168 WalkUpFromStmt CallExpr(add)
169 WalkUpFromStmt CompoundStmt
170 )txt"));
171 }
172 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseLeaf_WalkUpFromLeaf)173 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseLeaf_WalkUpFromLeaf) {
174   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
175   public:
176     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
177         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
178 
179     bool TraverseIntegerLiteral(IntegerLiteral *IL) {
180       recordCallback(__func__, IL, [&]() {
181         RecordingVisitorBase::TraverseIntegerLiteral(IL);
182       });
183       return true;
184     }
185 
186     bool WalkUpFromStmt(Stmt *S) {
187       recordCallback(__func__, S,
188                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
189       return true;
190     }
191 
192     bool WalkUpFromExpr(Expr *E) {
193       recordCallback(__func__, E,
194                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
195       return true;
196     }
197 
198     bool WalkUpFromIntegerLiteral(IntegerLiteral *IL) {
199       recordCallback(__func__, IL, [&]() {
200         RecordingVisitorBase::WalkUpFromIntegerLiteral(IL);
201       });
202       return true;
203     }
204   };
205 
206   StringRef Code = R"cpp(
207 void add(int, int);
208 void test() {
209   1;
210   2 + 3;
211   add(4, 5);
212 }
213 )cpp";
214 
215   EXPECT_TRUE(visitorCallbackLogEqual(
216       RecordingVisitor(ShouldTraversePostOrder::No), Code,
217       R"txt(
218 WalkUpFromStmt CompoundStmt
219 TraverseIntegerLiteral IntegerLiteral(1)
220   WalkUpFromIntegerLiteral IntegerLiteral(1)
221     WalkUpFromExpr IntegerLiteral(1)
222       WalkUpFromStmt IntegerLiteral(1)
223 WalkUpFromExpr BinaryOperator(+)
224   WalkUpFromStmt BinaryOperator(+)
225 TraverseIntegerLiteral IntegerLiteral(2)
226   WalkUpFromIntegerLiteral IntegerLiteral(2)
227     WalkUpFromExpr IntegerLiteral(2)
228       WalkUpFromStmt IntegerLiteral(2)
229 TraverseIntegerLiteral IntegerLiteral(3)
230   WalkUpFromIntegerLiteral IntegerLiteral(3)
231     WalkUpFromExpr IntegerLiteral(3)
232       WalkUpFromStmt IntegerLiteral(3)
233 WalkUpFromExpr CallExpr(add)
234   WalkUpFromStmt CallExpr(add)
235 WalkUpFromExpr ImplicitCastExpr
236   WalkUpFromStmt ImplicitCastExpr
237 WalkUpFromExpr DeclRefExpr(add)
238   WalkUpFromStmt DeclRefExpr(add)
239 TraverseIntegerLiteral IntegerLiteral(4)
240   WalkUpFromIntegerLiteral IntegerLiteral(4)
241     WalkUpFromExpr IntegerLiteral(4)
242       WalkUpFromStmt IntegerLiteral(4)
243 TraverseIntegerLiteral IntegerLiteral(5)
244   WalkUpFromIntegerLiteral IntegerLiteral(5)
245     WalkUpFromExpr IntegerLiteral(5)
246       WalkUpFromStmt IntegerLiteral(5)
247 )txt"));
248 
249   EXPECT_TRUE(visitorCallbackLogEqual(
250       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
251       R"txt(
252 TraverseIntegerLiteral IntegerLiteral(1)
253   WalkUpFromIntegerLiteral IntegerLiteral(1)
254     WalkUpFromExpr IntegerLiteral(1)
255       WalkUpFromStmt IntegerLiteral(1)
256 TraverseIntegerLiteral IntegerLiteral(2)
257   WalkUpFromIntegerLiteral IntegerLiteral(2)
258     WalkUpFromExpr IntegerLiteral(2)
259       WalkUpFromStmt IntegerLiteral(2)
260 TraverseIntegerLiteral IntegerLiteral(3)
261   WalkUpFromIntegerLiteral IntegerLiteral(3)
262     WalkUpFromExpr IntegerLiteral(3)
263       WalkUpFromStmt IntegerLiteral(3)
264 WalkUpFromExpr BinaryOperator(+)
265   WalkUpFromStmt BinaryOperator(+)
266 WalkUpFromExpr DeclRefExpr(add)
267   WalkUpFromStmt DeclRefExpr(add)
268 WalkUpFromExpr ImplicitCastExpr
269   WalkUpFromStmt ImplicitCastExpr
270 TraverseIntegerLiteral IntegerLiteral(4)
271   WalkUpFromIntegerLiteral IntegerLiteral(4)
272     WalkUpFromExpr IntegerLiteral(4)
273       WalkUpFromStmt IntegerLiteral(4)
274 TraverseIntegerLiteral IntegerLiteral(5)
275   WalkUpFromIntegerLiteral IntegerLiteral(5)
276     WalkUpFromExpr IntegerLiteral(5)
277       WalkUpFromStmt IntegerLiteral(5)
278 WalkUpFromExpr CallExpr(add)
279   WalkUpFromStmt CallExpr(add)
280 WalkUpFromStmt CompoundStmt
281 )txt"));
282 }
283 
TEST(RecursiveASTVisitor,StmtCallbacks_WalkUpFromLeaf)284 TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromLeaf) {
285   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
286   public:
287     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
288         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
289 
290     bool WalkUpFromStmt(Stmt *S) {
291       recordCallback(__func__, S,
292                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
293       return true;
294     }
295 
296     bool WalkUpFromExpr(Expr *E) {
297       recordCallback(__func__, E,
298                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
299       return true;
300     }
301 
302     bool WalkUpFromIntegerLiteral(IntegerLiteral *IL) {
303       recordCallback(__func__, IL, [&]() {
304         RecordingVisitorBase::WalkUpFromIntegerLiteral(IL);
305       });
306       return true;
307     }
308   };
309 
310   StringRef Code = R"cpp(
311 void add(int, int);
312 void test() {
313   1;
314   2 + 3;
315   add(4, 5);
316 }
317 )cpp";
318 
319   EXPECT_TRUE(visitorCallbackLogEqual(
320       RecordingVisitor(ShouldTraversePostOrder::No), Code,
321       R"txt(
322 WalkUpFromStmt CompoundStmt
323 WalkUpFromIntegerLiteral IntegerLiteral(1)
324   WalkUpFromExpr IntegerLiteral(1)
325     WalkUpFromStmt IntegerLiteral(1)
326 WalkUpFromExpr BinaryOperator(+)
327   WalkUpFromStmt BinaryOperator(+)
328 WalkUpFromIntegerLiteral IntegerLiteral(2)
329   WalkUpFromExpr IntegerLiteral(2)
330     WalkUpFromStmt IntegerLiteral(2)
331 WalkUpFromIntegerLiteral IntegerLiteral(3)
332   WalkUpFromExpr IntegerLiteral(3)
333     WalkUpFromStmt IntegerLiteral(3)
334 WalkUpFromExpr CallExpr(add)
335   WalkUpFromStmt CallExpr(add)
336 WalkUpFromExpr ImplicitCastExpr
337   WalkUpFromStmt ImplicitCastExpr
338 WalkUpFromExpr DeclRefExpr(add)
339   WalkUpFromStmt DeclRefExpr(add)
340 WalkUpFromIntegerLiteral IntegerLiteral(4)
341   WalkUpFromExpr IntegerLiteral(4)
342     WalkUpFromStmt IntegerLiteral(4)
343 WalkUpFromIntegerLiteral IntegerLiteral(5)
344   WalkUpFromExpr IntegerLiteral(5)
345     WalkUpFromStmt IntegerLiteral(5)
346 )txt"));
347 
348   EXPECT_TRUE(visitorCallbackLogEqual(
349       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
350       R"txt(
351 WalkUpFromIntegerLiteral IntegerLiteral(1)
352   WalkUpFromExpr IntegerLiteral(1)
353     WalkUpFromStmt IntegerLiteral(1)
354 WalkUpFromIntegerLiteral IntegerLiteral(2)
355   WalkUpFromExpr IntegerLiteral(2)
356     WalkUpFromStmt IntegerLiteral(2)
357 WalkUpFromIntegerLiteral IntegerLiteral(3)
358   WalkUpFromExpr IntegerLiteral(3)
359     WalkUpFromStmt IntegerLiteral(3)
360 WalkUpFromExpr BinaryOperator(+)
361   WalkUpFromStmt BinaryOperator(+)
362 WalkUpFromExpr DeclRefExpr(add)
363   WalkUpFromStmt DeclRefExpr(add)
364 WalkUpFromExpr ImplicitCastExpr
365   WalkUpFromStmt ImplicitCastExpr
366 WalkUpFromIntegerLiteral IntegerLiteral(4)
367   WalkUpFromExpr IntegerLiteral(4)
368     WalkUpFromStmt IntegerLiteral(4)
369 WalkUpFromIntegerLiteral IntegerLiteral(5)
370   WalkUpFromExpr IntegerLiteral(5)
371     WalkUpFromStmt IntegerLiteral(5)
372 WalkUpFromExpr CallExpr(add)
373   WalkUpFromStmt CallExpr(add)
374 WalkUpFromStmt CompoundStmt
375 )txt"));
376 }
377 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseUnaryOperator)378 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseUnaryOperator) {
379   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
380   public:
381     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
382         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
383 
384     bool TraverseUnaryOperator(UnaryOperator *UO) {
385       recordCallback(__func__, UO, [&]() {
386         RecordingVisitorBase::TraverseUnaryOperator(UO);
387       });
388       return true;
389     }
390 
391     bool WalkUpFromStmt(Stmt *S) {
392       recordCallback(__func__, S,
393                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
394       return true;
395     }
396   };
397 
398   StringRef Code = R"cpp(
399 void test() {
400   1;
401   -2;
402   3;
403 }
404 )cpp";
405 
406   EXPECT_TRUE(visitorCallbackLogEqual(
407       RecordingVisitor(ShouldTraversePostOrder::No), Code,
408       R"txt(
409 WalkUpFromStmt CompoundStmt
410 WalkUpFromStmt IntegerLiteral(1)
411 TraverseUnaryOperator UnaryOperator(-)
412   WalkUpFromStmt UnaryOperator(-)
413   WalkUpFromStmt IntegerLiteral(2)
414 WalkUpFromStmt IntegerLiteral(3)
415 )txt"));
416 
417   EXPECT_TRUE(visitorCallbackLogEqual(
418       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
419       R"txt(
420 WalkUpFromStmt IntegerLiteral(1)
421 TraverseUnaryOperator UnaryOperator(-)
422   WalkUpFromStmt IntegerLiteral(2)
423   WalkUpFromStmt UnaryOperator(-)
424 WalkUpFromStmt IntegerLiteral(3)
425 WalkUpFromStmt CompoundStmt
426 )txt"));
427 }
428 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseUnaryOperator_WalkUpFromUnaryOperator)429 TEST(RecursiveASTVisitor,
430      StmtCallbacks_TraverseUnaryOperator_WalkUpFromUnaryOperator) {
431   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
432   public:
433     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
434         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
435 
436     bool TraverseUnaryOperator(UnaryOperator *UO) {
437       recordCallback(__func__, UO, [&]() {
438         RecordingVisitorBase::TraverseUnaryOperator(UO);
439       });
440       return true;
441     }
442 
443     bool WalkUpFromStmt(Stmt *S) {
444       recordCallback(__func__, S,
445                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
446       return true;
447     }
448 
449     bool WalkUpFromExpr(Expr *E) {
450       recordCallback(__func__, E,
451                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
452       return true;
453     }
454 
455     bool WalkUpFromUnaryOperator(UnaryOperator *UO) {
456       recordCallback(__func__, UO, [&]() {
457         RecordingVisitorBase::WalkUpFromUnaryOperator(UO);
458       });
459       return true;
460     }
461   };
462 
463   StringRef Code = R"cpp(
464 void test() {
465   1;
466   -2;
467   3;
468 }
469 )cpp";
470 
471   EXPECT_TRUE(visitorCallbackLogEqual(
472       RecordingVisitor(ShouldTraversePostOrder::No), Code,
473       R"txt(
474 WalkUpFromStmt CompoundStmt
475 WalkUpFromExpr IntegerLiteral(1)
476   WalkUpFromStmt IntegerLiteral(1)
477 TraverseUnaryOperator UnaryOperator(-)
478   WalkUpFromUnaryOperator UnaryOperator(-)
479     WalkUpFromExpr UnaryOperator(-)
480       WalkUpFromStmt UnaryOperator(-)
481   WalkUpFromExpr IntegerLiteral(2)
482     WalkUpFromStmt IntegerLiteral(2)
483 WalkUpFromExpr IntegerLiteral(3)
484   WalkUpFromStmt IntegerLiteral(3)
485 )txt"));
486 
487   EXPECT_TRUE(visitorCallbackLogEqual(
488       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
489       R"txt(
490 WalkUpFromExpr IntegerLiteral(1)
491   WalkUpFromStmt IntegerLiteral(1)
492 TraverseUnaryOperator UnaryOperator(-)
493   WalkUpFromExpr IntegerLiteral(2)
494     WalkUpFromStmt IntegerLiteral(2)
495   WalkUpFromUnaryOperator UnaryOperator(-)
496     WalkUpFromExpr UnaryOperator(-)
497       WalkUpFromStmt UnaryOperator(-)
498 WalkUpFromExpr IntegerLiteral(3)
499   WalkUpFromStmt IntegerLiteral(3)
500 WalkUpFromStmt CompoundStmt
501 )txt"));
502 }
503 
TEST(RecursiveASTVisitor,StmtCallbacks_WalkUpFromUnaryOperator)504 TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromUnaryOperator) {
505   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
506   public:
507     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
508         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
509 
510     bool WalkUpFromStmt(Stmt *S) {
511       recordCallback(__func__, S,
512                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
513       return true;
514     }
515 
516     bool WalkUpFromExpr(Expr *E) {
517       recordCallback(__func__, E,
518                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
519       return true;
520     }
521 
522     bool WalkUpFromUnaryOperator(UnaryOperator *UO) {
523       recordCallback(__func__, UO, [&]() {
524         RecordingVisitorBase::WalkUpFromUnaryOperator(UO);
525       });
526       return true;
527     }
528   };
529 
530   StringRef Code = R"cpp(
531 void test() {
532   1;
533   -2;
534   3;
535 }
536 )cpp";
537 
538   EXPECT_TRUE(visitorCallbackLogEqual(
539       RecordingVisitor(ShouldTraversePostOrder::No), Code,
540       R"txt(
541 WalkUpFromStmt CompoundStmt
542 WalkUpFromExpr IntegerLiteral(1)
543   WalkUpFromStmt IntegerLiteral(1)
544 WalkUpFromUnaryOperator UnaryOperator(-)
545   WalkUpFromExpr UnaryOperator(-)
546     WalkUpFromStmt UnaryOperator(-)
547 WalkUpFromExpr IntegerLiteral(2)
548   WalkUpFromStmt IntegerLiteral(2)
549 WalkUpFromExpr IntegerLiteral(3)
550   WalkUpFromStmt IntegerLiteral(3)
551 )txt"));
552 
553   EXPECT_TRUE(visitorCallbackLogEqual(
554       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
555       R"txt(
556 WalkUpFromExpr IntegerLiteral(1)
557   WalkUpFromStmt IntegerLiteral(1)
558 WalkUpFromExpr IntegerLiteral(2)
559   WalkUpFromStmt IntegerLiteral(2)
560 WalkUpFromUnaryOperator UnaryOperator(-)
561   WalkUpFromExpr UnaryOperator(-)
562     WalkUpFromStmt UnaryOperator(-)
563 WalkUpFromExpr IntegerLiteral(3)
564   WalkUpFromStmt IntegerLiteral(3)
565 WalkUpFromStmt CompoundStmt
566 )txt"));
567 }
568 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseBinaryOperator)569 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseBinaryOperator) {
570   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
571   public:
572     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
573         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
574 
575     bool TraverseBinaryOperator(BinaryOperator *BO) {
576       recordCallback(__func__, BO, [&]() {
577         RecordingVisitorBase::TraverseBinaryOperator(BO);
578       });
579       return true;
580     }
581 
582     bool WalkUpFromStmt(Stmt *S) {
583       recordCallback(__func__, S,
584                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
585       return true;
586     }
587   };
588 
589   StringRef Code = R"cpp(
590 void test() {
591   1;
592   2 + 3;
593   4;
594 }
595 )cpp";
596 
597   EXPECT_TRUE(visitorCallbackLogEqual(
598       RecordingVisitor(ShouldTraversePostOrder::No), Code,
599       R"txt(
600 WalkUpFromStmt CompoundStmt
601 WalkUpFromStmt IntegerLiteral(1)
602 TraverseBinaryOperator BinaryOperator(+)
603   WalkUpFromStmt BinaryOperator(+)
604   WalkUpFromStmt IntegerLiteral(2)
605   WalkUpFromStmt IntegerLiteral(3)
606 WalkUpFromStmt IntegerLiteral(4)
607 )txt"));
608 
609   EXPECT_TRUE(visitorCallbackLogEqual(
610       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
611       R"txt(
612 WalkUpFromStmt IntegerLiteral(1)
613 TraverseBinaryOperator BinaryOperator(+)
614   WalkUpFromStmt IntegerLiteral(2)
615   WalkUpFromStmt IntegerLiteral(3)
616   WalkUpFromStmt BinaryOperator(+)
617 WalkUpFromStmt IntegerLiteral(4)
618 WalkUpFromStmt CompoundStmt
619 )txt"));
620 }
621 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseBinaryOperator_WalkUpFromBinaryOperator)622 TEST(RecursiveASTVisitor,
623      StmtCallbacks_TraverseBinaryOperator_WalkUpFromBinaryOperator) {
624   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
625   public:
626     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
627         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
628 
629     bool TraverseBinaryOperator(BinaryOperator *BO) {
630       recordCallback(__func__, BO, [&]() {
631         RecordingVisitorBase::TraverseBinaryOperator(BO);
632       });
633       return true;
634     }
635 
636     bool WalkUpFromStmt(Stmt *S) {
637       recordCallback(__func__, S,
638                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
639       return true;
640     }
641 
642     bool WalkUpFromExpr(Expr *E) {
643       recordCallback(__func__, E,
644                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
645       return true;
646     }
647 
648     bool WalkUpFromBinaryOperator(BinaryOperator *BO) {
649       recordCallback(__func__, BO, [&]() {
650         RecordingVisitorBase::WalkUpFromBinaryOperator(BO);
651       });
652       return true;
653     }
654   };
655 
656   StringRef Code = R"cpp(
657 void test() {
658   1;
659   2 + 3;
660   4;
661 }
662 )cpp";
663 
664   EXPECT_TRUE(visitorCallbackLogEqual(
665       RecordingVisitor(ShouldTraversePostOrder::No), Code,
666       R"txt(
667 WalkUpFromStmt CompoundStmt
668 WalkUpFromExpr IntegerLiteral(1)
669   WalkUpFromStmt IntegerLiteral(1)
670 TraverseBinaryOperator BinaryOperator(+)
671   WalkUpFromBinaryOperator BinaryOperator(+)
672     WalkUpFromExpr BinaryOperator(+)
673       WalkUpFromStmt BinaryOperator(+)
674   WalkUpFromExpr IntegerLiteral(2)
675     WalkUpFromStmt IntegerLiteral(2)
676   WalkUpFromExpr IntegerLiteral(3)
677     WalkUpFromStmt IntegerLiteral(3)
678 WalkUpFromExpr IntegerLiteral(4)
679   WalkUpFromStmt IntegerLiteral(4)
680 )txt"));
681 
682   EXPECT_TRUE(visitorCallbackLogEqual(
683       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
684       R"txt(
685 WalkUpFromExpr IntegerLiteral(1)
686   WalkUpFromStmt IntegerLiteral(1)
687 TraverseBinaryOperator BinaryOperator(+)
688   WalkUpFromExpr IntegerLiteral(2)
689     WalkUpFromStmt IntegerLiteral(2)
690   WalkUpFromExpr IntegerLiteral(3)
691     WalkUpFromStmt IntegerLiteral(3)
692   WalkUpFromBinaryOperator BinaryOperator(+)
693     WalkUpFromExpr BinaryOperator(+)
694       WalkUpFromStmt BinaryOperator(+)
695 WalkUpFromExpr IntegerLiteral(4)
696   WalkUpFromStmt IntegerLiteral(4)
697 WalkUpFromStmt CompoundStmt
698 )txt"));
699 }
700 
TEST(RecursiveASTVisitor,StmtCallbacks_WalkUpFromBinaryOperator)701 TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromBinaryOperator) {
702   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
703   public:
704     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
705         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
706 
707     bool WalkUpFromStmt(Stmt *S) {
708       recordCallback(__func__, S,
709                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
710       return true;
711     }
712 
713     bool WalkUpFromExpr(Expr *E) {
714       recordCallback(__func__, E,
715                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
716       return true;
717     }
718 
719     bool WalkUpFromBinaryOperator(BinaryOperator *BO) {
720       recordCallback(__func__, BO, [&]() {
721         RecordingVisitorBase::WalkUpFromBinaryOperator(BO);
722       });
723       return true;
724     }
725   };
726 
727   StringRef Code = R"cpp(
728 void test() {
729   1;
730   2 + 3;
731   4;
732 }
733 )cpp";
734 
735   EXPECT_TRUE(visitorCallbackLogEqual(
736       RecordingVisitor(ShouldTraversePostOrder::No), Code,
737       R"txt(
738 WalkUpFromStmt CompoundStmt
739 WalkUpFromExpr IntegerLiteral(1)
740   WalkUpFromStmt IntegerLiteral(1)
741 WalkUpFromBinaryOperator BinaryOperator(+)
742   WalkUpFromExpr BinaryOperator(+)
743     WalkUpFromStmt BinaryOperator(+)
744 WalkUpFromExpr IntegerLiteral(2)
745   WalkUpFromStmt IntegerLiteral(2)
746 WalkUpFromExpr IntegerLiteral(3)
747   WalkUpFromStmt IntegerLiteral(3)
748 WalkUpFromExpr IntegerLiteral(4)
749   WalkUpFromStmt IntegerLiteral(4)
750 )txt"));
751 
752   EXPECT_TRUE(visitorCallbackLogEqual(
753       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
754       R"txt(
755 WalkUpFromExpr IntegerLiteral(1)
756   WalkUpFromStmt IntegerLiteral(1)
757 WalkUpFromExpr IntegerLiteral(2)
758   WalkUpFromStmt IntegerLiteral(2)
759 WalkUpFromExpr IntegerLiteral(3)
760   WalkUpFromStmt IntegerLiteral(3)
761 WalkUpFromBinaryOperator BinaryOperator(+)
762   WalkUpFromExpr BinaryOperator(+)
763     WalkUpFromStmt BinaryOperator(+)
764 WalkUpFromExpr IntegerLiteral(4)
765   WalkUpFromStmt IntegerLiteral(4)
766 WalkUpFromStmt CompoundStmt
767 )txt"));
768 }
769 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseCompoundAssignOperator)770 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseCompoundAssignOperator) {
771   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
772   public:
773     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
774         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
775 
776     bool TraverseCompoundAssignOperator(CompoundAssignOperator *CAO) {
777       recordCallback(__func__, CAO, [&]() {
778         RecordingVisitorBase::TraverseCompoundAssignOperator(CAO);
779       });
780       return true;
781     }
782 
783     bool WalkUpFromStmt(Stmt *S) {
784       recordCallback(__func__, S,
785                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
786       return true;
787     }
788   };
789 
790   StringRef Code = R"cpp(
791 void test(int a) {
792   1;
793   a += 2;
794   3;
795 }
796 )cpp";
797 
798   EXPECT_TRUE(visitorCallbackLogEqual(
799       RecordingVisitor(ShouldTraversePostOrder::No), Code,
800       R"txt(
801 WalkUpFromStmt CompoundStmt
802 WalkUpFromStmt IntegerLiteral(1)
803 TraverseCompoundAssignOperator CompoundAssignOperator(+=)
804   WalkUpFromStmt CompoundAssignOperator(+=)
805   WalkUpFromStmt DeclRefExpr(a)
806   WalkUpFromStmt IntegerLiteral(2)
807 WalkUpFromStmt IntegerLiteral(3)
808 )txt"));
809 
810   EXPECT_TRUE(visitorCallbackLogEqual(
811       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
812       R"txt(
813 WalkUpFromStmt IntegerLiteral(1)
814 TraverseCompoundAssignOperator CompoundAssignOperator(+=)
815   WalkUpFromStmt DeclRefExpr(a)
816   WalkUpFromStmt IntegerLiteral(2)
817   WalkUpFromStmt CompoundAssignOperator(+=)
818 WalkUpFromStmt IntegerLiteral(3)
819 WalkUpFromStmt CompoundStmt
820 )txt"));
821 }
822 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseCompoundAssignOperator_WalkUpFromCompoundAssignOperator)823 TEST(
824     RecursiveASTVisitor,
825     StmtCallbacks_TraverseCompoundAssignOperator_WalkUpFromCompoundAssignOperator) {
826   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
827   public:
828     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
829         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
830 
831     bool TraverseCompoundAssignOperator(CompoundAssignOperator *CAO) {
832       recordCallback(__func__, CAO, [&]() {
833         RecordingVisitorBase::TraverseCompoundAssignOperator(CAO);
834       });
835       return true;
836     }
837 
838     bool WalkUpFromStmt(Stmt *S) {
839       recordCallback(__func__, S,
840                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
841       return true;
842     }
843 
844     bool WalkUpFromExpr(Expr *E) {
845       recordCallback(__func__, E,
846                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
847       return true;
848     }
849 
850     bool WalkUpFromCompoundAssignOperator(CompoundAssignOperator *CAO) {
851       recordCallback(__func__, CAO, [&]() {
852         RecordingVisitorBase::WalkUpFromCompoundAssignOperator(CAO);
853       });
854       return true;
855     }
856   };
857 
858   StringRef Code = R"cpp(
859 void test(int a) {
860   1;
861   a += 2;
862   3;
863 }
864 )cpp";
865 
866   EXPECT_TRUE(visitorCallbackLogEqual(
867       RecordingVisitor(ShouldTraversePostOrder::No), Code,
868       R"txt(
869 WalkUpFromStmt CompoundStmt
870 WalkUpFromExpr IntegerLiteral(1)
871   WalkUpFromStmt IntegerLiteral(1)
872 TraverseCompoundAssignOperator CompoundAssignOperator(+=)
873   WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=)
874     WalkUpFromExpr CompoundAssignOperator(+=)
875       WalkUpFromStmt CompoundAssignOperator(+=)
876   WalkUpFromExpr DeclRefExpr(a)
877     WalkUpFromStmt DeclRefExpr(a)
878   WalkUpFromExpr IntegerLiteral(2)
879     WalkUpFromStmt IntegerLiteral(2)
880 WalkUpFromExpr IntegerLiteral(3)
881   WalkUpFromStmt IntegerLiteral(3)
882 )txt"));
883 
884   EXPECT_TRUE(visitorCallbackLogEqual(
885       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
886       R"txt(
887 WalkUpFromExpr IntegerLiteral(1)
888   WalkUpFromStmt IntegerLiteral(1)
889 TraverseCompoundAssignOperator CompoundAssignOperator(+=)
890   WalkUpFromExpr DeclRefExpr(a)
891     WalkUpFromStmt DeclRefExpr(a)
892   WalkUpFromExpr IntegerLiteral(2)
893     WalkUpFromStmt IntegerLiteral(2)
894   WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=)
895     WalkUpFromExpr CompoundAssignOperator(+=)
896       WalkUpFromStmt CompoundAssignOperator(+=)
897 WalkUpFromExpr IntegerLiteral(3)
898   WalkUpFromStmt IntegerLiteral(3)
899 WalkUpFromStmt CompoundStmt
900 )txt"));
901 }
902 
TEST(RecursiveASTVisitor,StmtCallbacks_WalkUpFromCompoundAssignOperator)903 TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromCompoundAssignOperator) {
904   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
905   public:
906     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
907         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
908 
909     bool WalkUpFromStmt(Stmt *S) {
910       recordCallback(__func__, S,
911                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
912       return true;
913     }
914 
915     bool WalkUpFromExpr(Expr *E) {
916       recordCallback(__func__, E,
917                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
918       return true;
919     }
920 
921     bool WalkUpFromCompoundAssignOperator(CompoundAssignOperator *CAO) {
922       recordCallback(__func__, CAO, [&]() {
923         RecordingVisitorBase::WalkUpFromCompoundAssignOperator(CAO);
924       });
925       return true;
926     }
927   };
928 
929   StringRef Code = R"cpp(
930 void test(int a) {
931   1;
932   a += 2;
933   3;
934 }
935 )cpp";
936 
937   EXPECT_TRUE(visitorCallbackLogEqual(
938       RecordingVisitor(ShouldTraversePostOrder::No), Code,
939       R"txt(
940 WalkUpFromStmt CompoundStmt
941 WalkUpFromExpr IntegerLiteral(1)
942   WalkUpFromStmt IntegerLiteral(1)
943 WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=)
944   WalkUpFromExpr CompoundAssignOperator(+=)
945     WalkUpFromStmt CompoundAssignOperator(+=)
946 WalkUpFromExpr DeclRefExpr(a)
947   WalkUpFromStmt DeclRefExpr(a)
948 WalkUpFromExpr IntegerLiteral(2)
949   WalkUpFromStmt IntegerLiteral(2)
950 WalkUpFromExpr IntegerLiteral(3)
951   WalkUpFromStmt IntegerLiteral(3)
952 )txt"));
953 
954   EXPECT_TRUE(visitorCallbackLogEqual(
955       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
956       R"txt(
957 WalkUpFromExpr IntegerLiteral(1)
958   WalkUpFromStmt IntegerLiteral(1)
959 WalkUpFromExpr DeclRefExpr(a)
960   WalkUpFromStmt DeclRefExpr(a)
961 WalkUpFromExpr IntegerLiteral(2)
962   WalkUpFromStmt IntegerLiteral(2)
963 WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=)
964   WalkUpFromExpr CompoundAssignOperator(+=)
965     WalkUpFromStmt CompoundAssignOperator(+=)
966 WalkUpFromExpr IntegerLiteral(3)
967   WalkUpFromStmt IntegerLiteral(3)
968 WalkUpFromStmt CompoundStmt
969 )txt"));
970 }
971 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseCallExpr)972 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseCallExpr) {
973   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
974   public:
975     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
976         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
977 
978     bool TraverseCallExpr(CallExpr *CE) {
979       recordCallback(__func__, CE,
980                      [&]() { RecordingVisitorBase::TraverseCallExpr(CE); });
981       return true;
982     }
983 
984     bool WalkUpFromStmt(Stmt *S) {
985       recordCallback(__func__, S,
986                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
987       return true;
988     }
989   };
990 
991   StringRef Code = R"cpp(
992 void add(int, int);
993 void test() {
994   1;
995   2 + 3;
996   add(4, 5);
997 }
998 )cpp";
999 
1000   EXPECT_TRUE(visitorCallbackLogEqual(
1001       RecordingVisitor(ShouldTraversePostOrder::No), Code,
1002       R"txt(
1003 WalkUpFromStmt CompoundStmt
1004 WalkUpFromStmt IntegerLiteral(1)
1005 WalkUpFromStmt BinaryOperator(+)
1006 WalkUpFromStmt IntegerLiteral(2)
1007 WalkUpFromStmt IntegerLiteral(3)
1008 TraverseCallExpr CallExpr(add)
1009   WalkUpFromStmt CallExpr(add)
1010   WalkUpFromStmt ImplicitCastExpr
1011   WalkUpFromStmt DeclRefExpr(add)
1012   WalkUpFromStmt IntegerLiteral(4)
1013   WalkUpFromStmt IntegerLiteral(5)
1014 )txt"));
1015 
1016   EXPECT_TRUE(visitorCallbackLogEqual(
1017       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
1018       R"txt(
1019 WalkUpFromStmt IntegerLiteral(1)
1020 WalkUpFromStmt IntegerLiteral(2)
1021 WalkUpFromStmt IntegerLiteral(3)
1022 WalkUpFromStmt BinaryOperator(+)
1023 TraverseCallExpr CallExpr(add)
1024   WalkUpFromStmt DeclRefExpr(add)
1025   WalkUpFromStmt ImplicitCastExpr
1026   WalkUpFromStmt IntegerLiteral(4)
1027   WalkUpFromStmt IntegerLiteral(5)
1028   WalkUpFromStmt CallExpr(add)
1029 WalkUpFromStmt CompoundStmt
1030 )txt"));
1031 }
1032 
TEST(RecursiveASTVisitor,StmtCallbacks_TraverseCallExpr_WalkUpFromCallExpr)1033 TEST(RecursiveASTVisitor, StmtCallbacks_TraverseCallExpr_WalkUpFromCallExpr) {
1034   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
1035   public:
1036     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
1037         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
1038 
1039     bool TraverseCallExpr(CallExpr *CE) {
1040       recordCallback(__func__, CE,
1041                      [&]() { RecordingVisitorBase::TraverseCallExpr(CE); });
1042       return true;
1043     }
1044 
1045     bool WalkUpFromStmt(Stmt *S) {
1046       recordCallback(__func__, S,
1047                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
1048       return true;
1049     }
1050 
1051     bool WalkUpFromExpr(Expr *E) {
1052       recordCallback(__func__, E,
1053                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
1054       return true;
1055     }
1056 
1057     bool WalkUpFromCallExpr(CallExpr *CE) {
1058       recordCallback(__func__, CE,
1059                      [&]() { RecordingVisitorBase::WalkUpFromCallExpr(CE); });
1060       return true;
1061     }
1062   };
1063 
1064   StringRef Code = R"cpp(
1065 void add(int, int);
1066 void test() {
1067   1;
1068   2 + 3;
1069   add(4, 5);
1070 }
1071 )cpp";
1072 
1073   EXPECT_TRUE(visitorCallbackLogEqual(
1074       RecordingVisitor(ShouldTraversePostOrder::No), Code,
1075       R"txt(
1076 WalkUpFromStmt CompoundStmt
1077 WalkUpFromExpr IntegerLiteral(1)
1078   WalkUpFromStmt IntegerLiteral(1)
1079 WalkUpFromExpr BinaryOperator(+)
1080   WalkUpFromStmt BinaryOperator(+)
1081 WalkUpFromExpr IntegerLiteral(2)
1082   WalkUpFromStmt IntegerLiteral(2)
1083 WalkUpFromExpr IntegerLiteral(3)
1084   WalkUpFromStmt IntegerLiteral(3)
1085 TraverseCallExpr CallExpr(add)
1086   WalkUpFromCallExpr CallExpr(add)
1087     WalkUpFromExpr CallExpr(add)
1088       WalkUpFromStmt CallExpr(add)
1089   WalkUpFromExpr ImplicitCastExpr
1090     WalkUpFromStmt ImplicitCastExpr
1091   WalkUpFromExpr DeclRefExpr(add)
1092     WalkUpFromStmt DeclRefExpr(add)
1093   WalkUpFromExpr IntegerLiteral(4)
1094     WalkUpFromStmt IntegerLiteral(4)
1095   WalkUpFromExpr IntegerLiteral(5)
1096     WalkUpFromStmt IntegerLiteral(5)
1097 )txt"));
1098 
1099   EXPECT_TRUE(visitorCallbackLogEqual(
1100       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
1101       R"txt(
1102 WalkUpFromExpr IntegerLiteral(1)
1103   WalkUpFromStmt IntegerLiteral(1)
1104 WalkUpFromExpr IntegerLiteral(2)
1105   WalkUpFromStmt IntegerLiteral(2)
1106 WalkUpFromExpr IntegerLiteral(3)
1107   WalkUpFromStmt IntegerLiteral(3)
1108 WalkUpFromExpr BinaryOperator(+)
1109   WalkUpFromStmt BinaryOperator(+)
1110 TraverseCallExpr CallExpr(add)
1111   WalkUpFromExpr DeclRefExpr(add)
1112     WalkUpFromStmt DeclRefExpr(add)
1113   WalkUpFromExpr ImplicitCastExpr
1114     WalkUpFromStmt ImplicitCastExpr
1115   WalkUpFromExpr IntegerLiteral(4)
1116     WalkUpFromStmt IntegerLiteral(4)
1117   WalkUpFromExpr IntegerLiteral(5)
1118     WalkUpFromStmt IntegerLiteral(5)
1119   WalkUpFromCallExpr CallExpr(add)
1120     WalkUpFromExpr CallExpr(add)
1121       WalkUpFromStmt CallExpr(add)
1122 WalkUpFromStmt CompoundStmt
1123 )txt"));
1124 }
1125 
TEST(RecursiveASTVisitor,StmtCallbacks_WalkUpFromCallExpr)1126 TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromCallExpr) {
1127   class RecordingVisitor : public RecordingVisitorBase<RecordingVisitor> {
1128   public:
1129     RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue)
1130         : RecordingVisitorBase(ShouldTraversePostOrderValue) {}
1131 
1132     bool WalkUpFromStmt(Stmt *S) {
1133       recordCallback(__func__, S,
1134                      [&]() { RecordingVisitorBase::WalkUpFromStmt(S); });
1135       return true;
1136     }
1137 
1138     bool WalkUpFromExpr(Expr *E) {
1139       recordCallback(__func__, E,
1140                      [&]() { RecordingVisitorBase::WalkUpFromExpr(E); });
1141       return true;
1142     }
1143 
1144     bool WalkUpFromCallExpr(CallExpr *CE) {
1145       recordCallback(__func__, CE,
1146                      [&]() { RecordingVisitorBase::WalkUpFromCallExpr(CE); });
1147       return true;
1148     }
1149   };
1150 
1151   StringRef Code = R"cpp(
1152 void add(int, int);
1153 void test() {
1154   1;
1155   2 + 3;
1156   add(4, 5);
1157 }
1158 )cpp";
1159 
1160   EXPECT_TRUE(visitorCallbackLogEqual(
1161       RecordingVisitor(ShouldTraversePostOrder::No), Code,
1162       R"txt(
1163 WalkUpFromStmt CompoundStmt
1164 WalkUpFromExpr IntegerLiteral(1)
1165   WalkUpFromStmt IntegerLiteral(1)
1166 WalkUpFromExpr BinaryOperator(+)
1167   WalkUpFromStmt BinaryOperator(+)
1168 WalkUpFromExpr IntegerLiteral(2)
1169   WalkUpFromStmt IntegerLiteral(2)
1170 WalkUpFromExpr IntegerLiteral(3)
1171   WalkUpFromStmt IntegerLiteral(3)
1172 WalkUpFromCallExpr CallExpr(add)
1173   WalkUpFromExpr CallExpr(add)
1174     WalkUpFromStmt CallExpr(add)
1175 WalkUpFromExpr ImplicitCastExpr
1176   WalkUpFromStmt ImplicitCastExpr
1177 WalkUpFromExpr DeclRefExpr(add)
1178   WalkUpFromStmt DeclRefExpr(add)
1179 WalkUpFromExpr IntegerLiteral(4)
1180   WalkUpFromStmt IntegerLiteral(4)
1181 WalkUpFromExpr IntegerLiteral(5)
1182   WalkUpFromStmt IntegerLiteral(5)
1183 )txt"));
1184 
1185   EXPECT_TRUE(visitorCallbackLogEqual(
1186       RecordingVisitor(ShouldTraversePostOrder::Yes), Code,
1187       R"txt(
1188 WalkUpFromExpr IntegerLiteral(1)
1189   WalkUpFromStmt IntegerLiteral(1)
1190 WalkUpFromExpr IntegerLiteral(2)
1191   WalkUpFromStmt IntegerLiteral(2)
1192 WalkUpFromExpr IntegerLiteral(3)
1193   WalkUpFromStmt IntegerLiteral(3)
1194 WalkUpFromExpr BinaryOperator(+)
1195   WalkUpFromStmt BinaryOperator(+)
1196 WalkUpFromExpr DeclRefExpr(add)
1197   WalkUpFromStmt DeclRefExpr(add)
1198 WalkUpFromExpr ImplicitCastExpr
1199   WalkUpFromStmt ImplicitCastExpr
1200 WalkUpFromExpr IntegerLiteral(4)
1201   WalkUpFromStmt IntegerLiteral(4)
1202 WalkUpFromExpr IntegerLiteral(5)
1203   WalkUpFromStmt IntegerLiteral(5)
1204 WalkUpFromCallExpr CallExpr(add)
1205   WalkUpFromExpr CallExpr(add)
1206     WalkUpFromStmt CallExpr(add)
1207 WalkUpFromStmt CompoundStmt
1208 )txt"));
1209 }
1210