Mercurial > hg > CbC > CbC_llvm
view clang/unittests/Tooling/CastExprTest.cpp @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | c4bab56944e8 |
children |
line wrap: on
line source
//===- unittest/Tooling/CastExprTest.cpp ----------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "TestVisitor.h" using namespace clang; namespace { struct CastExprVisitor : TestVisitor<CastExprVisitor> { std::function<void(ExplicitCastExpr *)> OnExplicitCast; std::function<void(CastExpr *)> OnCast; bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) { if (OnExplicitCast) OnExplicitCast(Expr); return true; } bool VisitCastExpr(CastExpr *Expr) { if (OnCast) OnCast(Expr); return true; } }; TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) { CastExprVisitor Visitor; Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) { auto Sub = Expr->getSubExprAsWritten(); EXPECT_TRUE(isa<DeclRefExpr>(Sub)) << "Expected DeclRefExpr, but saw " << Sub->getStmtClassName(); }; Visitor.runOver("struct S1 {};\n" "struct S2 { operator S1(); };\n" "S1 f(S2 s) { return static_cast<S1>(s); }\n"); } // Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario // like // // CXXFunctionalCastExpr functional cast to struct S <ConstructorConversion> // `-ConstantExpr 'S' // |-value: Struct // `-CXXConstructExpr 'S' 'void (int)' // `-IntegerLiteral 'int' 0 TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) { CastExprVisitor Visitor; Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) { auto *Sub = Expr->getSubExprAsWritten(); EXPECT_TRUE(isa<IntegerLiteral>(Sub)) << "Expected IntegerLiteral, but saw " << Sub->getStmtClassName(); }; Visitor.runOver("struct S { consteval S(int) {} };\n" "S f() { return S(0); }\n", CastExprVisitor::Lang_CXX2a); } // Verify that getConversionFunction looks through a ConstantExpr for implicit // constructor conversions (https://github.com/llvm/llvm-project/issues/53044): // // `-ImplicitCastExpr 'X' <ConstructorConversion> // `-ConstantExpr 'X' // |-value: Struct // `-CXXConstructExpr 'X' 'void (const char *)' // `-ImplicitCastExpr 'const char *' <ArrayToPointerDecay> // `-StringLiteral 'const char [7]' lvalue "foobar" TEST(CastExprTest, GetCtorConversionFunctionThroughConstantExpr) { CastExprVisitor Visitor; Visitor.OnCast = [](CastExpr *Expr) { if (Expr->getCastKind() == CK_ConstructorConversion) { auto *Conv = Expr->getConversionFunction(); EXPECT_TRUE(isa<CXXConstructorDecl>(Conv)) << "Expected CXXConstructorDecl, but saw " << Conv->getDeclKindName(); } }; Visitor.runOver("struct X { consteval X(const char *) {} };\n" "void f() { X x = \"foobar\"; }\n", CastExprVisitor::Lang_CXX2a); } // Verify that getConversionFunction looks through a ConstantExpr for implicit // user-defined conversions. // // `-ImplicitCastExpr 'const char *' <UserDefinedConversion> // `-ConstantExpr 'const char *' // |-value: LValue // `-CXXMemberCallExpr 'const char *' // `-MemberExpr '<bound member function type>' .operator const char * // `-DeclRefExpr 'const X' lvalue Var 'x' 'const X' TEST(CastExprTest, GetUserDefinedConversionFunctionThroughConstantExpr) { CastExprVisitor Visitor; Visitor.OnCast = [](CastExpr *Expr) { if (Expr->getCastKind() == CK_UserDefinedConversion) { auto *Conv = Expr->getConversionFunction(); EXPECT_TRUE(isa<CXXMethodDecl>(Conv)) << "Expected CXXMethodDecl, but saw " << Conv->getDeclKindName(); } }; Visitor.runOver("struct X {\n" " consteval operator const char *() const {\n" " return nullptr;\n" " }\n" "};\n" "const char *f() {\n" " constexpr X x;\n" " return x;\n" "}\n", CastExprVisitor::Lang_CXX2a); } } // namespace