mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 01:15:39 +00:00
Finish moving call validation from Validator to Resolver
Call validation was already implemented in Resolver. This change completes it by deleting the relevant code in Validator, and moving and updating the builtins validation test to use the Resolver. Also added the "v-0004" error code for when detecting recursion, as was done for the similar error in the Validator. Bug: tint:642 Bug: tint:487 Change-Id: If7973bfd2d19681a0cbf48c6d427e17a3b927cde Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45463 Commit-Queue: Antonio Maiorano <amaiorano@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
4682e3fc31
commit
06feb3f287
616
src/resolver/builtins_validation_test.cc
Normal file
616
src/resolver/builtins_validation_test.cc
Normal file
@@ -0,0 +1,616 @@
|
||||
// Copyright 2021 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/resolver/resolver_test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
namespace {
|
||||
class ResolverBuiltinsValidationTest : public resolver::TestHelper,
|
||||
public testing::Test {};
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Length_Float_Scalar) {
|
||||
auto* builtin = Call("length", 1.0f);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec2) {
|
||||
auto* builtin = Call("length", vec2<float>(1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec3) {
|
||||
auto* builtin = Call("length", vec3<float>(1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec4) {
|
||||
auto* builtin = Call("length", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Scalar) {
|
||||
auto* builtin = Call("distance", 1.0f, 1.0f);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec2) {
|
||||
auto* builtin =
|
||||
Call("distance", vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec3) {
|
||||
auto* builtin = Call("distance", vec3<float>(1.0f, 1.0f, 1.0f),
|
||||
vec3<float>(1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec4) {
|
||||
auto* builtin = Call("distance", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat2x2) {
|
||||
auto* builtin = Call("determinant", mat2x2<float>(vec2<float>(1.0f, 1.0f),
|
||||
vec2<float>(1.0f, 1.0f)));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat3x3) {
|
||||
auto* builtin =
|
||||
Call("determinant", mat3x3<float>(vec3<float>(1.0f, 1.0f, 1.0f),
|
||||
vec3<float>(1.0f, 1.0f, 1.0f),
|
||||
vec3<float>(1.0f, 1.0f, 1.0f)));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat4x4) {
|
||||
auto* builtin =
|
||||
Call("determinant", mat4x4<float>(vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f)));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Scalar) {
|
||||
auto* a = Var("a", ty.i32(), ast::StorageClass::kFunction);
|
||||
auto* builtin = Call("frexp", 1.0f, Expr("a"));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec2) {
|
||||
auto* a = Var("a", ty.vec2<int>(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b",
|
||||
create<type::Pointer>(create<type::Vector>(ty.i32(), 2),
|
||||
ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("frexp", vec2<float>(1.0f, 1.0f), Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec3) {
|
||||
auto* a = Var("a", ty.vec3<int>(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b",
|
||||
create<type::Pointer>(create<type::Vector>(ty.i32(), 3),
|
||||
ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("frexp", vec3<float>(1.0f, 1.0f, 1.0f), Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec4) {
|
||||
auto* a = Var("a", ty.vec4<int>(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b",
|
||||
create<type::Pointer>(create<type::Vector>(ty.i32(), 4),
|
||||
ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("frexp", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Scalar) {
|
||||
auto* a = Var("a", ty.f32(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b", ty.pointer<float>(ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("modf", 1.0f, Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Vec2) {
|
||||
auto* a = Var("a", ty.vec2<float>(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b",
|
||||
create<type::Pointer>(create<type::Vector>(ty.f32(), 2),
|
||||
ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("modf", vec2<float>(1.0f, 1.0f), Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Vec3) {
|
||||
auto* a = Var("a", ty.vec3<float>(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b",
|
||||
create<type::Pointer>(create<type::Vector>(ty.f32(), 3),
|
||||
ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("modf", vec3<float>(1.0f, 1.0f, 1.0f), Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Vec4) {
|
||||
auto* a = Var("a", ty.vec4<float>(), ast::StorageClass::kFunction);
|
||||
auto* b = Const("b",
|
||||
create<type::Pointer>(create<type::Vector>(ty.f32(), 4),
|
||||
ast::StorageClass::kFunction),
|
||||
Expr("a"), {});
|
||||
auto* builtin = Call("modf", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b"));
|
||||
WrapInFunction(Decl(a), Decl(b), builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Cross_Float_Vec3) {
|
||||
auto* builtin = Call("cross", vec3<float>(1.0f, 1.0f, 1.0f),
|
||||
vec3<float>(1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec2) {
|
||||
auto* builtin = Call("dot", vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec3) {
|
||||
auto* builtin =
|
||||
Call("dot", vec3<float>(1.0f, 1.0f, 1.0f), vec3<float>(1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec4) {
|
||||
auto* builtin = Call("dot", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Select_Float_Scalar) {
|
||||
auto* builtin = Call("select", Expr(1.0f), Expr(1.0f), Expr(true));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Scalar) {
|
||||
auto* builtin = Call("select", Expr(1), Expr(1), Expr(true));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Select_Boolean_Scalar) {
|
||||
auto* builtin = Call("select", Expr(true), Expr(true), Expr(true));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Select_Float_Vec2) {
|
||||
auto* builtin = Call("select", vec2<float>(1.0f, 1.0f),
|
||||
vec2<float>(1.0f, 1.0f), vec2<bool>(true, true));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Vec2) {
|
||||
auto* builtin =
|
||||
Call("select", vec2<int>(1, 1), vec2<int>(1, 1), vec2<bool>(true, true));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Select_Boolean_Vec2) {
|
||||
auto* builtin = Call("select", vec2<bool>(true, true), vec2<bool>(true, true),
|
||||
vec2<bool>(true, true));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class ResolverBuiltinsValidationTestWithParams
|
||||
: public resolver::TestHelper,
|
||||
public testing::TestWithParam<T> {};
|
||||
|
||||
using FloatAllMatching =
|
||||
ResolverBuiltinsValidationTestWithParams<std::tuple<std::string, uint32_t>>;
|
||||
|
||||
TEST_P(FloatAllMatching, Scalar) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(Expr(1.0f));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>());
|
||||
}
|
||||
|
||||
TEST_P(FloatAllMatching, Vec2) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec2<float>(1.0f, 1.0f));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
}
|
||||
|
||||
TEST_P(FloatAllMatching, Vec3) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec3<float>(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
}
|
||||
|
||||
TEST_P(FloatAllMatching, Vec4) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
|
||||
FloatAllMatching,
|
||||
::testing::Values(std::make_tuple("abs", 1),
|
||||
std::make_tuple("acos", 1),
|
||||
std::make_tuple("asin", 1),
|
||||
std::make_tuple("atan", 1),
|
||||
std::make_tuple("atan2", 2),
|
||||
std::make_tuple("ceil", 1),
|
||||
std::make_tuple("clamp", 3),
|
||||
std::make_tuple("cos", 1),
|
||||
std::make_tuple("cosh", 1),
|
||||
std::make_tuple("dpdx", 1),
|
||||
std::make_tuple("dpdxCoarse", 1),
|
||||
std::make_tuple("dpdxFine", 1),
|
||||
std::make_tuple("dpdy", 1),
|
||||
std::make_tuple("dpdyCoarse", 1),
|
||||
std::make_tuple("dpdyFine", 1),
|
||||
std::make_tuple("exp", 1),
|
||||
std::make_tuple("exp2", 1),
|
||||
std::make_tuple("faceForward", 3),
|
||||
std::make_tuple("floor", 1),
|
||||
std::make_tuple("fma", 3),
|
||||
std::make_tuple("fract", 1),
|
||||
std::make_tuple("fwidth", 1),
|
||||
std::make_tuple("fwidthCoarse", 1),
|
||||
std::make_tuple("fwidthFine", 1),
|
||||
std::make_tuple("inverseSqrt", 1),
|
||||
std::make_tuple("log", 1),
|
||||
std::make_tuple("log2", 1),
|
||||
std::make_tuple("max", 2),
|
||||
std::make_tuple("min", 2),
|
||||
std::make_tuple("mix", 3),
|
||||
std::make_tuple("pow", 2),
|
||||
std::make_tuple("reflect", 2),
|
||||
std::make_tuple("round", 1),
|
||||
std::make_tuple("sign", 1),
|
||||
std::make_tuple("sin", 1),
|
||||
std::make_tuple("sinh", 1),
|
||||
std::make_tuple("smoothStep", 3),
|
||||
std::make_tuple("sqrt", 1),
|
||||
std::make_tuple("step", 2),
|
||||
std::make_tuple("tan", 1),
|
||||
std::make_tuple("tanh", 1),
|
||||
std::make_tuple("trunc", 1)));
|
||||
|
||||
using IntegerAllMatching =
|
||||
ResolverBuiltinsValidationTestWithParams<std::tuple<std::string, uint32_t>>;
|
||||
|
||||
TEST_P(IntegerAllMatching, ScalarUnsigned) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(Construct<uint32_t>(1));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<type::U32>());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, Vec2Unsigned) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec2<uint32_t>(1u, 1u));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, Vec3Unsigned) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec3<uint32_t>(1u, 1u, 1u));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, Vec4Unsigned) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec4<uint32_t>(1u, 1u, 1u, 1u));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, ScalarSigned) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(Construct<int32_t>(1));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<type::I32>());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, Vec2Signed) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec2<int32_t>(1, 1));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, Vec3Signed) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec3<int32_t>(1, 1, 1));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector());
|
||||
}
|
||||
|
||||
TEST_P(IntegerAllMatching, Vec4Signed) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec4<int32_t>(1, 1, 1, 1));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
|
||||
IntegerAllMatching,
|
||||
::testing::Values(std::make_tuple("abs", 1),
|
||||
std::make_tuple("clamp", 3),
|
||||
std::make_tuple("countOneBits", 1),
|
||||
std::make_tuple("max", 2),
|
||||
std::make_tuple("min", 2),
|
||||
std::make_tuple("reverseBits", 1)));
|
||||
|
||||
using BooleanVectorInput =
|
||||
ResolverBuiltinsValidationTestWithParams<std::tuple<std::string, uint32_t>>;
|
||||
|
||||
TEST_P(BooleanVectorInput, Vec2) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec2<bool>(true, true));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_P(BooleanVectorInput, Vec3) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec3<bool>(true, true, true));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_P(BooleanVectorInput, Vec4) {
|
||||
std::string name = std::get<0>(GetParam());
|
||||
uint32_t num_params = std::get<1>(GetParam());
|
||||
|
||||
ast::ExpressionList params;
|
||||
for (uint32_t i = 0; i < num_params; ++i) {
|
||||
params.push_back(vec4<bool>(true, true, true, true));
|
||||
}
|
||||
auto* builtin = Call(name, params);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
|
||||
BooleanVectorInput,
|
||||
::testing::Values(std::make_tuple("all", 1),
|
||||
std::make_tuple("any", 1)));
|
||||
|
||||
using DataPacking4x8 = ResolverBuiltinsValidationTestWithParams<std::string>;
|
||||
|
||||
TEST_P(DataPacking4x8, Float_Vec4) {
|
||||
auto name = GetParam();
|
||||
auto* builtin = Call(name, vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
|
||||
DataPacking4x8,
|
||||
::testing::Values("pack4x8snorm", "pack4x8unorm"));
|
||||
|
||||
using DataPacking2x16 = ResolverBuiltinsValidationTestWithParams<std::string>;
|
||||
|
||||
TEST_P(DataPacking2x16, Float_Vec2) {
|
||||
auto name = GetParam();
|
||||
auto* builtin = Call(name, vec2<float>(1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
|
||||
DataPacking2x16,
|
||||
::testing::Values("pack2x16snorm",
|
||||
"pack2x16unorm",
|
||||
"pack2x16float"));
|
||||
|
||||
} // namespace
|
||||
} // namespace tint
|
||||
@@ -582,7 +582,8 @@ bool Resolver::Call(ast::CallExpression* call) {
|
||||
auto callee_func_it = symbol_to_function_.find(ident->symbol());
|
||||
if (callee_func_it == symbol_to_function_.end()) {
|
||||
if (current_function_->declaration->symbol() == ident->symbol()) {
|
||||
diagnostics_.add_error("recursion is not permitted. '" + name +
|
||||
diagnostics_.add_error("v-0004",
|
||||
"recursion is not permitted. '" + name +
|
||||
"' attempted to call itself.",
|
||||
call->source());
|
||||
} else {
|
||||
@@ -637,39 +638,6 @@ bool Resolver::IntrinsicCall(ast::CallExpression* call,
|
||||
if (!result.intrinsic) {
|
||||
// Intrinsic lookup failed.
|
||||
diagnostics_.add(result.diagnostics);
|
||||
|
||||
// TODO(bclayton): https://crbug.com/tint/487
|
||||
// The Validator expects intrinsic signature mismatches to still produce
|
||||
// type information. The rules for what the Validator expects are rather
|
||||
// bespoke. Try to match what the Validator expects. As the Validator's
|
||||
// checks on intrinsics is now almost entirely covered by the
|
||||
// IntrinsicTable, we should remove the Validator checks on intrinsic
|
||||
// signatures and remove these hacks.
|
||||
semantic::ParameterList parameters;
|
||||
parameters.reserve(arg_tys.size());
|
||||
for (auto* arg : arg_tys) {
|
||||
parameters.emplace_back(semantic::Parameter{arg});
|
||||
}
|
||||
type::Type* ret_ty = nullptr;
|
||||
switch (intrinsic_type) {
|
||||
case IntrinsicType::kCross:
|
||||
ret_ty = builder_->ty.vec3<ProgramBuilder::f32>();
|
||||
break;
|
||||
case IntrinsicType::kDeterminant:
|
||||
ret_ty = builder_->create<type::F32>();
|
||||
break;
|
||||
case IntrinsicType::kArrayLength:
|
||||
ret_ty = builder_->create<type::U32>();
|
||||
break;
|
||||
default:
|
||||
ret_ty = arg_tys.empty() ? builder_->ty.void_() : arg_tys[0];
|
||||
break;
|
||||
}
|
||||
auto* intrinsic = builder_->create<semantic::Intrinsic>(intrinsic_type,
|
||||
ret_ty, parameters);
|
||||
builder_->Sem().Add(call, builder_->create<semantic::Call>(
|
||||
call, intrinsic, current_statement_));
|
||||
SetType(call, ret_ty);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,8 @@ TEST_F(ResolverValidationTest, Stmt_Call_recursive) {
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: recursion is not permitted. 'main' attempted to call "
|
||||
"12:34 error v-0004: recursion is not permitted. 'main' attempted "
|
||||
"to call "
|
||||
"itself.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user