1 //===- unittest/Tooling/CastExprTest.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 //===----------------------------------------------------------------------===// 8 9 #include "TestVisitor.h" 10 11 using namespace clang; 12 13 namespace { 14 15 struct CastExprVisitor : TestVisitor<CastExprVisitor> { 16 std::function<void(ExplicitCastExpr *)> OnExplicitCast; 17 18 bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) { 19 if (OnExplicitCast) 20 OnExplicitCast(Expr); 21 return true; 22 } 23 }; 24 25 TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) { 26 CastExprVisitor Visitor; 27 Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) { 28 auto Sub = Expr->getSubExprAsWritten(); 29 EXPECT_TRUE(isa<DeclRefExpr>(Sub)) 30 << "Expected DeclRefExpr, but saw " << Sub->getStmtClassName(); 31 }; 32 Visitor.runOver("struct S1 {};\n" 33 "struct S2 { operator S1(); };\n" 34 "S1 f(S2 s) { return static_cast<S1>(s); }\n"); 35 } 36 37 // Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario 38 // like 39 // 40 // CXXFunctionalCastExpr functional cast to struct S <ConstructorConversion> 41 // `-ConstantExpr 'S' 42 // |-value: Struct 43 // `-CXXConstructExpr 'S' 'void (int)' 44 // `-IntegerLiteral 'int' 0 45 TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) { 46 CastExprVisitor Visitor; 47 Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) { 48 auto *Sub = Expr->getSubExprAsWritten(); 49 EXPECT_TRUE(isa<IntegerLiteral>(Sub)) 50 << "Expected IntegerLiteral, but saw " << Sub->getStmtClassName(); 51 }; 52 Visitor.runOver("struct S { consteval S(int) {} };\n" 53 "S f() { return S(0); }\n", 54 CastExprVisitor::Lang_CXX2a); 55 } 56 57 } 58