brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 0ce7f4b Raw
99 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestVisitor.h"10#include "llvm/TargetParser/Host.h"11#include <stack>12 13using namespace clang;14 15namespace {16 17class LambdaExprVisitor : public ExpectedLocationVisitor {18public:19  LambdaExprVisitor() { ShouldVisitImplicitCode = false; }20 21  bool VisitLambdaExpr(LambdaExpr *Lambda) override {22    PendingBodies.push(Lambda->getBody());23    PendingClasses.push(Lambda->getLambdaClass());24    Match("", Lambda->getIntroducerRange().getBegin());25    return true;26  }27  /// For each call to VisitLambdaExpr, we expect a subsequent call to visit28  /// 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;33  }34  bool VisitDecl(Decl *D) override {35    if (!PendingClasses.empty() && D == PendingClasses.top())36      PendingClasses.pop();37    return true;38  }39  /// Determine whether parts of lambdas (VisitLambdaExpr) were later traversed.40  bool allBodiesHaveBeenTraversed() const { return PendingBodies.empty(); }41  bool allClassesHaveBeenTraversed() const { return PendingClasses.empty(); }42 43private:44  std::stack<Stmt *> PendingBodies;45  std::stack<Decl *> PendingClasses;46};47 48TEST(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());55}56 57TEST(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());65}66 67TEST(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());76}77 78TEST(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());86}87 88TEST(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));96}97 98} // end anonymous namespace99