[OptTable] Fix typo VALUE => VALUES (NFCI) (#121523)
[llvm-project.git] / clang / unittests / Tooling / RecursiveASTVisitorTests / LambdaExpr.cpp
blob0ce7f4b18762f27b89468ae65d4625c452697188
1 //===- unittest/Tooling/RecursiveASTVisitorTests/LambdaExpr.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 //===----------------------------------------------------------------------===//
9 #include "TestVisitor.h"
10 #include "llvm/TargetParser/Host.h"
11 #include <stack>
13 using namespace clang;
15 namespace {
17 class LambdaExprVisitor : public ExpectedLocationVisitor {
18 public:
19 LambdaExprVisitor() { ShouldVisitImplicitCode = false; }
21 bool VisitLambdaExpr(LambdaExpr *Lambda) override {
22 PendingBodies.push(Lambda->getBody());
23 PendingClasses.push(Lambda->getLambdaClass());
24 Match("", Lambda->getIntroducerRange().getBegin());
25 return true;
27 /// For each call to VisitLambdaExpr, we expect a subsequent call to visit
28 /// the body (and maybe the lambda class, which is implicit).
29 bool VisitStmt(Stmt *S) override {
30 if (!PendingBodies.empty() && S == PendingBodies.top())
31 PendingBodies.pop();
32 return true;
34 bool VisitDecl(Decl *D) override {
35 if (!PendingClasses.empty() && D == PendingClasses.top())
36 PendingClasses.pop();
37 return true;
39 /// Determine whether parts of lambdas (VisitLambdaExpr) were later traversed.
40 bool allBodiesHaveBeenTraversed() const { return PendingBodies.empty(); }
41 bool allClassesHaveBeenTraversed() const { return PendingClasses.empty(); }
43 private:
44 std::stack<Stmt *> PendingBodies;
45 std::stack<Decl *> PendingClasses;
48 TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
49 LambdaExprVisitor Visitor;
50 Visitor.ExpectMatch("", 1, 12);
51 EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
52 LambdaExprVisitor::Lang_CXX11));
53 EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
54 EXPECT_FALSE(Visitor.allClassesHaveBeenTraversed());
57 TEST(RecursiveASTVisitor, LambdaInLambda) {
58 LambdaExprVisitor Visitor;
59 Visitor.ExpectMatch("", 1, 12);
60 Visitor.ExpectMatch("", 1, 16);
61 EXPECT_TRUE(Visitor.runOver("void f() { []{ []{ return; }; }(); }",
62 LambdaExprVisitor::Lang_CXX11));
63 EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
64 EXPECT_FALSE(Visitor.allClassesHaveBeenTraversed());
67 TEST(RecursiveASTVisitor, TopLevelLambda) {
68 LambdaExprVisitor Visitor;
69 Visitor.ShouldVisitImplicitCode = true;
70 Visitor.ExpectMatch("", 1, 10);
71 Visitor.ExpectMatch("", 1, 14);
72 EXPECT_TRUE(Visitor.runOver("auto x = []{ [] {}; };",
73 LambdaExprVisitor::Lang_CXX11));
74 EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
75 EXPECT_TRUE(Visitor.allClassesHaveBeenTraversed());
78 TEST(RecursiveASTVisitor, VisitsLambdaExprAndImplicitClass) {
79 LambdaExprVisitor Visitor;
80 Visitor.ShouldVisitImplicitCode = true;
81 Visitor.ExpectMatch("", 1, 12);
82 EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
83 LambdaExprVisitor::Lang_CXX11));
84 EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
85 EXPECT_TRUE(Visitor.allClassesHaveBeenTraversed());
88 TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) {
89 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).isPS())
90 GTEST_SKIP(); // PS4/PS5 do not support fastcall.
91 LambdaExprVisitor Visitor;
92 Visitor.ExpectMatch("", 1, 12);
93 EXPECT_TRUE(Visitor.runOver(
94 "void f() { [] () __attribute__ (( fastcall )) { return; }(); }",
95 LambdaExprVisitor::Lang_CXX14));
98 } // end anonymous namespace