diff --git a/clang/include/clang/AST/IgnoreExpr.h b/clang/include/clang/AST/IgnoreExpr.h --- a/clang/include/clang/AST/IgnoreExpr.h +++ b/clang/include/clang/AST/IgnoreExpr.h @@ -23,7 +23,8 @@ inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; } template Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) { - return IgnoreExprNodesImpl(Fn(E), std::forward(Fns)...); + return IgnoreExprNodesImpl(std::forward(Fn)(E), + std::forward(Fns)...); } } // namespace detail diff --git a/clang/unittests/AST/ASTExprTest.cpp b/clang/unittests/AST/ASTExprTest.cpp new file mode 100644 --- /dev/null +++ b/clang/unittests/AST/ASTExprTest.cpp @@ -0,0 +1,58 @@ +//===- unittests/AST/ASTExprTest.cpp --- AST Expr tests -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains tests for AST Expr related methods. +// +//===----------------------------------------------------------------------===// + +#include "ASTPrint.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Expr.h" +#include "clang/AST/IgnoreExpr.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/Tooling.h" +#include "gtest/gtest.h" + +using namespace clang; + +TEST(ASTExpr, IgnoreExprCallbackForwarded) { + constexpr char Code[] = ""; + auto AST = tooling::buildASTFromCodeWithArgs(Code, /*Args=*/{"-std=c++20"}); + ASTContext &Ctx = AST->getASTContext(); + + auto createIntLiteral = [&](uint32_t Value) -> IntegerLiteral * { + const int numBits = 32; + return IntegerLiteral::Create(Ctx, llvm::APInt(numBits, Value), + Ctx.UnsignedIntTy, {}); + }; + + struct IgnoreParens { + Expr *operator()(Expr *E) & { return nullptr; } + Expr *operator()(Expr *E) && { + if (auto *PE = dyn_cast(E)) { + return PE->getSubExpr(); + } + return E; + } + }; + + { + auto *IntExpr = createIntLiteral(10); + ParenExpr *PE = + new (Ctx) ParenExpr(SourceLocation{}, SourceLocation{}, IntExpr); + EXPECT_EQ(IntExpr, IgnoreExprNodes(PE, IgnoreParens{})); + } + + { + IgnoreParens CB{}; + auto *IntExpr = createIntLiteral(10); + ParenExpr *PE = + new (Ctx) ParenExpr(SourceLocation{}, SourceLocation{}, IntExpr); + EXPECT_EQ(nullptr, IgnoreExprNodes(PE, CB)); + } +} diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt --- a/clang/unittests/AST/CMakeLists.txt +++ b/clang/unittests/AST/CMakeLists.txt @@ -7,6 +7,7 @@ add_clang_unittest(ASTTests ASTContextParentMapTest.cpp + ASTExprTest.cpp ASTImporterFixtures.cpp ASTImporterTest.cpp ASTImporterObjCTest.cpp