brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · e5a8d99 Raw
118 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestVisitor.h"10 11using namespace clang;12 13namespace {14 15struct CastExprVisitor : TestVisitor {16  std::function<void(ExplicitCastExpr *)> OnExplicitCast;17  std::function<void(CastExpr *)> OnCast;18 19  bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) override {20    if (OnExplicitCast)21      OnExplicitCast(Expr);22    return true;23  }24 25  bool VisitCastExpr(CastExpr *Expr) override {26    if (OnCast)27      OnCast(Expr);28    return true;29  }30};31 32TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) {33  CastExprVisitor Visitor;34  Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {35    auto Sub = Expr->getSubExprAsWritten();36    EXPECT_TRUE(isa<DeclRefExpr>(Sub))37        << "Expected DeclRefExpr, but saw " << Sub->getStmtClassName();38  };39  Visitor.runOver("struct S1 {};\n"40                  "struct S2 { operator S1(); };\n"41                  "S1 f(S2 s) { return static_cast<S1>(s); }\n");42}43 44// Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario45// like46//47//   CXXFunctionalCastExpr functional cast to struct S <ConstructorConversion>48//   `-ConstantExpr 'S'49//     |-value: Struct50//     `-CXXConstructExpr 'S' 'void (int)'51//       `-IntegerLiteral 'int' 052TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) {53  CastExprVisitor Visitor;54  Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {55    auto *Sub = Expr->getSubExprAsWritten();56    EXPECT_TRUE(isa<IntegerLiteral>(Sub))57        << "Expected IntegerLiteral, but saw " << Sub->getStmtClassName();58  };59  Visitor.runOver("struct S { consteval S(int) {} };\n"60                  "S f() { return S(0); }\n",61                  CastExprVisitor::Lang_CXX2a);62}63 64// Verify that getConversionFunction looks through a ConstantExpr for implicit65// constructor conversions (https://github.com/llvm/llvm-project/issues/53044):66//67// `-ImplicitCastExpr 'X' <ConstructorConversion>68//   `-ConstantExpr 'X'69//     |-value: Struct70//     `-CXXConstructExpr 'X' 'void (const char *)'71//       `-ImplicitCastExpr 'const char *' <ArrayToPointerDecay>72//         `-StringLiteral 'const char [7]' lvalue "foobar"73TEST(CastExprTest, GetCtorConversionFunctionThroughConstantExpr) {74  CastExprVisitor Visitor;75  Visitor.OnCast = [](CastExpr *Expr) {76    if (Expr->getCastKind() == CK_ConstructorConversion) {77      auto *Conv = Expr->getConversionFunction();78      EXPECT_TRUE(isa<CXXConstructorDecl>(Conv))79          << "Expected CXXConstructorDecl, but saw " << Conv->getDeclKindName();80    }81  };82  Visitor.runOver("struct X { consteval X(const char *) {} };\n"83                  "void f() { X x = \"foobar\"; }\n",84                  CastExprVisitor::Lang_CXX2a);85}86 87// Verify that getConversionFunction looks through a ConstantExpr for implicit88// user-defined conversions.89//90// `-ImplicitCastExpr 'const char *' <UserDefinedConversion>91//   `-ConstantExpr 'const char *'92//     |-value: LValue93//     `-CXXMemberCallExpr 'const char *'94//       `-MemberExpr '<bound member function type>' .operator const char *95//         `-DeclRefExpr 'const X' lvalue Var 'x' 'const X'96TEST(CastExprTest, GetUserDefinedConversionFunctionThroughConstantExpr) {97  CastExprVisitor Visitor;98  Visitor.OnCast = [](CastExpr *Expr) {99    if (Expr->getCastKind() == CK_UserDefinedConversion) {100      auto *Conv = Expr->getConversionFunction();101      EXPECT_TRUE(isa<CXXMethodDecl>(Conv))102          << "Expected CXXMethodDecl, but saw " << Conv->getDeclKindName();103    }104  };105  Visitor.runOver("struct X {\n"106                  "  consteval operator const char *() const {\n"107                  "    return nullptr;\n"108                  "  }\n"109                  "};\n"110                  "const char *f() {\n"111                  "  constexpr X x;\n"112                  "  return x;\n"113                  "}\n",114                  CastExprVisitor::Lang_CXX2a);115}116 117} // namespace118