Move intrinsic overload tests from Validator -> TypeDeterminer
TypeDeterminer now does overload resolution. Move these tests to the right place. Change-Id: I27a4fccac34ded00f9828a77cc25ccfe1cb5c0ea Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/41383 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org> Auto-Submit: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
2522b29f7d
commit
47c4d18375
|
@ -19,6 +19,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/array_accessor_expression.h"
|
||||
#include "src/ast/assignment_statement.h"
|
||||
|
@ -73,6 +74,8 @@
|
|||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
|
||||
using ::testing::HasSubstr;
|
||||
|
||||
namespace tint {
|
||||
namespace {
|
||||
|
||||
|
@ -1576,7 +1579,19 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
TextureTestParams{type::TextureDimension::k2dArray},
|
||||
TextureTestParams{type::TextureDimension::k3d}));
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Dot_Vec2) {
|
||||
Global("my_var", ast::StorageClass::kNone, ty.vec2<f32>());
|
||||
|
||||
auto* expr = Call("dot", "my_var", "my_var");
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(expr), nullptr);
|
||||
EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Dot_Vec3) {
|
||||
Global("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
|
||||
|
||||
auto* expr = Call("dot", "my_var", "my_var");
|
||||
|
@ -1588,6 +1603,48 @@ TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
|
|||
EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Dot_Vec4) {
|
||||
Global("my_var", ast::StorageClass::kNone, ty.vec4<f32>());
|
||||
|
||||
auto* expr = Call("dot", "my_var", "my_var");
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(expr), nullptr);
|
||||
EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Dot_Error_Scalar) {
|
||||
auto* expr = Call("dot", 1.0f, 1.0f);
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to dot(f32, f32)
|
||||
|
||||
1 candidate function:
|
||||
dot(vecN<f32>, vecN<f32>) -> f32
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Dot_Error_VectorInt) {
|
||||
Global("my_var", ast::StorageClass::kNone, ty.vec4<i32>());
|
||||
|
||||
auto* expr = Call("dot", "my_var", "my_var");
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to dot(ptr<vec4<i32>>, ptr<vec4<i32>>)
|
||||
|
||||
1 candidate function:
|
||||
dot(vecN<f32>, vecN<f32>) -> f32
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select) {
|
||||
Global("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
|
||||
|
||||
|
@ -1604,7 +1661,7 @@ TEST_F(TypeDeterminerTest, Intrinsic_Select) {
|
|||
EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select_NoParams) {
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_NoParams) {
|
||||
auto* expr = Call("select");
|
||||
WrapInFunction(expr);
|
||||
|
||||
|
@ -1619,6 +1676,68 @@ TEST_F(TypeDeterminerTest, Intrinsic_Select_NoParams) {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_SelectorInt) {
|
||||
auto* expr = Call("select", Expr(1), Expr(1), Expr(1));
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to select(i32, i32, i32)
|
||||
|
||||
2 candidate functions:
|
||||
select(T, T, bool) -> T where: T is scalar
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_Matrix) {
|
||||
auto* mat = mat2x2<float>(vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f));
|
||||
auto* expr = Call("select", mat, mat, Expr(true));
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to select(mat2x2<f32>, mat2x2<f32>, bool)
|
||||
|
||||
2 candidate functions:
|
||||
select(T, T, bool) -> T where: T is scalar
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_MismatchTypes) {
|
||||
auto* expr = Call("select", 1.0f, vec2<float>(2.0f, 3.0f), Expr(true));
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to select(f32, vec2<f32>, bool)
|
||||
|
||||
2 candidate functions:
|
||||
select(T, T, bool) -> T where: T is scalar
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_MismatchVectorSize) {
|
||||
auto* expr = Call("select", vec2<float>(1.0f, 2.0f),
|
||||
vec3<float>(3.0f, 4.0f, 5.0f), Expr(true));
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to select(vec2<f32>, vec3<f32>, bool)
|
||||
|
||||
2 candidate functions:
|
||||
select(T, T, bool) -> T where: T is scalar
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
|
||||
)");
|
||||
}
|
||||
|
||||
using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
|
||||
TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
|
||||
auto op = GetParam();
|
||||
|
@ -1787,6 +1906,50 @@ TEST_P(Intrinsic_DataPackingTest, InferType) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
|
||||
}
|
||||
|
||||
TEST_P(Intrinsic_DataPackingTest, Error_IncorrectParamType) {
|
||||
auto param = GetParam();
|
||||
|
||||
bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
|
||||
param.intrinsic == IntrinsicType::kPack4x8Unorm;
|
||||
|
||||
auto* call = pack4 ? Call(param.name, vec4<i32>(1, 2, 3, 4))
|
||||
: Call(param.name, vec2<i32>(1, 2));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_THAT(td()->error(),
|
||||
HasSubstr("no matching call to " + std::string(param.name)));
|
||||
}
|
||||
|
||||
TEST_P(Intrinsic_DataPackingTest, Error_NoParams) {
|
||||
auto param = GetParam();
|
||||
|
||||
auto* call = Call(param.name);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_THAT(td()->error(),
|
||||
HasSubstr("no matching call to " + std::string(param.name)));
|
||||
}
|
||||
|
||||
TEST_P(Intrinsic_DataPackingTest, Error_TooManyParams) {
|
||||
auto param = GetParam();
|
||||
|
||||
bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
|
||||
param.intrinsic == IntrinsicType::kPack4x8Unorm;
|
||||
|
||||
auto* call = pack4 ? Call(param.name, vec4<f32>(1.f, 2.f, 3.f, 4.f), 1.0f)
|
||||
: Call(param.name, vec2<f32>(1.f, 2.f), 1.0f);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_THAT(td()->error(),
|
||||
HasSubstr("no matching call to " + std::string(param.name)));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
TypeDeterminerTest,
|
||||
Intrinsic_DataPackingTest,
|
||||
|
@ -1869,6 +2032,22 @@ TEST_P(Intrinsic_SingleParamTest, Error_NoParams) {
|
|||
"(vecN<f32>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
TEST_P(Intrinsic_SingleParamTest, Error_TooManyParams) {
|
||||
auto param = GetParam();
|
||||
|
||||
auto* call = Call(param.name, 1, 2, 3);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(), "no matching call to " + std::string(param.name) +
|
||||
"(i32, i32, i32)\n\n"
|
||||
"2 candidate functions:\n " +
|
||||
std::string(param.name) + "(f32) -> f32\n " +
|
||||
std::string(param.name) +
|
||||
"(vecN<f32>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
TypeDeterminerTest,
|
||||
Intrinsic_SingleParamTest,
|
||||
|
@ -1894,6 +2073,30 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
IntrinsicData{"tanh", IntrinsicType::kTanh},
|
||||
IntrinsicData{"trunc", IntrinsicType::kTrunc}));
|
||||
|
||||
TEST_F(IntrinsicDataTest, ArrayLength_Vector) {
|
||||
Global("arr", ast::StorageClass::kNone, ty.array<int>());
|
||||
auto* call = Call("arrayLength", "arr");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, ArrayLength_Error_ArraySized) {
|
||||
Global("arr", ast::StorageClass::kNone, ty.array<int, 4>());
|
||||
auto* call = Call("arrayLength", "arr");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to arrayLength(ptr<array<i32, 4>>)\n\n"
|
||||
"1 candidate function:\n"
|
||||
" arrayLength(array<T>) -> u32\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Normalize_Vector) {
|
||||
auto* call = Call("normalize", vec3<f32>(1.0f, 1.0f, 3.0f));
|
||||
WrapInFunction(call);
|
||||
|
@ -1913,8 +2116,169 @@ TEST_F(IntrinsicDataTest, Normalize_Error_NoParams) {
|
|||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to normalize()\n\n"
|
||||
"1 candidate function:\n "
|
||||
"normalize(vecN<f32>) -> vecN<f32>\n");
|
||||
"1 candidate function:\n"
|
||||
" normalize(vecN<f32>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, FrexpScalar) {
|
||||
Global("exp", ast::StorageClass::kWorkgroup, ty.i32());
|
||||
auto* call = Call("frexp", 1.0f, "exp");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, FrexpVector) {
|
||||
Global("exp", ast::StorageClass::kWorkgroup, ty.vec3<i32>());
|
||||
auto* call = Call("frexp", vec3<f32>(1.0f, 2.0f, 3.0f), "exp");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::Vector>());
|
||||
EXPECT_TRUE(TypeOf(call)->As<type::Vector>()->type()->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Frexp_Error_FirstParamInt) {
|
||||
Global("exp", ast::StorageClass::kWorkgroup, ty.i32());
|
||||
auto* call = Call("frexp", 1, "exp");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to frexp(i32, ptr<workgroup, i32>)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
|
||||
" frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
|
||||
"where: T is i32 or u32\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Frexp_Error_SecondParamFloatPtr) {
|
||||
Global("exp", ast::StorageClass::kWorkgroup, ty.f32());
|
||||
auto* call = Call("frexp", 1.0f, "exp");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to frexp(f32, ptr<workgroup, f32>)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
|
||||
" frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
|
||||
"where: T is i32 or u32\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Frexp_Error_SecondParamNotAPointer) {
|
||||
auto* call = Call("frexp", 1.0f, 1);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to frexp(f32, i32)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
|
||||
" frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
|
||||
"where: T is i32 or u32\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Frexp_Error_VectorSizesDontMatch) {
|
||||
Global("exp", ast::StorageClass::kWorkgroup, ty.vec4<i32>());
|
||||
auto* call = Call("frexp", vec2<f32>(1.0f, 2.0f), "exp");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(
|
||||
td()->error(),
|
||||
"no matching call to frexp(vec2<f32>, ptr<workgroup, vec4<i32>>)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
|
||||
" frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
|
||||
"where: T is i32 or u32\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, ModfScalar) {
|
||||
Global("whole", ast::StorageClass::kWorkgroup, ty.f32());
|
||||
auto* call = Call("modf", 1.0f, "whole");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, ModfVector) {
|
||||
Global("whole", ast::StorageClass::kWorkgroup, ty.vec3<f32>());
|
||||
auto* call = Call("modf", vec3<f32>(1.0f, 2.0f, 3.0f), "whole");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::Vector>());
|
||||
EXPECT_TRUE(TypeOf(call)->As<type::Vector>()->type()->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Modf_Error_FirstParamInt) {
|
||||
Global("whole", ast::StorageClass::kWorkgroup, ty.f32());
|
||||
auto* call = Call("modf", 1, "whole");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to modf(i32, ptr<workgroup, f32>)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" modf(f32, ptr<f32>) -> f32\n"
|
||||
" modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Modf_Error_SecondParamIntPtr) {
|
||||
Global("whole", ast::StorageClass::kWorkgroup, ty.i32());
|
||||
auto* call = Call("modf", 1.0f, "whole");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to modf(f32, ptr<workgroup, i32>)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" modf(f32, ptr<f32>) -> f32\n"
|
||||
" modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Modf_Error_SecondParamNotAPointer) {
|
||||
auto* call = Call("modf", 1.0f, 1.0f);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to modf(f32, f32)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" modf(f32, ptr<f32>) -> f32\n"
|
||||
" modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicDataTest, Modf_Error_VectorSizesDontMatch) {
|
||||
Global("whole", ast::StorageClass::kWorkgroup, ty.vec4<f32>());
|
||||
auto* call = Call("modf", vec2<f32>(1.0f, 2.0f), "whole");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to modf(vec2<f32>, ptr<workgroup, vec4<f32>>)\n\n"
|
||||
"2 candidate functions:\n"
|
||||
" modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n"
|
||||
" modf(f32, ptr<f32>) -> f32\n");
|
||||
}
|
||||
|
||||
using Intrinsic_SingleParam_FloatOrInt_Test =
|
||||
|
@ -2077,6 +2441,24 @@ TEST_P(Intrinsic_TwoParamTest, Vector) {
|
|||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
|
||||
}
|
||||
|
||||
TEST_P(Intrinsic_TwoParamTest, Error_NoTooManyParams) {
|
||||
auto param = GetParam();
|
||||
|
||||
auto* call = Call(param.name, 1, 2, 3);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(), "no matching call to " + std::string(param.name) +
|
||||
"(i32, i32, i32)\n\n"
|
||||
"2 candidate functions:\n " +
|
||||
std::string(param.name) +
|
||||
"(f32, f32) -> f32\n " +
|
||||
std::string(param.name) +
|
||||
"(vecN<f32>, vecN<f32>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
TEST_P(Intrinsic_TwoParamTest, Error_NoParams) {
|
||||
auto param = GetParam();
|
||||
|
||||
|
@ -2093,6 +2475,7 @@ TEST_P(Intrinsic_TwoParamTest, Error_NoParams) {
|
|||
std::string(param.name) +
|
||||
"(vecN<f32>, vecN<f32>) -> vecN<f32>\n");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
TypeDeterminerTest,
|
||||
Intrinsic_TwoParamTest,
|
||||
|
@ -2124,7 +2507,7 @@ TEST_F(TypeDeterminerTest, Intrinsic_Distance_Vector) {
|
|||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross) {
|
||||
auto* call =
|
||||
Call("cross", vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
|
||||
Call("cross", vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(1.0f, 2.0f, 3.0f));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
@ -2134,7 +2517,7 @@ TEST_F(TypeDeterminerTest, Intrinsic_Cross) {
|
|||
EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross_NoArgs) {
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_NoArgs) {
|
||||
auto* call = Call("cross");
|
||||
WrapInFunction(call);
|
||||
|
||||
|
@ -2147,6 +2530,62 @@ TEST_F(TypeDeterminerTest, Intrinsic_Cross_NoArgs) {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_Scalar) {
|
||||
auto* call = Call("cross", 1.0f, 1.0f);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(), R"(no matching call to cross(f32, f32)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_Vec3Int) {
|
||||
auto* call = Call("cross", vec3<i32>(1, 2, 3), vec3<i32>(1, 2, 3));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(), R"(no matching call to cross(vec3<i32>, vec3<i32>)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_Vec4) {
|
||||
auto* call = Call("cross", vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f),
|
||||
vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f));
|
||||
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(), R"(no matching call to cross(vec4<f32>, vec4<f32>)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_TooManyParams) {
|
||||
auto* call = Call("cross", vec3<f32>(1.0f, 2.0f, 3.0f),
|
||||
vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(1.0f, 2.0f, 3.0f));
|
||||
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
R"(no matching call to cross(vec3<f32>, vec3<f32>, vec3<f32>)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
)");
|
||||
}
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Normalize) {
|
||||
auto* call = Call("normalize", vec3<f32>(1.0f, 1.0f, 3.0f));
|
||||
WrapInFunction(call);
|
||||
|
@ -2479,7 +2918,19 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
testing::Values(IntrinsicData{"min", IntrinsicType::kMin},
|
||||
IntrinsicData{"max", IntrinsicType::kMax}));
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_GLSL_Determinant) {
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Determinant_2x2) {
|
||||
Global("var", ast::StorageClass::kFunction, ty.mat2x2<f32>());
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Determinant_3x3) {
|
||||
Global("var", ast::StorageClass::kFunction, ty.mat3x3<f32>());
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
|
@ -2491,30 +2942,45 @@ TEST_F(TypeDeterminerTest, Intrinsic_GLSL_Determinant) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
|
||||
}
|
||||
|
||||
using Intrinsic_Matrix_OneParam_Test =
|
||||
TypeDeterminerTestWithParam<IntrinsicData>;
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Determinant_4x4) {
|
||||
Global("var", ast::StorageClass::kFunction, ty.mat4x4<f32>());
|
||||
|
||||
TEST_P(Intrinsic_Matrix_OneParam_Test, NoParams) {
|
||||
auto param = GetParam();
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
auto* call = Call(param.name);
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Determinant_NotSquare) {
|
||||
Global("var", ast::StorageClass::kFunction, ty.mat2x3<f32>());
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to " + std::string(param.name) + R"(()
|
||||
|
||||
1 candidate function:
|
||||
determinant(matNxN<f32>) -> f32
|
||||
)");
|
||||
"no matching call to determinant(ptr<function, mat2x3<f32>>)\n\n"
|
||||
"1 candidate function:\n"
|
||||
" determinant(matNxN<f32>) -> f32\n");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
|
||||
Intrinsic_Matrix_OneParam_Test,
|
||||
testing::Values(IntrinsicData{
|
||||
"determinant", IntrinsicType::kDeterminant}));
|
||||
TEST_F(TypeDeterminerTest, Intrinsic_Determinant_NotMatrix) {
|
||||
Global("var", ast::StorageClass::kFunction, ty.f32());
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
|
||||
EXPECT_EQ(td()->error(),
|
||||
"no matching call to determinant(ptr<function, f32>)\n\n"
|
||||
"1 candidate function:\n"
|
||||
" determinant(matNxN<f32>) -> f32\n");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
|
||||
// fn b() {}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue