1 //===- unittest/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "TestVisitor.h" 11 #include <stack> 12 13 using namespace clang; 14 15 namespace { 16 17 class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> { 18 public: 19 bool VisitLambdaExpr(LambdaExpr *Lambda) { 20 PendingBodies.push(Lambda); 21 Match("", Lambda->getIntroducerRange().getBegin()); 22 return true; 23 } 24 /// For each call to VisitLambdaExpr, we expect a subsequent call (with 25 /// proper nesting) to TraverseLambdaBody. 26 bool TraverseLambdaBody(LambdaExpr *Lambda) { 27 EXPECT_FALSE(PendingBodies.empty()); 28 EXPECT_EQ(PendingBodies.top(), Lambda); 29 PendingBodies.pop(); 30 return TraverseStmt(Lambda->getBody()); 31 } 32 /// Determine whether TraverseLambdaBody has been called for every call to 33 /// VisitLambdaExpr. 34 bool allBodiesHaveBeenTraversed() const { 35 return PendingBodies.empty(); 36 } 37 private: 38 std::stack<LambdaExpr *> PendingBodies; 39 }; 40 41 TEST(RecursiveASTVisitor, VisitsLambdaExpr) { 42 LambdaExprVisitor Visitor; 43 Visitor.ExpectMatch("", 1, 12); 44 EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", 45 LambdaExprVisitor::Lang_CXX11)); 46 } 47 48 TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) { 49 LambdaExprVisitor Visitor; 50 EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", 51 LambdaExprVisitor::Lang_CXX11)); 52 EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); 53 } 54 55 TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) { 56 LambdaExprVisitor Visitor; 57 Visitor.ExpectMatch("", 1, 12); 58 EXPECT_TRUE(Visitor.runOver( 59 "void f() { [] () __attribute__ (( fastcall )) { return; }(); }", 60 LambdaExprVisitor::Lang_CXX14)); 61 } 62 63 } // end anonymous namespace 64