tint: Replace all remaining AST types with ast::Type

This CL removes the following AST nodes:
* ast::Array
* ast::Atomic
* ast::Matrix
* ast::MultisampledTexture
* ast::Pointer
* ast::SampledTexture
* ast::Texture
* ast::TypeName
* ast::Vector

ast::Type, which used to be the base class for all AST types, is now a
thin wrapper around ast::IdentifierExpression. All types are now
referred to using their type name.

The resolver now handles type resolution and validation of the types
listed above based on the TemplateIdentifier arguments.

Other changes:
* ProgramBuilder has undergone substantial refactoring.
* ProgramBuilder helpers for type inferencing is now more explicit.
  Instead of passing 'nullptr', a new 'Infer' template argument is
  passed.
* ast::CheckIdentifier() is used for more tests that check identifiers,
  including types.

Bug: tint:1810
Change-Id: I8e739ef49435dc1c20a462f3ec5ba265661a7edb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118723
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton 2023-02-14 13:52:43 +00:00 committed by Dawn LUCI CQ
parent c950ff08b6
commit 971318f7a2
295 changed files with 4613 additions and 5901 deletions

View File

@ -239,9 +239,7 @@ libtint_source_set("libtint_syntax_tree_src") {
sources = [
"ast/accessor_expression.h",
"ast/alias.h",
"ast/array.h",
"ast/assignment_statement.h",
"ast/atomic.h",
"ast/attribute.h",
"ast/binary_expression.h",
"ast/binding_attribute.h",
@ -286,19 +284,15 @@ libtint_source_set("libtint_syntax_tree_src") {
"ast/literal_expression.h",
"ast/location_attribute.h",
"ast/loop_statement.h",
"ast/matrix.h",
"ast/member_accessor_expression.h",
"ast/module.h",
"ast/multisampled_texture.h",
"ast/node.h",
"ast/node_id.h",
"ast/override.h",
"ast/parameter.h",
"ast/phony_expression.h",
"ast/pipeline_stage.h",
"ast/pointer.h",
"ast/return_statement.h",
"ast/sampled_texture.h",
"ast/stage_attribute.h",
"ast/statement.h",
"ast/stride_attribute.h",
@ -309,17 +303,14 @@ libtint_source_set("libtint_syntax_tree_src") {
"ast/struct_member_size_attribute.h",
"ast/switch_statement.h",
"ast/templated_identifier.h",
"ast/texture.h",
"ast/traverse_expressions.h",
"ast/type.h",
"ast/type_decl.h",
"ast/type_name.h",
"ast/unary_op.h",
"ast/unary_op_expression.h",
"ast/var.h",
"ast/variable.h",
"ast/variable_decl_statement.h",
"ast/vector.h",
"ast/while_statement.h",
"ast/workgroup_attribute.h",
"clone_context.cc",
@ -542,12 +533,8 @@ libtint_source_set("libtint_ast_src") {
"ast/accessor_expression.h",
"ast/alias.cc",
"ast/alias.h",
"ast/array.cc",
"ast/array.h",
"ast/assignment_statement.cc",
"ast/assignment_statement.h",
"ast/atomic.cc",
"ast/atomic.h",
"ast/attribute.cc",
"ast/attribute.h",
"ast/binary_expression.cc",
@ -636,14 +623,10 @@ libtint_source_set("libtint_ast_src") {
"ast/location_attribute.h",
"ast/loop_statement.cc",
"ast/loop_statement.h",
"ast/matrix.cc",
"ast/matrix.h",
"ast/member_accessor_expression.cc",
"ast/member_accessor_expression.h",
"ast/module.cc",
"ast/module.h",
"ast/multisampled_texture.cc",
"ast/multisampled_texture.h",
"ast/node.cc",
"ast/node.h",
"ast/node_id.h",
@ -655,12 +638,8 @@ libtint_source_set("libtint_ast_src") {
"ast/phony_expression.h",
"ast/pipeline_stage.cc",
"ast/pipeline_stage.h",
"ast/pointer.cc",
"ast/pointer.h",
"ast/return_statement.cc",
"ast/return_statement.h",
"ast/sampled_texture.cc",
"ast/sampled_texture.h",
"ast/stage_attribute.cc",
"ast/stage_attribute.h",
"ast/statement.cc",
@ -681,15 +660,11 @@ libtint_source_set("libtint_ast_src") {
"ast/switch_statement.h",
"ast/templated_identifier.cc",
"ast/templated_identifier.h",
"ast/texture.cc",
"ast/texture.h",
"ast/traverse_expressions.h",
"ast/type.cc",
"ast/type.h",
"ast/type_decl.cc",
"ast/type_decl.h",
"ast/type_name.cc",
"ast/type_name.h",
"ast/unary_op.cc",
"ast/unary_op.h",
"ast/unary_op_expression.cc",
@ -700,8 +675,6 @@ libtint_source_set("libtint_ast_src") {
"ast/variable.h",
"ast/variable_decl_statement.cc",
"ast/variable_decl_statement.h",
"ast/vector.cc",
"ast/vector.h",
"ast/while_statement.cc",
"ast/while_statement.h",
"ast/workgroup_attribute.cc",
@ -1294,9 +1267,7 @@ if (tint_build_unittests) {
tint_unittests_source_set("tint_unittests_ast_src") {
sources = [
"ast/alias_test.cc",
"ast/array_test.cc",
"ast/assignment_statement_test.cc",
"ast/atomic_test.cc",
"ast/binary_expression_test.cc",
"ast/binding_attribute_test.cc",
"ast/bitcast_expression_test.cc",
@ -1336,14 +1307,10 @@ if (tint_build_unittests) {
"ast/invariant_attribute_test.cc",
"ast/location_attribute_test.cc",
"ast/loop_statement_test.cc",
"ast/matrix_test.cc",
"ast/member_accessor_expression_test.cc",
"ast/module_test.cc",
"ast/multisampled_texture_test.cc",
"ast/phony_expression_test.cc",
"ast/pointer_test.cc",
"ast/return_statement_test.cc",
"ast/sampled_texture_test.cc",
"ast/stage_attribute_test.cc",
"ast/stride_attribute_test.cc",
"ast/struct_member_align_attribute_test.cc",
@ -1353,13 +1320,10 @@ if (tint_build_unittests) {
"ast/struct_test.cc",
"ast/switch_statement_test.cc",
"ast/templated_identifier_test.cc",
"ast/texture_test.cc",
"ast/traverse_expressions_test.cc",
"ast/type_name_test.cc",
"ast/unary_op_expression_test.cc",
"ast/variable_decl_statement_test.cc",
"ast/variable_test.cc",
"ast/vector_test.cc",
"ast/while_statement_test.cc",
"ast/workgroup_attribute_test.cc",
]
@ -1489,7 +1453,6 @@ if (tint_build_unittests) {
sources = [
"type/access_test.cc",
"type/address_space_test.cc",
"type/array_test.cc",
"type/atomic_test.cc",
"type/bool_test.cc",
"type/builtin_test.cc",
@ -1583,6 +1546,7 @@ if (tint_build_unittests) {
deps = [
":libtint_base_src",
":libtint_transform_src",
":libtint_unittests_ast_helper",
":libtint_wgsl_reader_src",
":libtint_wgsl_writer_src",
]
@ -1626,6 +1590,7 @@ if (tint_build_unittests) {
]
deps = [
":libtint_base_src",
":libtint_unittests_ast_helper",
":libtint_writer_src",
]
}

View File

@ -84,12 +84,8 @@ list(APPEND TINT_LIB_SRCS
ast/accessor_expression.h
ast/alias.cc
ast/alias.h
ast/array.cc
ast/array.h
ast/assignment_statement.cc
ast/assignment_statement.h
ast/atomic.cc
ast/atomic.h
ast/attribute.cc
ast/attribute.h
ast/binary_expression.cc
@ -172,14 +168,10 @@ list(APPEND TINT_LIB_SRCS
ast/location_attribute.h
ast/loop_statement.cc
ast/loop_statement.h
ast/matrix.cc
ast/matrix.h
ast/member_accessor_expression.cc
ast/member_accessor_expression.h
ast/module.cc
ast/module.h
ast/multisampled_texture.cc
ast/multisampled_texture.h
ast/node_id.h
ast/node.cc
ast/node.h
@ -191,12 +183,8 @@ list(APPEND TINT_LIB_SRCS
ast/phony_expression.h
ast/pipeline_stage.cc
ast/pipeline_stage.h
ast/pointer.cc
ast/pointer.h
ast/return_statement.cc
ast/return_statement.h
ast/sampled_texture.cc
ast/sampled_texture.h
ast/stage_attribute.cc
ast/stage_attribute.h
ast/statement.cc
@ -217,15 +205,11 @@ list(APPEND TINT_LIB_SRCS
ast/switch_statement.h
ast/templated_identifier.cc
ast/templated_identifier.h
ast/texture.cc
ast/texture.h
ast/traverse_expressions.h
ast/type_decl.cc
ast/type_decl.h
ast/type_name.cc
ast/type_name.h
ast/type.cc
ast/type.h
ast/type_decl.cc
ast/type_decl.h
ast/unary_op_expression.cc
ast/unary_op_expression.h
ast/unary_op.cc
@ -236,8 +220,6 @@ list(APPEND TINT_LIB_SRCS
ast/variable_decl_statement.h
ast/variable.cc
ast/variable.h
ast/vector.cc
ast/vector.h
ast/while_statement.cc
ast/while_statement.h
ast/workgroup_attribute.cc
@ -808,9 +790,7 @@ endif()
if(TINT_BUILD_TESTS)
list(APPEND TINT_TEST_SRCS
ast/alias_test.cc
ast/array_test.cc
ast/assignment_statement_test.cc
ast/atomic_test.cc
ast/binary_expression_test.cc
ast/binding_attribute_test.cc
ast/bitcast_expression_test.cc
@ -847,14 +827,10 @@ if(TINT_BUILD_TESTS)
ast/invariant_attribute_test.cc
ast/location_attribute_test.cc
ast/loop_statement_test.cc
ast/matrix_test.cc
ast/member_accessor_expression_test.cc
ast/module_test.cc
ast/multisampled_texture_test.cc
ast/phony_expression_test.cc
ast/pointer_test.cc
ast/return_statement_test.cc
ast/sampled_texture_test.cc
ast/stage_attribute_test.cc
ast/stride_attribute_test.cc
ast/struct_member_align_attribute_test.cc
@ -866,13 +842,10 @@ if(TINT_BUILD_TESTS)
ast/templated_identifier_test.cc
ast/test_helper.h
ast/test_helper_test.cc
ast/texture_test.cc
ast/traverse_expressions_test.cc
ast/type_name_test.cc
ast/unary_op_expression_test.cc
ast/variable_decl_statement_test.cc
ast/variable_test.cc
ast/vector_test.cc
ast/while_statement_test.cc
ast/workgroup_attribute_test.cc
castable_test.cc

View File

@ -20,7 +20,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::Alias);
namespace tint::ast {
Alias::Alias(ProgramID pid, NodeID nid, const Source& src, const Identifier* n, const Type* subtype)
Alias::Alias(ProgramID pid, NodeID nid, const Source& src, const Identifier* n, Type subtype)
: Base(pid, nid, src, n), type(subtype) {
TINT_ASSERT(AST, type);
}
@ -33,7 +33,7 @@ const Alias* Alias::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sym = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
return ctx->dst->create<Alias>(src, sym, ty);
}

View File

@ -17,13 +17,9 @@
#include <string>
#include "src/tint/ast/type.h"
#include "src/tint/ast/type_decl.h"
// Forward declarations
namespace tint::ast {
class Type;
} // namespace tint::ast
namespace tint::ast {
/// A type alias type. Holds a name and pointer to another type.
@ -35,11 +31,7 @@ class Alias final : public Castable<Alias, TypeDecl> {
/// @param src the source of this node
/// @param name the symbol for the alias
/// @param subtype the alias'd type
Alias(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* name,
const Type* subtype);
Alias(ProgramID pid, NodeID nid, const Source& src, const Identifier* name, Type subtype);
/// Move constructor
Alias(Alias&&);
/// Destructor
@ -51,7 +43,7 @@ class Alias final : public Castable<Alias, TypeDecl> {
const Alias* Clone(CloneContext* ctx) const override;
/// the alias type
const Type* const type;
const Type type;
};
} // namespace tint::ast

View File

@ -13,13 +13,7 @@
// limitations under the License.
#include "src/tint/ast/alias.h"
#include "src/tint/ast/array.h"
#include "src/tint/ast/matrix.h"
#include "src/tint/ast/pointer.h"
#include "src/tint/ast/struct.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/type/access.h"
namespace tint::ast {
@ -28,10 +22,10 @@ namespace {
using AstAliasTest = TestHelper;
TEST_F(AstAliasTest, Create) {
auto* u32 = ty.u32();
auto u32 = ty.u32();
auto* a = Alias("a_type", u32);
EXPECT_EQ(Symbols().NameFor(a->name->symbol), "a_type");
EXPECT_EQ(a->type, u32);
CheckIdentifier(Symbols(), a->name, "a_type");
CheckIdentifier(Symbols(), a->type, "u32");
}
} // namespace

View File

@ -1,80 +0,0 @@
// Copyright 2020 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/tint/ast/array.h"
#include <cmath>
#include <utility>
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Array);
namespace tint::ast {
namespace {
// Returns the string representation of an array size expression.
std::string SizeExprToString(const Expression* size, const SymbolTable& symbols) {
if (auto* ident = size->As<IdentifierExpression>()) {
return symbols.NameFor(ident->identifier->symbol);
}
if (auto* literal = size->As<IntLiteralExpression>()) {
return std::to_string(literal->value);
}
// This will never be exposed to the user as the Resolver will reject this
// expression for array size.
return "<invalid>";
}
} // namespace
Array::Array(ProgramID pid,
NodeID nid,
const Source& src,
const Type* subtype,
const Expression* cnt,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src), type(subtype), count(cnt), attributes(std::move(attrs)) {}
Array::Array(Array&&) = default;
Array::~Array() = default;
std::string Array::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
for (auto* attr : attributes) {
if (auto* stride = attr->As<ast::StrideAttribute>()) {
out << "@stride(" << stride->stride << ") ";
}
}
out << "array";
if (type) {
out << "<" << type->FriendlyName(symbols);
if (count) {
out << ", " << SizeExprToString(count, symbols);
}
out << ">";
}
return out.str();
}
const Array* Array::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
auto* cnt = ctx->Clone(count);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Array>(src, ty, cnt, std::move(attrs));
}
} // namespace tint::ast

View File

@ -1,77 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_ARRAY_H_
#define SRC_TINT_AST_ARRAY_H_
#include <string>
#include "src/tint/ast/attribute.h"
#include "src/tint/ast/type.h"
// Forward declarations
namespace tint::ast {
class Expression;
} // namespace tint::ast
namespace tint::ast {
/// An array type. If size is zero then it is a runtime array.
class Array final : public Castable<Array, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param subtype the type of the array elements
/// @param count the number of elements in the array
/// @param attributes the array attributes
/// @note a runtime-sized array is represented by a null count and a non-null type
Array(ProgramID pid,
NodeID nid,
const Source& src,
const Type* subtype,
const Expression* count,
utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Array(Array&&);
~Array() override;
/// @returns true if this is a runtime array.
/// i.e. the size is determined at runtime
bool IsRuntimeArray() const { return type != nullptr && count == nullptr; }
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Array* Clone(CloneContext* ctx) const override;
/// the array element type
const Type* const type;
/// the array size in elements, or nullptr for a runtime array
const Expression* const count;
/// the array attributes
const utils::Vector<const Attribute*, 1> attributes;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_ARRAY_H_

View File

@ -1,84 +0,0 @@
// Copyright 2020 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/tint/ast/array.h"
#include "src/tint/ast/test_helper.h"
using namespace tint::number_suffixes; // NOLINT
namespace tint::ast {
namespace {
using AstArrayTest = TestHelper;
TEST_F(AstArrayTest, CreateSizedArray) {
auto* count = Expr(3_u);
auto* arr = create<Array>(ty.u32(), count, utils::Empty);
ASSERT_TRUE(arr->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(arr->type->As<ast::TypeName>()->name->symbol), "u32");
EXPECT_EQ(arr->count, count);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_FALSE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, CreateRuntimeArray) {
auto* arr = create<Array>(ty.u32(), nullptr, utils::Empty);
ASSERT_TRUE(arr->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(arr->type->As<ast::TypeName>()->name->symbol), "u32");
EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_TRUE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, CreateInferredTypeArray) {
auto* arr = create<Array>(nullptr, nullptr, utils::Empty);
EXPECT_EQ(arr->type, nullptr);
EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_FALSE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
auto* arr = create<Array>(ty.i32(), nullptr, utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
}
TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
auto* arr = create<Array>(ty.i32(), Expr(5_u), utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
}
TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
auto* arr = create<Array>(ty.i32(), Expr("size"), utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
}
TEST_F(AstArrayTest, FriendlyName_WithStride) {
auto* arr = create<Array>(ty.i32(), Expr(5_u), utils::Vector{create<StrideAttribute>(32u)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
}
TEST_F(AstArrayTest, FriendlyName_InferredTypeAndCount) {
auto* arr = create<Array>(nullptr, nullptr, utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array");
}
TEST_F(AstArrayTest, FriendlyName_InferredTypeAndCount_WithStrize) {
auto* arr = create<Array>(nullptr, nullptr, utils::Vector{create<StrideAttribute>(32u)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array");
}
} // namespace
} // namespace tint::ast

View File

@ -1,43 +0,0 @@
// 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/tint/ast/atomic.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Atomic);
namespace tint::ast {
Atomic::Atomic(ProgramID pid, NodeID nid, const Source& src, const Type* const subtype)
: Base(pid, nid, src), type(subtype) {}
std::string Atomic::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "atomic<" << type->FriendlyName(symbols) << ">";
return out.str();
}
Atomic::Atomic(Atomic&&) = default;
Atomic::~Atomic() = default;
const Atomic* Atomic::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Atomic>(src, ty);
}
} // namespace tint::ast

View File

@ -1,53 +0,0 @@
// 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.
#ifndef SRC_TINT_AST_ATOMIC_H_
#define SRC_TINT_AST_ATOMIC_H_
#include <string>
#include "src/tint/ast/type.h"
namespace tint::ast {
/// An atomic type.
class Atomic final : public Castable<Atomic, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param subtype the pointee type
Atomic(ProgramID pid, NodeID nid, const Source& src, const Type* const subtype);
/// Move constructor
Atomic(Atomic&&);
~Atomic() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Atomic* Clone(CloneContext* ctx) const override;
/// the pointee type
const Type* const type;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_ATOMIC_H_

View File

@ -1,38 +0,0 @@
// 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/tint/ast/atomic.h"
#include "src/tint/ast/test_helper.h"
namespace tint::ast {
namespace {
using AstAtomicTest = TestHelper;
TEST_F(AstAtomicTest, Creation) {
auto* i32 = ty.i32();
auto* p = create<Atomic>(i32);
ASSERT_TRUE(p->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(p->type->As<ast::TypeName>()->name->symbol), "i32");
}
TEST_F(AstAtomicTest, FriendlyName) {
auto* i32 = ty.i32();
auto* p = create<Atomic>(i32);
EXPECT_EQ(p->FriendlyName(Symbols()), "atomic<i32>");
}
} // namespace
} // namespace tint::ast

View File

@ -23,7 +23,7 @@ namespace tint::ast {
BitcastExpression::BitcastExpression(ProgramID pid,
NodeID nid,
const Source& src,
const Type* t,
Type t,
const Expression* e)
: Base(pid, nid, src), type(t), expr(e) {
TINT_ASSERT(AST, type);
@ -37,7 +37,7 @@ BitcastExpression::~BitcastExpression() = default;
const BitcastExpression* BitcastExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* t = ctx->Clone(type);
auto t = ctx->Clone(type);
auto* e = ctx->Clone(expr);
return ctx->dst->create<BitcastExpression>(src, t, e);
}

View File

@ -16,11 +16,7 @@
#define SRC_TINT_AST_BITCAST_EXPRESSION_H_
#include "src/tint/ast/expression.h"
// Forward declarations
namespace tint::ast {
class Type;
} // namespace tint::ast
#include "src/tint/ast/type.h"
namespace tint::ast {
@ -36,7 +32,7 @@ class BitcastExpression final : public Castable<BitcastExpression, Expression> {
BitcastExpression(ProgramID pid,
NodeID nid,
const Source& source,
const Type* type,
Type type,
const Expression* expr);
/// Move constructor
BitcastExpression(BitcastExpression&&);
@ -49,7 +45,7 @@ class BitcastExpression final : public Castable<BitcastExpression, Expression> {
const BitcastExpression* Clone(CloneContext* ctx) const override;
/// the target cast type
const Type* const type;
const Type type;
/// the expression
const Expression* const expr;
};

View File

@ -24,17 +24,15 @@ using BitcastExpressionTest = TestHelper;
TEST_F(BitcastExpressionTest, Create) {
auto* expr = Expr("expr");
auto* exp = create<BitcastExpression>(ty.f32(), expr);
ASSERT_TRUE(exp->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(exp->type->As<ast::TypeName>()->name->symbol), "f32");
auto* exp = Bitcast(ty.f32(), expr);
CheckIdentifier(Symbols(), exp->type, "f32");
ASSERT_EQ(exp->expr, expr);
}
TEST_F(BitcastExpressionTest, CreateWithSource) {
auto* expr = Expr("expr");
auto* exp = create<BitcastExpression>(Source{Source::Location{20, 2}}, ty.f32(), expr);
auto* exp = Bitcast(Source{Source::Location{20, 2}}, ty.f32(), expr);
auto src = exp->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
@ -43,7 +41,7 @@ TEST_F(BitcastExpressionTest, CreateWithSource) {
TEST_F(BitcastExpressionTest, IsBitcast) {
auto* expr = Expr("expr");
auto* exp = create<BitcastExpression>(ty.f32(), expr);
auto* exp = Bitcast(ty.f32(), expr);
EXPECT_TRUE(exp->Is<BitcastExpression>());
}
@ -51,7 +49,7 @@ TEST_F(BitcastExpressionTest, Assert_Null_Type) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BitcastExpression>(nullptr, b.Expr("idx"));
b.Bitcast(ast::Type(), "idx");
},
"internal compiler error");
}
@ -60,7 +58,7 @@ TEST_F(BitcastExpressionTest, Assert_Null_Expr) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BitcastExpression>(b.ty.f32(), nullptr);
b.Bitcast(b.ty.f32(), nullptr);
},
"internal compiler error");
}
@ -70,7 +68,7 @@ TEST_F(BitcastExpressionTest, Assert_DifferentProgramID_Expr) {
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BitcastExpression>(b1.ty.f32(), b2.Expr("idx"));
b1.Bitcast(b1.ty.f32(), b2.Expr("idx"));
},
"internal compiler error");
}

View File

@ -127,7 +127,7 @@ std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data) {
return out;
}
const ast::Type* TextureOverloadCase::BuildResultVectorComponentType(ProgramBuilder* b) const {
ast::Type TextureOverloadCase::BuildResultVectorComponentType(ProgramBuilder* b) const {
switch (texture_data_type) {
case ast::builtin::test::TextureDataType::kF32:
return b->ty.f32();
@ -166,7 +166,7 @@ const ast::Variable* TextureOverloadCase::BuildTextureVariable(ProgramBuilder* b
attrs);
case ast::builtin::test::TextureKind::kStorage: {
auto* st = b->ty.storage_texture(texture_dimension, texel_format, access);
auto st = b->ty.storage_texture(texture_dimension, texel_format, access);
return b->GlobalVar(kTextureName, st, attrs);
}
}

View File

@ -224,7 +224,7 @@ struct TextureOverloadCase {
/// @param builder the AST builder used for the test
/// @returns the vector component type of the texture function return value
const ast::Type* BuildResultVectorComponentType(ProgramBuilder* builder) const;
ast::Type BuildResultVectorComponentType(ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test
/// @returns a variable holding the test texture, automatically registered as
/// a global variable.

View File

@ -22,41 +22,14 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::CallExpression);
namespace tint::ast {
namespace {
CallExpression::Target ToTarget(const Identifier* name) {
CallExpression::Target target;
target.name = name;
return target;
}
CallExpression::Target ToTarget(const Type* type) {
CallExpression::Target target;
target.type = type;
return target;
}
} // namespace
CallExpression::CallExpression(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* name,
const IdentifierExpression* t,
utils::VectorRef<const Expression*> a)
: Base(pid, nid, src), target(ToTarget(name)), args(std::move(a)) {
TINT_ASSERT(AST, name);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
for (auto* arg : args) {
TINT_ASSERT(AST, arg);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
}
}
CallExpression::CallExpression(ProgramID pid,
NodeID nid,
const Source& src,
const Type* type,
utils::VectorRef<const Expression*> a)
: Base(pid, nid, src), target(ToTarget(type)), args(std::move(a)) {
TINT_ASSERT(AST, type);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
: Base(pid, nid, src), target(t), args(std::move(a)) {
TINT_ASSERT(AST, target);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, target, program_id);
for (auto* arg : args) {
TINT_ASSERT(AST, arg);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
@ -71,9 +44,8 @@ const CallExpression* CallExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto p = ctx->Clone(args);
return target.name
? ctx->dst->create<CallExpression>(src, ctx->Clone(target.name), std::move(p))
: ctx->dst->create<CallExpression>(src, ctx->Clone(target.type), std::move(p));
auto t = ctx->Clone(target);
return ctx->dst->create<CallExpression>(src, t, std::move(p));
}
} // namespace tint::ast

View File

@ -19,8 +19,7 @@
// Forward declarations
namespace tint::ast {
class Type;
class Identifier;
class IdentifierExpression;
} // namespace tint::ast
namespace tint::ast {
@ -36,24 +35,12 @@ class CallExpression final : public Castable<CallExpression, Expression> {
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param source the call expression source
/// @param name the function or type name
/// @param target the target of the call
/// @param args the arguments
CallExpression(ProgramID pid,
NodeID nid,
const Source& source,
const Identifier* name,
utils::VectorRef<const Expression*> args);
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param source the call expression source
/// @param type the type
/// @param args the arguments
CallExpression(ProgramID pid,
NodeID nid,
const Source& source,
const Type* type,
const IdentifierExpression* target,
utils::VectorRef<const Expression*> args);
/// Move constructor
@ -66,18 +53,8 @@ class CallExpression final : public Castable<CallExpression, Expression> {
/// @return the newly cloned node
const CallExpression* Clone(CloneContext* ctx) const override;
/// Target is either an identifier, or a Type.
/// One of these must be nullptr and the other a non-nullptr.
struct Target {
/// name is a function or builtin to call, or type name to construct or
/// cast-to
const Identifier* name = nullptr;
/// type to construct or cast-to
const Type* type = nullptr;
};
/// The target function
const Target target;
/// The target function or type
const IdentifierExpression* target;
/// The arguments
const utils::Vector<const Expression*, 8> args;

View File

@ -21,15 +21,14 @@ namespace {
using CallExpressionTest = TestHelper;
TEST_F(CallExpressionTest, CreationIdentifier) {
auto* func = Ident("func");
auto* func = Expr("func");
utils::Vector params{
Expr("param1"),
Expr("param2"),
};
auto* stmt = Call(func, params);
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
EXPECT_EQ(stmt->target, func);
const auto& vec = stmt->args;
ASSERT_EQ(vec.Length(), 2u);
@ -38,10 +37,9 @@ TEST_F(CallExpressionTest, CreationIdentifier) {
}
TEST_F(CallExpressionTest, CreationIdentifier_WithSource) {
auto* func = Ident("func");
auto* func = Expr("func");
auto* stmt = Call(Source{{20, 2}}, func);
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
EXPECT_EQ(stmt->target, func);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
@ -49,15 +47,14 @@ TEST_F(CallExpressionTest, CreationIdentifier_WithSource) {
}
TEST_F(CallExpressionTest, CreationType) {
auto* type = ty.f32();
auto* type = Expr(ty.f32());
utils::Vector params{
Expr("param1"),
Expr("param2"),
};
auto* stmt = Call(type, params);
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
EXPECT_EQ(stmt->target, type);
const auto& vec = stmt->args;
ASSERT_EQ(vec.Length(), 2u);
@ -66,10 +63,9 @@ TEST_F(CallExpressionTest, CreationType) {
}
TEST_F(CallExpressionTest, CreationType_WithSource) {
auto* type = ty.f32();
auto* type = Expr(ty.f32());
auto* stmt = Call(Source{{20, 2}}, type);
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
EXPECT_EQ(stmt->target, type);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
@ -77,7 +73,7 @@ TEST_F(CallExpressionTest, CreationType_WithSource) {
}
TEST_F(CallExpressionTest, IsCall) {
auto* func = Ident("func");
auto* func = Expr("func");
auto* stmt = Call(func);
EXPECT_TRUE(stmt->Is<CallExpression>());
}
@ -91,15 +87,6 @@ TEST_F(CallExpressionTest, Assert_Null_Identifier) {
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_Null_Type) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Call(static_cast<Type*>(nullptr));
},
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_Null_Param) {
EXPECT_FATAL_FAILURE(
{

View File

@ -26,7 +26,7 @@ Const::Const(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
const Expression* init,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, init, std::move(attrs)) {
@ -44,7 +44,7 @@ const char* Const::Kind() const {
const Const* Const::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto n = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Const>(src, n, ty, init, std::move(attrs));

View File

@ -44,7 +44,7 @@ class Const final : public Castable<Const, Variable> {
NodeID nid,
const Source& source,
const Identifier* name,
const ast::Type* type,
Type type,
const Expression* initializer,
utils::VectorRef<const Attribute*> attributes);

View File

@ -27,7 +27,7 @@ Function::Function(ProgramID pid,
const Source& src,
const Identifier* n,
utils::VectorRef<const Parameter*> parameters,
const Type* return_ty,
Type return_ty,
const BlockStatement* b,
utils::VectorRef<const Attribute*> attrs,
utils::VectorRef<const Attribute*> return_type_attrs)
@ -73,7 +73,7 @@ const Function* Function::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto n = ctx->Clone(name);
auto p = ctx->Clone(params);
auto* ret = ctx->Clone(return_type);
auto ret = ctx->Clone(return_type);
auto* b = ctx->Clone(body);
auto attrs = ctx->Clone(attributes);
auto ret_attrs = ctx->Clone(return_type_attributes);

View File

@ -32,6 +32,7 @@
// Forward declarations
namespace tint::ast {
class Identifier;
class IdentifierExpression;
} // namespace tint::ast
namespace tint::ast {
@ -54,7 +55,7 @@ class Function final : public Castable<Function, Node> {
const Source& source,
const Identifier* name,
utils::VectorRef<const Parameter*> params,
const Type* return_type,
Type return_type,
const BlockStatement* body,
utils::VectorRef<const Attribute*> attributes,
utils::VectorRef<const Attribute*> return_type_attributes);
@ -82,7 +83,7 @@ class Function final : public Castable<Function, Node> {
const utils::Vector<const Parameter*, 8> params;
/// The function return type
const Type* const return_type;
const Type return_type;
/// The function body
const BlockStatement* const body;

View File

@ -27,13 +27,13 @@ using FunctionTest = TestHelper;
TEST_F(FunctionTest, Creation_i32ReturnType) {
utils::Vector params{Param("var", ty.i32())};
auto* i32 = ty.i32();
auto i32 = ty.i32();
auto* var = params[0];
auto* f = Func("func", params, i32, utils::Empty);
EXPECT_EQ(f->name->symbol, Symbols().Get("func"));
ASSERT_EQ(f->params.Length(), 1u);
EXPECT_EQ(f->return_type, i32);
CheckIdentifier(Symbols(), f->return_type, "i32");
EXPECT_EQ(f->params[0], var);
}
@ -116,15 +116,6 @@ TEST_F(FunctionTest, Assert_TemplatedName) {
"internal compiler error");
}
TEST_F(FunctionTest, Assert_InvalidName) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Func("", utils::Empty, b.ty.void_(), utils::Empty);
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_NullParam) {
using ParamList = utils::Vector<const ast::Parameter*, 2>;
EXPECT_FATAL_FAILURE(

View File

@ -44,11 +44,6 @@ TEST_F(IdentifierExpressionTest, Creation_WithSource) {
EXPECT_EQ(i->identifier->source.range, (Source::Range{{20, 2}}));
}
TEST_F(IdentifierExpressionTest, IsIdentifier) {
auto* i = Expr("ident");
EXPECT_TRUE(i->Is<IdentifierExpression>());
}
TEST_F(IdentifierExpressionTest, Assert_InvalidSymbol) {
EXPECT_FATAL_FAILURE(
{

View File

@ -26,7 +26,7 @@ Let::Let(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
const Expression* init,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, init, std::move(attrs)) {
@ -44,7 +44,7 @@ const char* Let::Kind() const {
const Let* Let::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Let>(src, n, ty, init, std::move(attrs));

View File

@ -41,7 +41,7 @@ class Let final : public Castable<Let, Variable> {
NodeID nid,
const Source& source,
const Identifier* name,
const ast::Type* type,
Type type,
const Expression* initializer,
utils::VectorRef<const Attribute*> attributes);

View File

@ -1,57 +0,0 @@
// Copyright 2020 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/tint/ast/matrix.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Matrix);
namespace tint::ast {
Matrix::Matrix(ProgramID pid,
NodeID nid,
const Source& src,
const Type* subtype,
uint32_t r,
uint32_t c)
: Base(pid, nid, src), type(subtype), rows(r), columns(c) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, subtype, program_id);
TINT_ASSERT(AST, rows > 1);
TINT_ASSERT(AST, rows < 5);
TINT_ASSERT(AST, columns > 1);
TINT_ASSERT(AST, columns < 5);
}
Matrix::Matrix(Matrix&&) = default;
Matrix::~Matrix() = default;
std::string Matrix::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "mat" << columns << "x" << rows;
if (type) {
out << "<" << type->FriendlyName(symbols) << ">";
}
return out.str();
}
const Matrix* Matrix::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Matrix>(src, ty, rows, columns);
}
} // namespace tint::ast

View File

@ -1,70 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_MATRIX_H_
#define SRC_TINT_AST_MATRIX_H_
#include <string>
#include "src/tint/ast/type.h"
namespace tint::ast {
/// A matrix type
class Matrix final : public Castable<Matrix, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param subtype the declared type of the matrix components. May be null for
/// matrix initializers, where the element type will be inferred from
/// the initializer arguments
/// @param rows the number of rows in the matrix
/// @param columns the number of columns in the matrix
Matrix(ProgramID pid,
NodeID nid,
const Source& src,
const Type* subtype,
uint32_t rows,
uint32_t columns);
/// Move constructor
Matrix(Matrix&&);
~Matrix() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Matrix* Clone(CloneContext* ctx) const override;
/// The declared type of the matrix components. May be null for matrix
/// initializers, where the element type will be inferred from the initializer
/// arguments
const Type* const type;
/// The number of rows in the matrix
const uint32_t rows;
/// The number of columns in the matrix
const uint32_t columns;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_MATRIX_H_

View File

@ -1,49 +0,0 @@
// Copyright 2020 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/tint/ast/matrix.h"
#include "src/tint/ast/alias.h"
#include "src/tint/ast/array.h"
#include "src/tint/ast/pointer.h"
#include "src/tint/ast/struct.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/type/access.h"
namespace tint::ast {
namespace {
using AstMatrixTest = TestHelper;
TEST_F(AstMatrixTest, Creation) {
auto* m = create<Matrix>(ty.i32(), 2u, 4u);
ASSERT_TRUE(m->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(m->type->As<ast::TypeName>()->name->symbol), "i32");
EXPECT_EQ(m->rows, 2u);
EXPECT_EQ(m->columns, 4u);
}
TEST_F(AstMatrixTest, FriendlyName) {
auto* m = create<Matrix>(ty.i32(), 3u, 2u);
EXPECT_EQ(m->FriendlyName(Symbols()), "mat2x3<i32>");
}
TEST_F(AstMatrixTest, FriendlyName_WithoutType) {
auto* m = create<Matrix>(nullptr, 3u, 2u);
EXPECT_EQ(m->FriendlyName(Symbols()), "mat2x3");
}
} // namespace
} // namespace tint::ast

View File

@ -21,7 +21,6 @@
#include "src/tint/ast/diagnostic_directive.h"
#include "src/tint/ast/enable.h"
#include "src/tint/ast/function.h"
#include "src/tint/ast/type.h"
#include "src/tint/utils/vector.h"
namespace tint::ast {

View File

@ -1,49 +0,0 @@
// Copyright 2020 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/tint/ast/multisampled_texture.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::MultisampledTexture);
namespace tint::ast {
MultisampledTexture::MultisampledTexture(ProgramID pid,
NodeID nid,
const Source& src,
type::TextureDimension d,
const Type* ty)
: Base(pid, nid, src, d), type(ty) {
TINT_ASSERT(AST, type);
}
MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;
MultisampledTexture::~MultisampledTexture() = default;
std::string MultisampledTexture::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "texture_multisampled_" << dim << "<" << type->FriendlyName(symbols) << ">";
return out.str();
}
const MultisampledTexture* MultisampledTexture::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<MultisampledTexture>(src, dim, ty);
}
} // namespace tint::ast

View File

@ -1,59 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_MULTISAMPLED_TEXTURE_H_
#define SRC_TINT_AST_MULTISAMPLED_TEXTURE_H_
#include <string>
#include "src/tint/ast/texture.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::ast {
/// A multisampled texture type.
class MultisampledTexture final : public Castable<MultisampledTexture, Texture> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param dim the dimensionality of the texture
/// @param type the data type of the multisampled texture
MultisampledTexture(ProgramID pid,
NodeID nid,
const Source& src,
type::TextureDimension dim,
const Type* type);
/// Move constructor
MultisampledTexture(MultisampledTexture&&);
~MultisampledTexture() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const MultisampledTexture* Clone(CloneContext* ctx) const override;
/// The subtype of the multisampled texture
const Type* const type;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_MULTISAMPLED_TEXTURE_H_

View File

@ -1,56 +0,0 @@
// Copyright 2020 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/tint/ast/multisampled_texture.h"
#include "src/tint/ast/alias.h"
#include "src/tint/ast/array.h"
#include "src/tint/ast/matrix.h"
#include "src/tint/ast/pointer.h"
#include "src/tint/ast/sampled_texture.h"
#include "src/tint/ast/struct.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/type/access.h"
namespace tint::ast {
namespace {
using AstMultisampledTextureTest = TestHelper;
TEST_F(AstMultisampledTextureTest, IsTexture) {
Texture* t = create<MultisampledTexture>(type::TextureDimension::kCube, ty.f32());
EXPECT_TRUE(t->Is<MultisampledTexture>());
EXPECT_FALSE(t->Is<SampledTexture>());
}
TEST_F(AstMultisampledTextureTest, Dim) {
auto* s = create<MultisampledTexture>(type::TextureDimension::k3d, ty.f32());
EXPECT_EQ(s->dim, type::TextureDimension::k3d);
}
TEST_F(AstMultisampledTextureTest, Type) {
auto* s = create<MultisampledTexture>(type::TextureDimension::k3d, ty.f32());
ASSERT_TRUE(s->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(s->type->As<ast::TypeName>()->name->symbol), "f32");
}
TEST_F(AstMultisampledTextureTest, FriendlyName) {
auto* s = create<MultisampledTexture>(type::TextureDimension::k3d, ty.f32());
EXPECT_EQ(s->FriendlyName(Symbols()), "texture_multisampled_3d<f32>");
}
} // namespace
} // namespace tint::ast

View File

@ -26,7 +26,7 @@ Override::Override(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
const Expression* init,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, init, std::move(attrs)) {}
@ -42,7 +42,7 @@ const char* Override::Kind() const {
const Override* Override::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Override>(src, n, ty, init, std::move(attrs));

View File

@ -44,7 +44,7 @@ class Override final : public Castable<Override, Variable> {
NodeID nid,
const Source& source,
const Identifier* name,
const ast::Type* type,
Type type,
const Expression* initializer,
utils::VectorRef<const Attribute*> attributes);

View File

@ -26,7 +26,7 @@ Parameter::Parameter(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, nullptr, std::move(attrs)) {}
@ -41,7 +41,7 @@ const char* Parameter::Kind() const {
const Parameter* Parameter::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Parameter>(src, n, ty, std::move(attrs));
}

View File

@ -44,7 +44,7 @@ class Parameter final : public Castable<Parameter, Variable> {
NodeID nid,
const Source& source,
const Identifier* name,
const ast::Type* type,
Type type,
utils::VectorRef<const Attribute*> attributes);
/// Move constructor

View File

@ -1,56 +0,0 @@
// Copyright 2020 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/tint/ast/pointer.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Pointer);
namespace tint::ast {
Pointer::Pointer(ProgramID pid,
NodeID nid,
const Source& src,
const Type* const subtype,
type::AddressSpace addr_space,
type::Access ac)
: Base(pid, nid, src), type(subtype), address_space(addr_space), access(ac) {}
std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "ptr<";
if (address_space != type::AddressSpace::kNone) {
out << address_space << ", ";
}
out << type->FriendlyName(symbols);
if (access != type::Access::kUndefined) {
out << ", " << access;
}
out << ">";
return out.str();
}
Pointer::Pointer(Pointer&&) = default;
Pointer::~Pointer() = default;
const Pointer* Pointer::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Pointer>(src, ty, address_space, access);
}
} // namespace tint::ast

View File

@ -1,68 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_POINTER_H_
#define SRC_TINT_AST_POINTER_H_
#include <string>
#include "src/tint/ast/type.h"
#include "src/tint/type/access.h"
#include "src/tint/type/address_space.h"
namespace tint::ast {
/// A pointer type.
class Pointer final : public Castable<Pointer, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param subtype the pointee type
/// @param address_space the address space of the pointer
/// @param access the access control of the pointer
Pointer(ProgramID pid,
NodeID nid,
const Source& src,
const Type* const subtype,
type::AddressSpace address_space,
type::Access access);
/// Move constructor
Pointer(Pointer&&);
~Pointer() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Pointer* Clone(CloneContext* ctx) const override;
/// The pointee type
const Type* const type;
/// The address space of the pointer
type::AddressSpace const address_space;
/// The access control of the pointer
type::Access const access;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_POINTER_H_

View File

@ -1,43 +0,0 @@
// Copyright 2020 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/tint/ast/pointer.h"
#include "src/tint/ast/test_helper.h"
namespace tint::ast {
namespace {
using AstPointerTest = TestHelper;
TEST_F(AstPointerTest, Creation) {
auto* p = create<Pointer>(ty.i32(), type::AddressSpace::kStorage, type::Access::kRead);
ASSERT_TRUE(p->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(p->type->As<ast::TypeName>()->name->symbol), "i32");
EXPECT_EQ(p->address_space, type::AddressSpace::kStorage);
EXPECT_EQ(p->access, type::Access::kRead);
}
TEST_F(AstPointerTest, FriendlyName) {
auto* p = create<Pointer>(ty.i32(), type::AddressSpace::kWorkgroup, type::Access::kUndefined);
EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<workgroup, i32>");
}
TEST_F(AstPointerTest, FriendlyNameWithAccess) {
auto* p = create<Pointer>(ty.i32(), type::AddressSpace::kStorage, type::Access::kReadWrite);
EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<storage, i32, read_write>");
}
} // namespace
} // namespace tint::ast

View File

@ -1,49 +0,0 @@
// Copyright 2020 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/tint/ast/sampled_texture.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::SampledTexture);
namespace tint::ast {
SampledTexture::SampledTexture(ProgramID pid,
NodeID nid,
const Source& src,
type::TextureDimension d,
const Type* ty)
: Base(pid, nid, src, d), type(ty) {
TINT_ASSERT(AST, type);
}
SampledTexture::SampledTexture(SampledTexture&&) = default;
SampledTexture::~SampledTexture() = default;
std::string SampledTexture::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "texture_" << dim << "<" << type->FriendlyName(symbols) << ">";
return out.str();
}
const SampledTexture* SampledTexture::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<SampledTexture>(src, dim, ty);
}
} // namespace tint::ast

View File

@ -1,59 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_SAMPLED_TEXTURE_H_
#define SRC_TINT_AST_SAMPLED_TEXTURE_H_
#include <string>
#include "src/tint/ast/texture.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::ast {
/// A sampled texture type.
class SampledTexture final : public Castable<SampledTexture, Texture> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param dim the dimensionality of the texture
/// @param type the data type of the sampled texture
SampledTexture(ProgramID pid,
NodeID nid,
const Source& src,
type::TextureDimension dim,
const Type* type);
/// Move constructor
SampledTexture(SampledTexture&&);
~SampledTexture() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const SampledTexture* Clone(CloneContext* ctx) const override;
/// The subtype of the sampled texture
const Type* const type;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_SAMPLED_TEXTURE_H_

View File

@ -1,46 +0,0 @@
// Copyright 2020 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/tint/ast/sampled_texture.h"
#include "src/tint/ast/test_helper.h"
namespace tint::ast {
namespace {
using AstSampledTextureTest = TestHelper;
TEST_F(AstSampledTextureTest, IsTexture) {
Texture* t = create<SampledTexture>(type::TextureDimension::kCube, ty.f32());
EXPECT_TRUE(t->Is<SampledTexture>());
}
TEST_F(AstSampledTextureTest, Dim) {
auto* s = create<SampledTexture>(type::TextureDimension::k3d, ty.f32());
EXPECT_EQ(s->dim, type::TextureDimension::k3d);
}
TEST_F(AstSampledTextureTest, Type) {
auto* s = create<SampledTexture>(type::TextureDimension::k3d, ty.f32());
ASSERT_TRUE(s->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(s->type->As<ast::TypeName>()->name->symbol), "f32");
}
TEST_F(AstSampledTextureTest, FriendlyName) {
auto* s = create<SampledTexture>(type::TextureDimension::k3d, ty.f32());
EXPECT_EQ(s->FriendlyName(Symbols()), "texture_3d<f32>");
}
} // namespace
} // namespace tint::ast

View File

@ -24,7 +24,7 @@ StructMember::StructMember(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src), name(n), type(ty), attributes(std::move(attrs)) {
@ -47,7 +47,7 @@ const StructMember* StructMember::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto n = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<StructMember>(src, n, ty, std::move(attrs));
}

View File

@ -18,11 +18,11 @@
#include <utility>
#include "src/tint/ast/attribute.h"
#include "src/tint/ast/type.h"
// Forward declarations
namespace tint::ast {
class Identifier;
class Type;
} // namespace tint::ast
namespace tint::ast {
@ -41,7 +41,7 @@ class StructMember final : public Castable<StructMember, Node> {
NodeID nid,
const Source& src,
const Identifier* name,
const ast::Type* type,
Type type,
utils::VectorRef<const Attribute*> attributes);
/// Move constructor
StructMember(StructMember&&);
@ -58,7 +58,7 @@ class StructMember final : public Castable<StructMember, Node> {
const Identifier* const name;
/// The type
const ast::Type* const type;
const Type type;
/// The attributes
const utils::Vector<const Attribute*, 4> attributes;

View File

@ -23,9 +23,8 @@ using StructMemberTest = TestHelper;
TEST_F(StructMemberTest, Creation) {
auto* st = Member("a", ty.i32(), utils::Vector{MemberSize(4_a)});
EXPECT_EQ(Symbols().NameFor(st->name->symbol), "a");
ASSERT_TRUE(st->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(st->type->As<ast::TypeName>()->name->symbol), "i32");
ast::CheckIdentifier(Symbols(), st->name, "a");
ast::CheckIdentifier(Symbols(), st->type, "i32");
EXPECT_EQ(st->attributes.Length(), 1u);
EXPECT_TRUE(st->attributes[0]->Is<StructMemberSizeAttribute>());
EXPECT_EQ(st->source.range.begin.line, 0u);
@ -37,9 +36,8 @@ TEST_F(StructMemberTest, Creation) {
TEST_F(StructMemberTest, CreationWithSource) {
auto* st = Member(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}}, "a",
ty.i32());
EXPECT_EQ(Symbols().NameFor(st->name->symbol), "a");
ASSERT_TRUE(st->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(st->type->As<ast::TypeName>()->name->symbol), "i32");
ast::CheckIdentifier(Symbols(), st->name, "a");
ast::CheckIdentifier(Symbols(), st->type, "i32");
EXPECT_EQ(st->attributes.Length(), 0u);
EXPECT_EQ(st->source.range.begin.line, 27u);
EXPECT_EQ(st->source.range.begin.column, 4u);
@ -60,7 +58,7 @@ TEST_F(StructMemberTest, Assert_Null_Type) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Member("a", nullptr);
b.Member("a", ast::Type{});
},
"internal compiler error");
}

View File

@ -15,12 +15,7 @@
#include "src/tint/ast/struct.h"
#include "gtest/gtest-spi.h"
#include "src/tint/ast/alias.h"
#include "src/tint/ast/array.h"
#include "src/tint/ast/matrix.h"
#include "src/tint/ast/pointer.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/transform/add_block_attribute.h"
namespace tint::ast {

View File

@ -26,10 +26,15 @@ TemplatedIdentifier::TemplatedIdentifier(ProgramID pid,
NodeID nid,
const Source& src,
const Symbol& sym,
utils::VectorRef<const ast::Expression*> args)
: Base(pid, nid, src, sym), arguments(std::move(args)) {
utils::VectorRef<const Expression*> args,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, sym), arguments(std::move(args)), attributes(std::move(attrs)) {
TINT_ASSERT(AST, !arguments.IsEmpty()); // Should have been an Identifier if this fires.
for (auto* arg : arguments) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL(AST, arg, program_id);
}
for (auto* attr : attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
}
}
@ -42,7 +47,8 @@ const TemplatedIdentifier* TemplatedIdentifier::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
auto args = ctx->Clone(arguments);
return ctx->dst->create<TemplatedIdentifier>(src, sym, args);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<TemplatedIdentifier>(src, sym, std::move(args), std::move(attrs));
}
} // namespace tint::ast

View File

@ -19,6 +19,7 @@
// Forward declarations
namespace tint::ast {
class Attribute;
class Expression;
} // namespace tint::ast
@ -33,11 +34,13 @@ class TemplatedIdentifier final : public Castable<TemplatedIdentifier, Identifie
/// @param src the source of this node
/// @param sym the symbol for the identifier
/// @param args the template arguments
/// @param attrs the identifier attributes
TemplatedIdentifier(ProgramID pid,
NodeID nid,
const Source& src,
const Symbol& sym,
utils::VectorRef<const Expression*> args);
utils::VectorRef<const Expression*> args,
utils::VectorRef<const Attribute*> attrs);
/// Move constructor
TemplatedIdentifier(TemplatedIdentifier&&);
~TemplatedIdentifier() override;
@ -49,6 +52,9 @@ class TemplatedIdentifier final : public Castable<TemplatedIdentifier, Identifie
/// The templated arguments
const utils::Vector<const Expression*, 3> arguments;
/// Attributes on the identifier
const utils::Vector<const Attribute*, 0> attributes;
};
} // namespace tint::ast

View File

@ -71,14 +71,13 @@ struct IsTemplatedIdentifierMatcher<TemplatedIdentifierMatcher<ARGS...>> {
static constexpr bool value = true;
};
/// A testing utility for checking that an Identifier and any optional templated arguments match the
/// expected values.
/// A testing utility for checking that an Identifier matches the expected values.
/// @param symbols the symbol table
/// @param got the identifier
/// @param expected the expected identifier name
template <typename... ARGS>
void CheckIdentifier(const SymbolTable& symbols, const Identifier* got, std::string_view expected) {
EXPECT_FALSE(got->Is<ast::TemplatedIdentifier>());
EXPECT_FALSE(got->Is<TemplatedIdentifier>());
EXPECT_EQ(symbols.NameFor(got->symbol), expected);
}
@ -92,8 +91,8 @@ void CheckIdentifier(const SymbolTable& symbols,
const Identifier* ident,
const TemplatedIdentifierMatcher<ARGS...>& expected) {
EXPECT_EQ(symbols.NameFor(ident->symbol), expected.name);
ASSERT_TRUE(ident->Is<ast::TemplatedIdentifier>());
auto* got = ident->As<ast::TemplatedIdentifier>();
ASSERT_TRUE(ident->Is<TemplatedIdentifier>());
auto* got = ident->As<TemplatedIdentifier>();
ASSERT_EQ(got->arguments.Length(), std::tuple_size_v<decltype(expected.args)>);
size_t arg_idx = 0;
@ -103,8 +102,7 @@ void CheckIdentifier(const SymbolTable& symbols,
using T = std::decay_t<decltype(expected_arg)>;
if constexpr (traits::IsStringLike<T>) {
ASSERT_TRUE(got_arg->Is<IdentifierExpression>());
ast::CheckIdentifier(symbols, got_arg->As<IdentifierExpression>()->identifier,
expected_arg);
CheckIdentifier(symbols, got_arg->As<IdentifierExpression>()->identifier, expected_arg);
} else if constexpr (IsTemplatedIdentifierMatcher<T>::value) {
ASSERT_TRUE(got_arg->Is<IdentifierExpression>());
auto* got_ident = got_arg->As<IdentifierExpression>()->identifier;
@ -150,6 +148,33 @@ void CheckIdentifier(const SymbolTable& symbols,
std::apply([&](auto&&... args) { ((check_arg(args)), ...); }, expected.args);
}
/// A testing utility for checking that an IdentifierExpression matches the expected values.
/// @param symbols the symbol table
/// @param expr the IdentifierExpression
/// @param expected the expected identifier name
template <typename... ARGS>
void CheckIdentifier(const SymbolTable& symbols,
const Expression* expr,
std::string_view expected) {
auto* expr_ident = expr->As<IdentifierExpression>();
ASSERT_NE(expr_ident, nullptr) << "expression is not a IdentifierExpression";
CheckIdentifier(symbols, expr_ident->identifier, expected);
}
/// A testing utility for checking that an IdentifierExpression matches the expected name and
/// template arguments.
/// @param symbols the symbol table
/// @param expr the IdentifierExpression
/// @param expected the expected identifier name and arguments
template <typename... ARGS>
void CheckIdentifier(const SymbolTable& symbols,
const Expression* expr,
const TemplatedIdentifierMatcher<ARGS...>& expected) {
auto* expr_ident = expr->As<IdentifierExpression>();
ASSERT_NE(expr_ident, nullptr) << "expression is not a IdentifierExpression";
CheckIdentifier(symbols, expr_ident->identifier, expected);
}
} // namespace tint::ast
#endif // SRC_TINT_AST_TEST_HELPER_H_

View File

@ -1,60 +0,0 @@
// Copyright 2020 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/tint/ast/texture.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Texture);
namespace tint::ast {
bool IsTextureArray(type::TextureDimension dim) {
switch (dim) {
case type::TextureDimension::k2dArray:
case type::TextureDimension::kCubeArray:
return true;
case type::TextureDimension::k2d:
case type::TextureDimension::kNone:
case type::TextureDimension::k1d:
case type::TextureDimension::k3d:
case type::TextureDimension::kCube:
return false;
}
return false;
}
int NumCoordinateAxes(type::TextureDimension dim) {
switch (dim) {
case type::TextureDimension::kNone:
return 0;
case type::TextureDimension::k1d:
return 1;
case type::TextureDimension::k2d:
case type::TextureDimension::k2dArray:
return 2;
case type::TextureDimension::k3d:
case type::TextureDimension::kCube:
case type::TextureDimension::kCubeArray:
return 3;
}
return 0;
}
Texture::Texture(ProgramID pid, NodeID nid, const Source& src, type::TextureDimension d)
: Base(pid, nid, src), dim(d) {}
Texture::Texture(Texture&&) = default;
Texture::~Texture() = default;
} // namespace tint::ast

View File

@ -1,60 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_TEXTURE_H_
#define SRC_TINT_AST_TEXTURE_H_
#include "src/tint/ast/type.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::ast {
/// @param dim the type::TextureDimension to query
/// @return true if the given type::TextureDimension is an array texture
bool IsTextureArray(type::TextureDimension dim);
/// Returns the number of axes in the coordinate used for accessing
/// the texture, where an access is one of: sampling, fetching, load,
/// or store.
/// None -> 0
/// 1D -> 1
/// 2D, 2DArray -> 2
/// 3D, Cube, CubeArray -> 3
/// Note: To sample a cube texture, the coordinate has 3 dimensions,
/// but textureDimensions on a cube or cube array returns a 2-element
/// size, representing the (x,y) size of each cube face, in texels.
/// @param dim the type::TextureDimension to query
/// @return number of dimensions in a coordinate for the dimensionality
int NumCoordinateAxes(type::TextureDimension dim);
/// A texture type.
class Texture : public Castable<Texture, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param dim the dimensionality of the texture
Texture(ProgramID pid, NodeID nid, const Source& src, type::TextureDimension dim);
/// Move constructor
Texture(Texture&&);
~Texture() override;
/// The texture dimension
const type::TextureDimension dim;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_TEXTURE_H_

View File

@ -1,51 +0,0 @@
// 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/tint/ast/texture.h"
#include "src/tint/ast/alias.h"
#include "src/tint/ast/array.h"
#include "src/tint/ast/matrix.h"
#include "src/tint/ast/pointer.h"
#include "src/tint/ast/struct.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/vector.h"
namespace tint::ast {
namespace {
using AstTextureTypeTest = TestHelper;
TEST_F(AstTextureTypeTest, IsTextureArray) {
EXPECT_EQ(false, IsTextureArray(type::TextureDimension::kNone));
EXPECT_EQ(false, IsTextureArray(type::TextureDimension::k1d));
EXPECT_EQ(false, IsTextureArray(type::TextureDimension::k2d));
EXPECT_EQ(true, IsTextureArray(type::TextureDimension::k2dArray));
EXPECT_EQ(false, IsTextureArray(type::TextureDimension::k3d));
EXPECT_EQ(false, IsTextureArray(type::TextureDimension::kCube));
EXPECT_EQ(true, IsTextureArray(type::TextureDimension::kCubeArray));
}
TEST_F(AstTextureTypeTest, NumCoordinateAxes) {
EXPECT_EQ(0, NumCoordinateAxes(type::TextureDimension::kNone));
EXPECT_EQ(1, NumCoordinateAxes(type::TextureDimension::k1d));
EXPECT_EQ(2, NumCoordinateAxes(type::TextureDimension::k2d));
EXPECT_EQ(2, NumCoordinateAxes(type::TextureDimension::k2dArray));
EXPECT_EQ(3, NumCoordinateAxes(type::TextureDimension::k3d));
EXPECT_EQ(3, NumCoordinateAxes(type::TextureDimension::kCube));
EXPECT_EQ(3, NumCoordinateAxes(type::TextureDimension::kCubeArray));
}
} // namespace
} // namespace tint::ast

View File

@ -148,7 +148,8 @@ bool TraverseExpressions(const ast::Expression* root, diag::List& diags, CALLBAC
PhonyExpression>()))) {
return true; // Leaf expression
}
TINT_ICE(AST, diags) << "unhandled expression type: " << expr->TypeInfo().name;
TINT_ICE(AST, diags)
<< "unhandled expression type: " << (expr ? expr->TypeInfo().name : "<null>");
return false;
});
if (!ok) {

View File

@ -1,4 +1,4 @@
// Copyright 2020 The Tint Authors.
// Copyright 2023 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.
@ -13,22 +13,12 @@
// limitations under the License.
#include "src/tint/ast/type.h"
#include "src/tint/ast/identifier_expression.h"
#include "src/tint/ast/alias.h"
#include "src/tint/ast/matrix.h"
#include "src/tint/ast/pointer.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/symbol_table.h"
namespace tint {
TINT_INSTANTIATE_TYPEINFO(tint::ast::Type);
ProgramID ProgramIDOf(ast::Type type) {
return ProgramIDOf(type.expr);
}
namespace tint::ast {
Type::Type(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
Type::Type(Type&&) = default;
Type::~Type() = default;
} // namespace tint::ast
} // namespace tint

View File

@ -1,4 +1,4 @@
// Copyright 2020 The Tint Authors.
// Copyright 2023 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.
@ -15,38 +15,38 @@
#ifndef SRC_TINT_AST_TYPE_H_
#define SRC_TINT_AST_TYPE_H_
#include <string>
#include "src/tint/ast/node.h"
#include "src/tint/clone_context.h"
#include "src/tint/program_id.h"
// Forward declarations
namespace tint {
class ProgramBuilder;
class SymbolTable;
} // namespace tint
namespace tint::ast {
class IdentifierExpression;
} // namespace tint::ast
namespace tint::ast {
/// Base class for a type in the system
class Type : public Castable<Type, Node> {
public:
/// Move constructor
Type(Type&&);
~Type() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
/// Type is a thin wrapper around an IdentifierExpression, to help statically disambiguate known
/// type expressions from other expressions.
struct Type {
/// The type expression
const IdentifierExpression* expr = nullptr;
protected:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
Type(ProgramID pid, NodeID nid, const Source& src);
/// Indirection operator for accessing the type's expression
/// @return #expr
const IdentifierExpression* operator->() const { return expr; }
/// Implicit conversion operator to the type's expression
/// @return #expr
operator const IdentifierExpression*() const { return expr; }
};
} // namespace tint::ast
namespace tint {
/// @param type an AST type
/// @returns the ProgramID of the given AST type.
ProgramID ProgramIDOf(ast::Type type);
} // namespace tint
#endif // SRC_TINT_AST_TYPE_H_

View File

@ -1,40 +0,0 @@
// 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/tint/ast/type_name.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::TypeName);
namespace tint::ast {
TypeName::TypeName(ProgramID pid, NodeID nid, const Source& src, const Identifier* n)
: Base(pid, nid, src), name(n) {}
TypeName::~TypeName() = default;
TypeName::TypeName(TypeName&&) = default;
std::string TypeName::FriendlyName(const SymbolTable& symbols) const {
return symbols.NameFor(name->symbol);
}
const TypeName* TypeName::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto n = ctx->Clone(name);
return ctx->dst->create<TypeName>(src, n);
}
} // namespace tint::ast

View File

@ -1,59 +0,0 @@
// 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.
#ifndef SRC_TINT_AST_TYPE_NAME_H_
#define SRC_TINT_AST_TYPE_NAME_H_
#include <string>
#include "src/tint/ast/type.h"
// Forward declarations
namespace tint::ast {
class Identifier;
} // namespace tint::ast
namespace tint::ast {
/// A named type (i.e. struct or alias)
class TypeName final : public Castable<TypeName, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param name the type name
TypeName(ProgramID pid, NodeID nid, const Source& src, const Identifier* name);
/// Move constructor
TypeName(TypeName&&);
/// Destructor
~TypeName() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const TypeName* Clone(CloneContext* ctx) const override;
/// The type name
Identifier const* const name;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_TYPE_NAME_H_

View File

@ -1,72 +0,0 @@
// Copyright 2023 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 "gtest/gtest-spi.h"
#include "src/tint/ast/test_helper.h"
namespace tint::ast {
namespace {
using namespace tint::number_suffixes; // NOLINT
using TypeNameTest = TestHelper;
TEST_F(TypeNameTest, Creation_NonTemplated) {
auto* t = ty("ty");
ASSERT_NE(t->name, nullptr);
EXPECT_EQ(t->name->symbol, Symbols().Get("ty"));
}
TEST_F(TypeNameTest, Creation_Templated) {
auto* t = ty("ty", 1_a, 2._a, false);
auto* name = As<ast::TemplatedIdentifier>(t->name);
ASSERT_NE(name, nullptr);
EXPECT_EQ(name->symbol, Symbols().Get("ty"));
ASSERT_EQ(name->arguments.Length(), 3u);
EXPECT_TRUE(name->arguments[0]->Is<ast::IntLiteralExpression>());
EXPECT_TRUE(name->arguments[1]->Is<ast::FloatLiteralExpression>());
EXPECT_TRUE(name->arguments[2]->Is<ast::BoolLiteralExpression>());
}
TEST_F(TypeNameTest, Creation_WithSource) {
auto* t = ty(Source{{20, 2}}, "ty");
ASSERT_NE(t->name, nullptr);
EXPECT_EQ(t->name->symbol, Symbols().Get("ty"));
auto src = t->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(TypeNameTest, Assert_InvalidSymbol) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.ty("");
},
"internal compiler error");
}
TEST_F(TypeNameTest, Assert_DifferentProgramID_Symbol) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.ty(b2.Sym("b2"));
},
"internal compiler error");
}
} // namespace
} // namespace tint::ast

View File

@ -24,7 +24,7 @@ Var::Var(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
type::AddressSpace address_space,
type::Access access,
const Expression* init,
@ -44,7 +44,7 @@ const char* Var::Kind() const {
const Var* Var::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type);
auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Var>(src, n, ty, declared_address_space, declared_access, init,

View File

@ -55,7 +55,7 @@ class Var final : public Castable<Var, Variable> {
NodeID nid,
const Source& source,
const Identifier* name,
const ast::Type* type,
Type type,
type::AddressSpace declared_address_space,
type::Access declared_access,
const Expression* initializer,

View File

@ -25,7 +25,7 @@ Variable::Variable(ProgramID pid,
NodeID nid,
const Source& src,
const Identifier* n,
const ast::Type* ty,
Type ty,
const Expression* init,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src), name(n), type(ty), initializer(init), attributes(std::move(attrs)) {

View File

@ -22,6 +22,7 @@
#include "src/tint/ast/binding_attribute.h"
#include "src/tint/ast/expression.h"
#include "src/tint/ast/group_attribute.h"
#include "src/tint/ast/type.h"
#include "src/tint/type/access.h"
#include "src/tint/type/address_space.h"
@ -29,7 +30,6 @@
namespace tint::ast {
class Identifier;
class LocationAttribute;
class Type;
} // namespace tint::ast
namespace tint::ast {
@ -54,7 +54,7 @@ class Variable : public Castable<Variable, Node> {
NodeID nid,
const Source& src,
const Identifier* name,
const ast::Type* type,
Type type,
const Expression* initializer,
utils::VectorRef<const Attribute*> attributes);
@ -80,7 +80,7 @@ class Variable : public Castable<Variable, Node> {
/// The declared variable type. This is null if the type is inferred, e.g.:
/// let f = 1.0;
/// var i = 1;
const ast::Type* const type;
const Type type;
/// The initializer expression or nullptr if none set
const Expression* const initializer;

View File

@ -27,10 +27,9 @@ using VariableTest = TestHelper;
TEST_F(VariableTest, Creation) {
auto* v = Var("my_var", ty.i32(), type::AddressSpace::kFunction);
EXPECT_EQ(Symbols().NameFor(v->name->symbol), "my_var");
CheckIdentifier(Symbols(), v->name, "my_var");
EXPECT_EQ(v->declared_address_space, type::AddressSpace::kFunction);
ASSERT_TRUE(v->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "i32");
CheckIdentifier(Symbols(), v->type, "i32");
EXPECT_EQ(v->source.range.begin.line, 0u);
EXPECT_EQ(v->source.range.begin.column, 0u);
EXPECT_EQ(v->source.range.end.line, 0u);
@ -41,10 +40,9 @@ TEST_F(VariableTest, CreationWithSource) {
auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}, "i",
ty.f32(), type::AddressSpace::kPrivate, utils::Empty);
EXPECT_EQ(Symbols().NameFor(v->name->symbol), "i");
CheckIdentifier(Symbols(), v->name, "i");
EXPECT_EQ(v->declared_address_space, type::AddressSpace::kPrivate);
ASSERT_TRUE(v->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "f32");
CheckIdentifier(Symbols(), v->type, "f32");
EXPECT_EQ(v->source.range.begin.line, 27u);
EXPECT_EQ(v->source.range.begin.column, 4u);
EXPECT_EQ(v->source.range.end.line, 27u);
@ -55,10 +53,9 @@ TEST_F(VariableTest, CreationEmpty) {
auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}, "a_var",
ty.i32(), type::AddressSpace::kWorkgroup, utils::Empty);
EXPECT_EQ(Symbols().NameFor(v->name->symbol), "a_var");
CheckIdentifier(Symbols(), v->name, "a_var");
EXPECT_EQ(v->declared_address_space, type::AddressSpace::kWorkgroup);
ASSERT_TRUE(v->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "i32");
CheckIdentifier(Symbols(), v->type, "i32");
EXPECT_EQ(v->source.range.begin.line, 27u);
EXPECT_EQ(v->source.range.begin.column, 4u);
EXPECT_EQ(v->source.range.end.line, 27u);

View File

@ -1,50 +0,0 @@
// Copyright 2020 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/tint/ast/vector.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Vector);
namespace tint::ast {
Vector::Vector(ProgramID pid, NodeID nid, Source const& src, const Type* subtype, uint32_t w)
: Base(pid, nid, src), type(subtype), width(w) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, subtype, program_id);
TINT_ASSERT(AST, width > 1);
TINT_ASSERT(AST, width < 5);
}
Vector::Vector(Vector&&) = default;
Vector::~Vector() = default;
std::string Vector::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "vec" << width;
if (type) {
out << "<" << type->FriendlyName(symbols) << ">";
}
return out.str();
}
const Vector* Vector::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Vector>(src, ty, width);
}
} // namespace tint::ast

View File

@ -1,61 +0,0 @@
// Copyright 2020 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.
#ifndef SRC_TINT_AST_VECTOR_H_
#define SRC_TINT_AST_VECTOR_H_
#include <string>
#include "src/tint/ast/type.h"
namespace tint::ast {
/// A vector type.
class Vector final : public Castable<Vector, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param subtype the declared type of the vector components. May be null
/// for vector initializers, where the element type will be inferred
/// from the initializer arguments
/// @param width the number of elements in the vector
Vector(ProgramID pid, NodeID nid, Source const& src, const Type* subtype, uint32_t width);
/// Move constructor
Vector(Vector&&);
~Vector() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Vector* Clone(CloneContext* ctx) const override;
/// The declared type of the vector components. May be null for vector
/// initializers, where the element type will be inferred from the initializer
/// arguments
const Type* const type;
/// The number of elements in the vector
const uint32_t width;
};
} // namespace tint::ast
#endif // SRC_TINT_AST_VECTOR_H_

View File

@ -1,37 +0,0 @@
// Copyright 2020 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/tint/ast/vector.h"
#include "src/tint/ast/test_helper.h"
namespace tint::ast {
namespace {
using AstVectorTest = TestHelper;
TEST_F(AstVectorTest, Creation) {
auto* v = create<Vector>(ty.i32(), 2u);
ASSERT_TRUE(v->type->Is<ast::TypeName>());
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "i32");
EXPECT_EQ(v->width, 2u);
}
TEST_F(AstVectorTest, FriendlyName) {
auto* v = create<Vector>(ty.f32(), 3u);
EXPECT_EQ(v->FriendlyName(Symbols()), "vec3<f32>");
}
} // namespace
} // namespace tint::ast

View File

@ -66,6 +66,10 @@ ast::FunctionList CloneContext::Clone(const ast::FunctionList& v) {
return out;
}
ast::Type CloneContext::Clone(const ast::Type& ty) {
return {Clone(ty.expr)};
}
const tint::Cloneable* CloneContext::CloneCloneable(const Cloneable* object) {
// If the input is nullptr, there's nothing to clone - just return nullptr.
if (object == nullptr) {

View File

@ -40,6 +40,7 @@ class ProgramBuilder;
namespace tint::ast {
class FunctionList;
class Node;
struct Type;
} // namespace tint::ast
namespace tint {
@ -142,6 +143,11 @@ class CloneContext {
return CheckedCast<T>(c);
}
/// Clones the ast::Type `ty` into the ProgramBuilder #dst
/// @param ty the AST type.
/// @return the cloned node
ast::Type Clone(const ast::Type& ty);
/// Clones the Source `s` into #dst
/// TODO(bclayton) - Currently this 'clone' is a shallow copy. If/when
/// `Source.File`s are owned by the Program this should make a copy of the

View File

@ -286,7 +286,7 @@ TEST_P(InspectorGetEntryPointComponentAndCompositionTest, Test) {
ComponentType component;
CompositionType composition;
std::tie(component, composition) = GetParam();
std::function<const ast::Type*()> tint_type = GetTypeFunction(component, composition);
std::function<ast::Type()> tint_type = GetTypeFunction(component, composition);
if (component == ComponentType::kF16) {
Enable(ast::Extension::kF16);
@ -1785,14 +1785,14 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MemberInfo{0, ty.i32()},
});
auto* s_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
auto s_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
AddResource("s_texture", s_texture_type, 2, 0);
AddSampler("s_var", 3, 0);
AddGlobalVariable("s_coords", ty.f32());
MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", ty.f32(),
utils::Empty);
auto* cs_depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
auto cs_depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
AddResource("cs_texture", cs_depth_texture_type, 3, 1);
AddComparisonSampler("cs_var", 3, 2);
AddGlobalVariable("cs_coords", ty.vec2<f32>());
@ -1800,14 +1800,14 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MakeComparisonSamplerReferenceBodyFunction("cs_func", "cs_texture", "cs_var", "cs_coords",
"cs_depth", ty.f32(), utils::Empty);
auto* depth_ms_texture_type = ty.depth_multisampled_texture(type::TextureDimension::k2d);
auto depth_ms_texture_type = ty.depth_multisampled_texture(type::TextureDimension::k2d);
AddResource("depth_ms_texture", depth_ms_texture_type, 3, 3);
Func("depth_ms_func", utils::Empty, ty.void_(),
utils::Vector{
Ignore("depth_ms_texture"),
});
auto* st_type =
auto st_type =
MakeStorageTextureTypes(type::TextureDimension::k2d, type::TexelFormat::kR32Uint);
AddStorageTexture("st_var", st_type, 4, 0);
MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<u32>(), utils::Empty);
@ -2586,7 +2586,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
}
TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
auto sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
@ -2621,7 +2621,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
}
TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
auto sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
@ -2646,7 +2646,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
}
TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
auto sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
@ -2663,7 +2663,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
}
TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
auto depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2684,7 +2684,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
}
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
auto depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2721,7 +2721,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
}
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
auto depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2747,7 +2747,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
}
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
auto depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2766,7 +2766,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
}
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
auto sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
@ -2798,11 +2798,11 @@ TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
}
TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
auto* sampled_texture_type =
ast::Type sampled_texture_type =
ty.sampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
ast::Type coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
AddGlobalVariable("foo_coords", coord_type);
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
@ -2847,11 +2847,11 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kFloat}));
TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam, textureSample) {
auto* sampled_texture_type =
ast::Type sampled_texture_type =
ty.sampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
ast::Type coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
AddGlobalVariable("foo_coords", coord_type);
AddGlobalVariable("foo_array_index", ty.i32());
@ -2886,10 +2886,10 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kFloat}));
TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam, textureLoad) {
auto* multisampled_texture_type =
ast::Type multisampled_texture_type =
ty.multisampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddResource("foo_texture", multisampled_texture_type, 0, 0);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.i32());
ast::Type coord_type = GetCoordsType(GetParam().type_dim, ty.i32());
AddGlobalVariable("foo_coords", coord_type);
AddGlobalVariable("foo_sample_index", ty.i32());
@ -2973,10 +2973,10 @@ TEST_P(InspectorGetStorageTextureResourceBindingsTestWithParam, Simple) {
ResourceBinding::SampledKind expected_kind;
std::tie(format, expected_format, expected_kind) = format_params;
auto* st_type = MakeStorageTextureTypes(dim, format);
ast::Type st_type = MakeStorageTextureTypes(dim, format);
AddStorageTexture("st_var", st_type, 0, 0);
const ast::Type* dim_type = nullptr;
ast::Type dim_type;
switch (dim) {
case type::TextureDimension::k1d:
dim_type = ty.u32();
@ -3074,7 +3074,7 @@ INSTANTIATE_TEST_SUITE_P(
ResourceBinding::SampledKind::kFloat))));
TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam, textureDimensions) {
auto* depth_texture_type = ty.depth_texture(GetParam().type_dim);
auto depth_texture_type = ty.depth_texture(GetParam().type_dim);
AddResource("dt", depth_texture_type, 0, 0);
Func("ep", utils::Empty, ty.void_(),
@ -3111,7 +3111,7 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::TextureDimension::kCubeArray}));
TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest, textureDimensions) {
auto* depth_ms_texture_type = ty.depth_multisampled_texture(type::TextureDimension::k2d);
auto depth_ms_texture_type = ty.depth_multisampled_texture(type::TextureDimension::k2d);
AddResource("tex", depth_ms_texture_type, 0, 0);
Func("ep", utils::Empty, ty.void_(),
@ -3135,7 +3135,7 @@ TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest, textureDimensio
}
TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) {
auto* external_texture_type = ty.external_texture();
auto external_texture_type = ty.external_texture();
AddResource("et", external_texture_type, 0, 0);
Func("ep", utils::Empty, ty.void_(),

View File

@ -64,7 +64,7 @@ const ast::Struct* InspectorBuilder::MakeInOutStruct(std::string name,
const ast::Function* InspectorBuilder::MakePlainGlobalReferenceBodyFunction(
std::string func,
std::string var,
const ast::Type* type,
ast::Type type,
utils::VectorRef<const ast::Attribute*> attributes) {
utils::Vector<const ast::Statement*, 3> stmts;
stmts.Push(Decl(Var("local_" + var, type)));
@ -82,15 +82,14 @@ bool InspectorBuilder::ContainsName(utils::VectorRef<StageVariable> vec, const s
return false;
}
std::string InspectorBuilder::StructMemberName(size_t idx, const ast::Type* type) {
return std::to_string(idx) + type->FriendlyName(Symbols());
std::string InspectorBuilder::StructMemberName(size_t idx, ast::Type type) {
return std::to_string(idx) + Symbols().NameFor(type->identifier->symbol);
}
const ast::Struct* InspectorBuilder::MakeStructType(
const std::string& name,
utils::VectorRef<const ast::Type*> member_types) {
const ast::Struct* InspectorBuilder::MakeStructType(const std::string& name,
utils::VectorRef<ast::Type> member_types) {
utils::Vector<const ast::StructMember*, 8> members;
for (auto* type : member_types) {
for (auto type : member_types) {
members.Push(MakeStructMember(members.Length(), type, {}));
}
return MakeStructTypeFromMembers(name, std::move(members));
@ -104,37 +103,37 @@ const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(
const ast::StructMember* InspectorBuilder::MakeStructMember(
size_t index,
const ast::Type* type,
ast::Type type,
utils::VectorRef<const ast::Attribute*> attributes) {
return Member(StructMemberName(index, type), type, std::move(attributes));
}
const ast::Struct* InspectorBuilder::MakeUniformBufferType(
const std::string& name,
utils::VectorRef<const ast::Type*> member_types) {
utils::VectorRef<ast::Type> member_types) {
return MakeStructType(name, member_types);
}
std::function<const ast::TypeName*()> InspectorBuilder::MakeStorageBufferTypes(
std::function<ast::Type()> InspectorBuilder::MakeStorageBufferTypes(
const std::string& name,
utils::VectorRef<const ast::Type*> member_types) {
utils::VectorRef<ast::Type> member_types) {
MakeStructType(name, member_types);
return [this, name] { return ty(name); };
}
void InspectorBuilder::AddUniformBuffer(const std::string& name,
const ast::Type* type,
ast::Type type,
uint32_t group,
uint32_t binding) {
GlobalVar(name, type, type::AddressSpace::kUniform, Binding(AInt(binding)), Group(AInt(group)));
}
void InspectorBuilder::AddWorkgroupStorage(const std::string& name, const ast::Type* type) {
void InspectorBuilder::AddWorkgroupStorage(const std::string& name, ast::Type type) {
GlobalVar(name, type, type::AddressSpace::kWorkgroup);
}
void InspectorBuilder::AddStorageBuffer(const std::string& name,
const ast::Type* type,
ast::Type type,
type::Access access,
uint32_t group,
uint32_t binding) {
@ -145,11 +144,11 @@ void InspectorBuilder::AddStorageBuffer(const std::string& name,
void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
std::string func_name,
std::string struct_name,
utils::VectorRef<std::tuple<size_t, const ast::Type*>> members) {
utils::VectorRef<std::tuple<size_t, ast::Type>> members) {
utils::Vector<const ast::Statement*, 8> stmts;
for (auto member : members) {
size_t member_idx;
const ast::Type* member_type;
ast::Type member_type;
std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type);
@ -158,7 +157,7 @@ void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
for (auto member : members) {
size_t member_idx;
const ast::Type* member_type;
ast::Type member_type;
std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type);
@ -183,13 +182,13 @@ void InspectorBuilder::AddComparisonSampler(const std::string& name,
}
void InspectorBuilder::AddResource(const std::string& name,
const ast::Type* type,
ast::Type type,
uint32_t group,
uint32_t binding) {
GlobalVar(name, type, Binding(AInt(binding)), Group(AInt(group)));
}
void InspectorBuilder::AddGlobalVariable(const std::string& name, const ast::Type* type) {
void InspectorBuilder::AddGlobalVariable(const std::string& name, ast::Type type) {
GlobalVar(name, type, type::AddressSpace::kPrivate);
}
@ -198,7 +197,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
const std::string& texture_name,
const std::string& sampler_name,
const std::string& coords_name,
const ast::Type* base_type,
ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result";
@ -216,7 +215,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
const std::string& sampler_name,
const std::string& coords_name,
const std::string& array_index,
const ast::Type* base_type,
ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result";
@ -235,7 +234,7 @@ const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunctio
const std::string& sampler_name,
const std::string& coords_name,
const std::string& depth_name,
const ast::Type* base_type,
ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result";
@ -248,7 +247,7 @@ const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunctio
return Func(func_name, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
const ast::Type* InspectorBuilder::GetBaseType(ResourceBinding::SampledKind sampled_kind) {
ast::Type InspectorBuilder::GetBaseType(ResourceBinding::SampledKind sampled_kind) {
switch (sampled_kind) {
case ResourceBinding::SampledKind::kFloat:
return ty.f32();
@ -257,35 +256,34 @@ const ast::Type* InspectorBuilder::GetBaseType(ResourceBinding::SampledKind samp
case ResourceBinding::SampledKind::kUInt:
return ty.u32();
default:
return nullptr;
return ast::Type{};
}
}
const ast::Type* InspectorBuilder::GetCoordsType(type::TextureDimension dim,
const ast::Type* scalar) {
ast::Type InspectorBuilder::GetCoordsType(type::TextureDimension dim, ast::Type scalar) {
switch (dim) {
case type::TextureDimension::k1d:
return scalar;
case type::TextureDimension::k2d:
case type::TextureDimension::k2dArray:
return create<ast::Vector>(scalar, 2u);
return ty.vec2(scalar);
case type::TextureDimension::k3d:
case type::TextureDimension::kCube:
case type::TextureDimension::kCubeArray:
return create<ast::Vector>(scalar, 3u);
return ty.vec3(scalar);
default:
[=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
}
return nullptr;
return ast::Type{};
}
const ast::Type* InspectorBuilder::MakeStorageTextureTypes(type::TextureDimension dim,
ast::Type InspectorBuilder::MakeStorageTextureTypes(type::TextureDimension dim,
type::TexelFormat format) {
return ty.storage_texture(dim, format, type::Access::kWrite);
}
void InspectorBuilder::AddStorageTexture(const std::string& name,
const ast::Type* type,
ast::Type type,
uint32_t group,
uint32_t binding) {
GlobalVar(name, type, Binding(AInt(binding)), Group(AInt(group)));
@ -294,7 +292,7 @@ void InspectorBuilder::AddStorageTexture(const std::string& name,
const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
const std::string& func_name,
const std::string& st_name,
const ast::Type* dim_type,
ast::Type dim_type,
utils::VectorRef<const ast::Attribute*> attributes) {
utils::Vector stmts{
Decl(Var("dim", dim_type)),
@ -305,24 +303,24 @@ const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
return Func(func_name, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(ComponentType component,
std::function<ast::Type()> InspectorBuilder::GetTypeFunction(ComponentType component,
CompositionType composition) {
std::function<const ast::Type*()> func;
std::function<ast::Type()> func;
switch (component) {
case ComponentType::kF32:
func = [this]() -> const ast::Type* { return ty.f32(); };
func = [this]() { return ty.f32(); };
break;
case ComponentType::kI32:
func = [this]() -> const ast::Type* { return ty.i32(); };
func = [this]() { return ty.i32(); };
break;
case ComponentType::kU32:
func = [this]() -> const ast::Type* { return ty.u32(); };
func = [this]() { return ty.u32(); };
break;
case ComponentType::kF16:
func = [this]() -> const ast::Type* { return ty.f16(); };
func = [this]() { return ty.f16(); };
break;
case ComponentType::kUnknown:
return []() -> const ast::Type* { return nullptr; };
return []() { return ast::Type{}; };
}
uint32_t n;
@ -339,10 +337,10 @@ std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(ComponentTyp
n = 4;
break;
default:
return []() -> ast::Type* { return nullptr; };
return []() { return ast::Type{}; };
}
return [this, func, n]() -> const ast::Type* { return ty.vec(func(), n); };
return [this, func, n]() { return ty.vec(func(), n); };
}
Inspector& InspectorBuilder::Build() {

View File

@ -107,7 +107,7 @@ class InspectorBuilder : public ProgramBuilder {
const ast::Function* MakePlainGlobalReferenceBodyFunction(
std::string func,
std::string var,
const ast::Type* type,
ast::Type type,
utils::VectorRef<const ast::Attribute*> attributes);
/// @param vec Vector of StageVariable to be searched
@ -119,14 +119,14 @@ class InspectorBuilder : public ProgramBuilder {
/// @param idx index of member
/// @param type type of member
/// @returns a string for the member
std::string StructMemberName(size_t idx, const ast::Type* type);
std::string StructMemberName(size_t idx, ast::Type type);
/// Generates a struct type
/// @param name name for the type
/// @param member_types a vector of member types
/// @returns a struct type
const ast::Struct* MakeStructType(const std::string& name,
utils::VectorRef<const ast::Type*> member_types);
utils::VectorRef<ast::Type> member_types);
/// Generates a struct type from a list of member nodes.
/// @param name name for the struct type
@ -142,7 +142,7 @@ class InspectorBuilder : public ProgramBuilder {
/// @param attributes a list of attributes to apply to the member field
/// @returns a struct member
const ast::StructMember* MakeStructMember(size_t index,
const ast::Type* type,
ast::Type type,
utils::VectorRef<const ast::Attribute*> attributes);
/// Generates types appropriate for using in an uniform buffer
@ -150,15 +150,14 @@ class InspectorBuilder : public ProgramBuilder {
/// @param member_types a vector of member types
/// @returns a struct type that has the layout for an uniform buffer.
const ast::Struct* MakeUniformBufferType(const std::string& name,
utils::VectorRef<const ast::Type*> member_types);
utils::VectorRef<ast::Type> member_types);
/// Generates types appropriate for using in a storage buffer
/// @param name name for the type
/// @param member_types a vector of member types
/// @returns a function that returns the created structure.
std::function<const ast::TypeName*()> MakeStorageBufferTypes(
const std::string& name,
utils::VectorRef<const ast::Type*> member_types);
std::function<ast::Type()> MakeStorageBufferTypes(const std::string& name,
utils::VectorRef<ast::Type> member_types);
/// Adds an uniform buffer variable to the program
/// @param name the name of the variable
@ -166,14 +165,14 @@ class InspectorBuilder : public ProgramBuilder {
/// @param group the binding/group/ to use for the uniform buffer
/// @param binding the binding number to use for the uniform buffer
void AddUniformBuffer(const std::string& name,
const ast::Type* type,
ast::Type type,
uint32_t group,
uint32_t binding);
/// Adds a workgroup storage variable to the program
/// @param name the name of the variable
/// @param type the type of the variable
void AddWorkgroupStorage(const std::string& name, const ast::Type* type);
void AddWorkgroupStorage(const std::string& name, ast::Type type);
/// Adds a storage buffer variable to the program
/// @param name the name of the variable
@ -182,13 +181,13 @@ class InspectorBuilder : public ProgramBuilder {
/// @param group the binding/group to use for the storage buffer
/// @param binding the binding number to use for the storage buffer
void AddStorageBuffer(const std::string& name,
const ast::Type* type,
ast::Type type,
type::Access access,
uint32_t group,
uint32_t binding);
/// MemberInfo is a tuple of member index and type.
using MemberInfo = std::tuple<size_t, const ast::Type*>;
using MemberInfo = std::tuple<size_t, ast::Type>;
/// Generates a function that references a specific struct variable
/// @param func_name name of the function created
@ -215,15 +214,12 @@ class InspectorBuilder : public ProgramBuilder {
/// @param type the type to use
/// @param group the binding/group to use for the resource
/// @param binding the binding number to use for the resource
void AddResource(const std::string& name,
const ast::Type* type,
uint32_t group,
uint32_t binding);
void AddResource(const std::string& name, ast::Type type, uint32_t group, uint32_t binding);
/// Add a module scope private variable to the progames
/// @param name the name of the variable
/// @param type the type to use
void AddGlobalVariable(const std::string& name, const ast::Type* type);
void AddGlobalVariable(const std::string& name, ast::Type type);
/// Generates a function that references a specific sampler variable
/// @param func_name name of the function created
@ -238,7 +234,7 @@ class InspectorBuilder : public ProgramBuilder {
const std::string& texture_name,
const std::string& sampler_name,
const std::string& coords_name,
const ast::Type* base_type,
ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes);
/// Generates a function that references a specific sampler variable
@ -256,7 +252,7 @@ class InspectorBuilder : public ProgramBuilder {
const std::string& sampler_name,
const std::string& coords_name,
const std::string& array_index,
const ast::Type* base_type,
ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes);
/// Generates a function that references a specific comparison sampler
@ -275,26 +271,26 @@ class InspectorBuilder : public ProgramBuilder {
const std::string& sampler_name,
const std::string& coords_name,
const std::string& depth_name,
const ast::Type* base_type,
ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes);
/// Gets an appropriate type for the data in a given texture type.
/// @param sampled_kind type of in the texture
/// @returns a pointer to a type appropriate for the coord param
const ast::Type* GetBaseType(ResourceBinding::SampledKind sampled_kind);
ast::Type GetBaseType(ResourceBinding::SampledKind sampled_kind);
/// Gets an appropriate type for the coords parameter depending the the
/// dimensionality of the texture being sampled.
/// @param dim dimensionality of the texture being sampled
/// @param scalar the scalar type
/// @returns a pointer to a type appropriate for the coord param
const ast::Type* GetCoordsType(type::TextureDimension dim, const ast::Type* scalar);
ast::Type GetCoordsType(type::TextureDimension dim, ast::Type scalar);
/// Generates appropriate types for a Read-Only StorageTexture
/// @param dim the texture dimension of the storage texture
/// @param format the texel format of the storage texture
/// @returns the storage texture type
const ast::Type* MakeStorageTextureTypes(type::TextureDimension dim, type::TexelFormat format);
ast::Type MakeStorageTextureTypes(type::TextureDimension dim, type::TexelFormat format);
/// Adds a storage texture variable to the program
/// @param name the name of the variable
@ -302,7 +298,7 @@ class InspectorBuilder : public ProgramBuilder {
/// @param group the binding/group to use for the sampled texture
/// @param binding the binding57 number to use for the sampled texture
void AddStorageTexture(const std::string& name,
const ast::Type* type,
ast::Type type,
uint32_t group,
uint32_t binding);
@ -315,7 +311,7 @@ class InspectorBuilder : public ProgramBuilder {
const ast::Function* MakeStorageTextureBodyFunction(
const std::string& func_name,
const std::string& st_name,
const ast::Type* dim_type,
ast::Type dim_type,
utils::VectorRef<const ast::Attribute*> attributes);
/// Get a generator function that returns a type appropriate for a stage
@ -323,7 +319,7 @@ class InspectorBuilder : public ProgramBuilder {
/// @param component component type of the stage variable
/// @param composition composition type of the stage variable
/// @returns a generator function for the stage variable's type.
std::function<const ast::Type*()> GetTypeFunction(ComponentType component,
std::function<ast::Type()> GetTypeFunction(ComponentType component,
CompositionType composition);
/// Build the Program given all of the previous methods called and return an

View File

@ -136,6 +136,15 @@ enum builtin_type {
i32
u32
// https://www.w3.org/TR/WGSL/#matrix-types
mat2x2
mat2x3
mat2x4
mat3x2
mat3x3
mat3x4
mat4x2
mat4x3
mat4x4
mat2x2f
mat2x2h
mat2x3f
@ -155,6 +164,9 @@ enum builtin_type {
mat4x4f
mat4x4h
// https://www.w3.org/TR/WGSL/#vector-types
vec2
vec3
vec4
vec2f
vec2h
vec2i
@ -167,6 +179,12 @@ enum builtin_type {
vec4h
vec4i
vec4u
// https://www.w3.org/TR/WGSL/#array-types
array
// https://www.w3.org/TR/WGSL/#atomic-types
atomic
// https://www.w3.org/TR/WGSL/#ref-ptr-types
ptr
// https://www.w3.org/TR/WGSL/#sampler-type
sampler
sampler_comparison
@ -176,6 +194,15 @@ enum builtin_type {
texture_depth_cube
texture_depth_cube_array
texture_depth_multisampled_2d
// https://www.w3.org/TR/WGSL/#sampled-texture-type
texture_1d
texture_2d
texture_2d_array
texture_3d
texture_cube
texture_cube_array
// https://www.w3.org/TR/WGSL/#multisampled-texture-type
texture_multisampled_2d
// https://www.w3.org/TR/WGSL/#texture-storage
texture_storage_1d
texture_storage_2d

View File

@ -19,6 +19,7 @@
#include <unordered_map>
#include <utility>
#include "src/tint/ast/type.h"
#include "src/tint/constant/clone_context.h"
#include "src/tint/diagnostic/diagnostic.h"
#include "src/tint/ir/builder.h"
@ -49,7 +50,6 @@ class Node;
class ReturnStatement;
class Statement;
class SwitchStatement;
class Type;
class WhileStatement;
class Variable;
} // namespace tint::ast

View File

@ -18,6 +18,7 @@
#include "src/tint/demangler.h"
#include "src/tint/resolver/resolver.h"
#include "src/tint/sem/type_expression.h"
#include "src/tint/sem/value_expression.h"
namespace tint {
@ -118,21 +119,24 @@ bool Program::IsValid() const {
}
const type::Type* Program::TypeOf(const ast::Expression* expr) const {
auto* sem = Sem().GetVal(expr);
return sem ? sem->Type() : nullptr;
return tint::Switch(
Sem().Get(expr), //
[](const sem::ValueExpression* ty_expr) { return ty_expr->Type(); },
[](const sem::TypeExpression* ty_expr) { return ty_expr->Type(); });
}
const type::Type* Program::TypeOf(const ast::Type* type) const {
return Sem().Get(type);
const type::Type* Program::TypeOf(const ast::Variable* var) const {
auto* sem = Sem().Get(var);
return sem ? sem->Type() : nullptr;
}
const type::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const {
return Sem().Get(type_decl);
}
std::string Program::FriendlyName(const ast::Type* type) const {
std::string Program::FriendlyName(ast::Type type) const {
TINT_ASSERT_PROGRAM_IDS_EQUAL(Program, type, ID());
return type ? type->FriendlyName(Symbols()) : "<null>";
return type ? Symbols().NameFor(type->identifier->symbol) : "<null>";
}
std::string Program::FriendlyName(const type::Type* type) const {

View File

@ -138,11 +138,11 @@ class Program {
/// expression has no resolved type.
const type::Type* TypeOf(const ast::Expression* expr) const;
/// Helper for returning the resolved semantic type of the AST type `type`.
/// @param type the AST type
/// @return the resolved semantic type for the type, or nullptr if the type
/// has no resolved type.
const type::Type* TypeOf(const ast::Type* type) const;
/// Helper for returning the resolved semantic type of the variable `var`.
/// @param var the AST variable
/// @return the resolved semantic type for the variable, or nullptr if the
/// variable has no resolved type.
const type::Type* TypeOf(const ast::Variable* var) const;
/// Helper for returning the resolved semantic type of the AST type
/// declaration `type_decl`.
@ -152,13 +152,11 @@ class Program {
const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
/// @param type a type
/// @returns the name for `type` that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const ast::Type* type) const;
/// @returns the name for `type` that closely resembles how it would be declared in WGSL.
std::string FriendlyName(ast::Type type) const;
/// @param type a type
/// @returns the name for `type` that closely resembles how it would be
/// declared in WGSL.
/// @returns the name for `type` that closely resembles how it would be declared in WGSL.
std::string FriendlyName(const type::Type* type) const;
/// Overload of FriendlyName, which removes an ambiguity when passing nullptr.

View File

@ -19,6 +19,7 @@
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/debug.h"
#include "src/tint/demangler.h"
#include "src/tint/sem/type_expression.h"
#include "src/tint/sem/value_expression.h"
#include "src/tint/sem/variable.h"
#include "src/tint/utils/compiler_macros.h"
@ -97,8 +98,10 @@ void ProgramBuilder::AssertNotMoved() const {
}
const type::Type* ProgramBuilder::TypeOf(const ast::Expression* expr) const {
auto* sem = Sem().GetVal(expr);
return sem ? sem->Type() : nullptr;
return tint::Switch(
Sem().Get(expr), //
[](const sem::ValueExpression* e) { return e->Type(); },
[](const sem::TypeExpression* e) { return e->Type(); });
}
const type::Type* ProgramBuilder::TypeOf(const ast::Variable* var) const {
@ -106,17 +109,13 @@ const type::Type* ProgramBuilder::TypeOf(const ast::Variable* var) const {
return sem ? sem->Type() : nullptr;
}
const type::Type* ProgramBuilder::TypeOf(const ast::Type* type) const {
return Sem().Get(type);
}
const type::Type* ProgramBuilder::TypeOf(const ast::TypeDecl* type_decl) const {
return Sem().Get(type_decl);
}
std::string ProgramBuilder::FriendlyName(const ast::Type* type) const {
std::string ProgramBuilder::FriendlyName(ast::Type type) const {
TINT_ASSERT_PROGRAM_IDS_EQUAL(ProgramBuilder, type, ID());
return type ? type->FriendlyName(Symbols()) : "<null>";
return type.expr ? Symbols().NameFor(type->identifier->symbol) : "<null>";
}
std::string ProgramBuilder::FriendlyName(const type::Type* type) const {
@ -127,10 +126,6 @@ std::string ProgramBuilder::FriendlyName(std::nullptr_t) const {
return "<null>";
}
const ast::TypeName* ProgramBuilder::TypesBuilder::Of(const ast::TypeDecl* decl) const {
return (*this)(decl->name->symbol);
}
ProgramBuilder::TypesBuilder::TypesBuilder(ProgramBuilder* pb) : builder(pb) {}
const ast::Statement* ProgramBuilder::WrapInStatement(const ast::Expression* expr) {

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ TEST_F(ProgramBuilderTest, IDsAreUnique) {
TEST_F(ProgramBuilderTest, WrapDoesntAffectInner) {
Program inner([] {
ProgramBuilder builder;
auto* ty = builder.ty.f32();
auto ty = builder.ty.f32();
builder.Func("a", {}, ty, {}, {});
return builder;
}());
@ -54,7 +54,7 @@ TEST_F(ProgramBuilderTest, WrapDoesntAffectInner) {
EXPECT_FALSE(inner.Symbols().Get("b").IsValid());
EXPECT_FALSE(outer.Symbols().Get("b").IsValid());
auto* ty = outer.ty.f32();
auto ty = outer.ty.f32();
outer.Func("b", {}, ty, {}, {});
ASSERT_EQ(inner.AST().Functions().Length(), 1u);

View File

@ -1259,7 +1259,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
FunctionDeclaration decl;
decl.source = source;
decl.name = ep_info_->name;
const ast::Type* return_type = nullptr; // Populated below.
ast::Type return_type; // Populated below.
// Pipeline inputs become parameters to the wrapper function, and
// their values are saved into the corresponding private variables that
@ -3825,7 +3825,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (unary_builtin_name != nullptr) {
ExpressionList params;
params.Push(MakeOperand(inst, 0).expr);
return {ast_type, builder_.Call(Source{}, unary_builtin_name, std::move(params))};
return {ast_type, builder_.Call(unary_builtin_name, std::move(params))};
}
const auto builtin = GetBuiltin(op);
@ -3906,7 +3906,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
}
operands.Push(operand.expr);
}
return {ast_type, builder_.Call(Source{}, ast_type->Build(builder_), std::move(operands))};
return {ast_type, builder_.Call(ast_type->Build(builder_), std::move(operands))};
}
if (op == spv::Op::OpCompositeExtract) {
@ -3971,7 +3971,7 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(const spvtools::opt::Inst
auto e1 = MakeOperand(inst, 2);
auto e2 = ToSignedIfUnsigned(MakeOperand(inst, 3));
return {e1.type, builder_.Call(Source{}, "ldexp", utils::Vector{e1.expr, e2.expr})};
return {e1.type, builder_.Call("ldexp", utils::Vector{e1.expr, e2.expr})};
}
auto* result_type = parser_impl_.ConvertType(inst.type_id());
@ -3983,7 +3983,7 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(const spvtools::opt::Inst
case GLSLstd450Determinant: {
auto m = MakeOperand(inst, 2);
TINT_ASSERT(Reader, m.type->Is<Matrix>());
return {ty_.F32(), builder_.Call(Source{}, "determinant", m.expr)};
return {ty_.F32(), builder_.Call("determinant", m.expr)};
}
case GLSLstd450Normalize:
@ -4049,7 +4049,7 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(const spvtools::opt::Inst
return {
f32,
builder_.MemberAccessor(
builder_.Call(Source{}, "refract",
builder_.Call("refract",
utils::Vector{
builder_.vec2<tint::f32>(incident.expr, 0_f),
builder_.vec2<tint::f32>(normal.expr, 0_f),
@ -4084,7 +4084,7 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(const spvtools::opt::Inst
}
operands.Push(operand.expr);
}
auto* call = builder_.Call(Source{}, name, std::move(operands));
auto* call = builder_.Call(name, std::move(operands));
TypedExpression call_expr{result_type, call};
return parser_impl_.RectifyForcedResultType(call_expr, inst, first_operand_type);
}
@ -5199,7 +5199,7 @@ bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
if (failed()) {
return false;
}
auto* call_expr = create<ast::CallExpression>(Source{}, function, std::move(args));
auto* call_expr = builder_.Call(function, std::move(args));
auto* result_type = parser_impl_.ConvertType(inst.type_id());
if (!result_type) {
return Fail() << "internal error: no mapped type result of call: " << inst.PrettyPrint();
@ -5270,7 +5270,7 @@ TypedExpression FunctionEmitter::MakeBuiltinCall(const spvtools::opt::Instructio
}
params.Push(operand.expr);
}
auto* call_expr = create<ast::CallExpression>(Source{}, ident, std::move(params));
auto* call_expr = builder_.Call(ident, std::move(params));
auto* result_type = parser_impl_.ConvertType(inst.type_id());
if (!result_type) {
Fail() << "internal error: no mapped type result of call: " << inst.PrettyPrint();
@ -5298,10 +5298,7 @@ TypedExpression FunctionEmitter::MakeSimpleSelect(const spvtools::opt::Instructi
params.Push(true_value.expr);
// The condition goes last.
params.Push(condition.expr);
return {op_ty, create<ast::CallExpression>(
Source{},
create<ast::Identifier>(Source{}, builder_.Symbols().Register("select")),
std::move(params))};
return {op_ty, builder_.Call("select", std::move(params))};
}
return {};
}
@ -5604,7 +5601,7 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
return false;
}
auto* call_expr = builder_.Call(Source{}, builtin_name, std::move(args));
auto* call_expr = builder_.Call(builtin_name, std::move(args));
if (inst.type_id() != 0) {
// It returns a value.
@ -5697,7 +5694,7 @@ bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
dims_args.Push(MakeOperand(inst, 1).expr);
}
const ast::Expression* dims_call =
builder_.Call(Source{}, "textureDimensions", std::move(dims_args));
builder_.Call("textureDimensions", std::move(dims_args));
auto dims = texture_type->dims;
if ((dims == type::TextureDimension::kCube) ||
(dims == type::TextureDimension::kCubeArray)) {
@ -5706,9 +5703,8 @@ bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
create<ast::MemberAccessorExpression>(Source{}, dims_call, PrefixSwizzle(2));
}
exprs.Push(dims_call);
if (ast::IsTextureArray(dims)) {
auto num_layers =
builder_.Call(Source{}, "textureNumLayers", GetImageExpression(inst));
if (type::IsTextureArray(dims)) {
auto num_layers = builder_.Call("textureNumLayers", GetImageExpression(inst));
exprs.Push(num_layers);
}
auto* result_type = parser_impl_.ConvertType(inst.type_id());
@ -5720,7 +5716,7 @@ bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
// vector initializer - otherwise, just emit the single expression to omit an
// unnecessary cast.
(exprs.Length() > 1)
? builder_.Call(Source{}, unsigned_type->Build(builder_), std::move(exprs))
? builder_.Call(unsigned_type->Build(builder_), std::move(exprs))
: exprs[0],
};
@ -5735,15 +5731,13 @@ bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
case spv::Op::OpImageQuerySamples: {
const auto* name =
(op == spv::Op::OpImageQueryLevels) ? "textureNumLevels" : "textureNumSamples";
const ast::Expression* ast_expr =
builder_.Call(Source{}, name, GetImageExpression(inst));
const ast::Expression* ast_expr = builder_.Call(name, GetImageExpression(inst));
auto* result_type = parser_impl_.ConvertType(inst.type_id());
// The SPIR-V result type must be integer scalar.
// The WGSL bulitin returns u32.
// If they aren't the same then convert the result.
if (!result_type->Is<U32>()) {
ast_expr =
builder_.Call(Source{}, result_type->Build(builder_), utils::Vector{ast_expr});
ast_expr = builder_.Call(result_type->Build(builder_), utils::Vector{ast_expr});
}
TypedExpression expr{result_type, ast_expr};
return EmitConstDefOrWriteToHoistedVar(inst, expr);
@ -5768,7 +5762,7 @@ bool FunctionEmitter::EmitAtomicOp(const spvtools::opt::Instruction& inst) {
}
// Function return type
const ast::Type* ret_type = nullptr;
ast::Type ret_type;
if (inst.type_id() != 0) {
ret_type = parser_impl_.ConvertType(inst.type_id())->Build(builder_);
} else {
@ -5787,7 +5781,7 @@ bool FunctionEmitter::EmitAtomicOp(const spvtools::opt::Instruction& inst) {
});
// Emit call to stub, will be replaced with call to atomic builtin by transform::SpirvAtomic
auto* call = builder_.Call(Source{}, stub->name->symbol, std::move(exprs));
auto* call = builder_.Call(stub->name->symbol, std::move(exprs));
if (inst.type_id() != 0) {
auto* result_type = parser_impl_.ConvertType(inst.type_id());
TypedExpression expr{result_type, call};
@ -5897,8 +5891,8 @@ FunctionEmitter::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageA
}
type::TextureDimension dim = texture_type->dims;
// Number of regular coordinates.
uint32_t num_axes = static_cast<uint32_t>(ast::NumCoordinateAxes(dim));
bool is_arrayed = ast::IsTextureArray(dim);
uint32_t num_axes = static_cast<uint32_t>(type::NumCoordinateAxes(dim));
bool is_arrayed = type::IsTextureArray(dim);
if ((num_axes == 0) || (num_axes > 3)) {
Fail() << "unsupported image dimensionality for " << texture_type->TypeInfo().name
<< " prompted by " << inst.PrettyPrint();
@ -6052,7 +6046,7 @@ const ast::Expression* FunctionEmitter::ConvertTexelForStorage(
for (auto i = src_count; i < dest_count; i++) {
exprs.Push(parser_impl_.MakeNullExpression(component_type).expr);
}
texel.expr = builder_.Call(Source{}, src_type->Build(builder_), std::move(exprs));
texel.expr = builder_.Call(src_type->Build(builder_), std::move(exprs));
}
return texel.expr;
@ -6062,7 +6056,7 @@ TypedExpression FunctionEmitter::ToI32(TypedExpression value) {
if (!value || value.type->Is<I32>()) {
return value;
}
return {ty_.I32(), builder_.Call(Source{}, builder_.ty.i32(), utils::Vector{value.expr})};
return {ty_.I32(), builder_.Call(builder_.ty.i32(), utils::Vector{value.expr})};
}
TypedExpression FunctionEmitter::ToSignedIfUnsigned(TypedExpression value) {
@ -6103,7 +6097,7 @@ TypedExpression FunctionEmitter::MakeArrayLength(const spvtools::opt::Instructio
auto* member_access = builder_.MemberAccessor(Source{}, member_expr.expr, field_name);
// Generate the builtin function call.
auto* call_expr = builder_.Call(Source{}, "arrayLength", builder_.AddressOf(member_access));
auto* call_expr = builder_.Call("arrayLength", builder_.AddressOf(member_access));
return {parser_impl_.ConvertType(inst.type_id()), call_expr};
}
@ -6142,11 +6136,9 @@ TypedExpression FunctionEmitter::MakeOuterProduct(const spvtools::opt::Instructi
row_factor, column_factor);
result_row.Push(elem);
}
result_columns.Push(
builder_.Call(Source{}, col_ty->Build(builder_), std::move(result_row)));
result_columns.Push(builder_.Call(col_ty->Build(builder_), std::move(result_row)));
}
return {result_ty,
builder_.Call(Source{}, result_ty->Build(builder_), std::move(result_columns))};
return {result_ty, builder_.Call(result_ty->Build(builder_), std::move(result_columns))};
}
bool FunctionEmitter::MakeVectorInsertDynamic(const spvtools::opt::Instruction& inst) {

View File

@ -24,7 +24,6 @@
#include "src/tint/ast/disable_validation_attribute.h"
#include "src/tint/ast/id_attribute.h"
#include "src/tint/ast/interpolate_attribute.h"
#include "src/tint/ast/type_name.h"
#include "src/tint/ast/unary_op_expression.h"
#include "src/tint/reader/spirv/function.h"
#include "src/tint/type/depth_texture.h"

View File

@ -546,7 +546,7 @@ TEST_F(SpvParserTest, ConvertType_StructTwoMembers) {
ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->Is<Struct>());
auto* str = type->Build(p->builder());
auto str = type->Build(p->builder());
Program program = p->program();
EXPECT_EQ(test::ToString(program, str), "S");
}
@ -564,7 +564,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->Is<Struct>());
auto* str = type->Build(p->builder());
auto str = type->Build(p->builder());
Program program = p->program();
EXPECT_EQ(test::ToString(program, str), "S");
}
@ -586,7 +586,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->Is<Struct>());
auto* str = type->Build(p->builder());
auto str = type->Build(p->builder());
Program program = p->program();
EXPECT_EQ(test::ToString(program, str), "S");
}

View File

@ -66,13 +66,6 @@ std::string ToString(const Program& program, const ast::Node* node) {
}
return writer.result();
},
[&](const ast::Type* ty) {
std::stringstream out;
if (!writer.EmitType(out, ty)) {
return "WGSL writer error: " + writer.error();
}
return out.str();
},
[&](const ast::Identifier* ident) { return program.Symbols().NameFor(ident->symbol); },
[&](Default) {
return "<unhandled AST node type " + std::string(node->TypeInfo().name) + ">";

View File

@ -149,23 +149,23 @@ static bool operator==(const StorageTexture& a, const StorageTexture& b) {
}
//! @endcond
const ast::Type* Void::Build(ProgramBuilder& b) const {
ast::Type Void::Build(ProgramBuilder& b) const {
return b.ty.void_();
}
const ast::Type* Bool::Build(ProgramBuilder& b) const {
ast::Type Bool::Build(ProgramBuilder& b) const {
return b.ty.bool_();
}
const ast::Type* U32::Build(ProgramBuilder& b) const {
ast::Type U32::Build(ProgramBuilder& b) const {
return b.ty.u32();
}
const ast::Type* F32::Build(ProgramBuilder& b) const {
ast::Type F32::Build(ProgramBuilder& b) const {
return b.ty.f32();
}
const ast::Type* I32::Build(ProgramBuilder& b) const {
ast::Type I32::Build(ProgramBuilder& b) const {
return b.ty.i32();
}
@ -179,7 +179,7 @@ Pointer::Pointer(const Type* t, type::AddressSpace s, type::Access a)
: type(t), address_space(s), access(a) {}
Pointer::Pointer(const Pointer&) = default;
const ast::Type* Pointer::Build(ProgramBuilder& b) const {
ast::Type Pointer::Build(ProgramBuilder& b) const {
auto store_type = type->Build(b);
if (!store_type) {
// TODO(crbug.com/tint/1838): We should not be constructing pointers with 'void' store
@ -193,28 +193,28 @@ Reference::Reference(const Type* t, type::AddressSpace s, type::Access a)
: type(t), address_space(s), access(a) {}
Reference::Reference(const Reference&) = default;
const ast::Type* Reference::Build(ProgramBuilder& b) const {
ast::Type Reference::Build(ProgramBuilder& b) const {
return type->Build(b);
}
Vector::Vector(const Type* t, uint32_t s) : type(t), size(s) {}
Vector::Vector(const Vector&) = default;
const ast::Type* Vector::Build(ProgramBuilder& b) const {
ast::Type Vector::Build(ProgramBuilder& b) const {
return b.ty.vec(type->Build(b), size);
}
Matrix::Matrix(const Type* t, uint32_t c, uint32_t r) : type(t), columns(c), rows(r) {}
Matrix::Matrix(const Matrix&) = default;
const ast::Type* Matrix::Build(ProgramBuilder& b) const {
ast::Type Matrix::Build(ProgramBuilder& b) const {
return b.ty.mat(type->Build(b), columns, rows);
}
Array::Array(const Type* t, uint32_t sz, uint32_t st) : type(t), size(sz), stride(st) {}
Array::Array(const Array&) = default;
const ast::Type* Array::Build(ProgramBuilder& b) const {
ast::Type Array::Build(ProgramBuilder& b) const {
if (size > 0) {
if (stride > 0) {
return b.ty.array(type->Build(b), u32(size), utils::Vector{b.Stride(stride)});
@ -223,9 +223,9 @@ const ast::Type* Array::Build(ProgramBuilder& b) const {
}
} else {
if (stride > 0) {
return b.ty.array(type->Build(b), nullptr, utils::Vector{b.Stride(stride)});
return b.ty.array(type->Build(b), utils::Vector{b.Stride(stride)});
} else {
return b.ty.array(type->Build(b), nullptr);
return b.ty.array(type->Build(b));
}
}
}
@ -233,7 +233,7 @@ const ast::Type* Array::Build(ProgramBuilder& b) const {
Sampler::Sampler(type::SamplerKind k) : kind(k) {}
Sampler::Sampler(const Sampler&) = default;
const ast::Type* Sampler::Build(ProgramBuilder& b) const {
ast::Type Sampler::Build(ProgramBuilder& b) const {
return b.ty.sampler(kind);
}
@ -243,14 +243,14 @@ Texture::Texture(const Texture&) = default;
DepthTexture::DepthTexture(type::TextureDimension d) : Base(d) {}
DepthTexture::DepthTexture(const DepthTexture&) = default;
const ast::Type* DepthTexture::Build(ProgramBuilder& b) const {
ast::Type DepthTexture::Build(ProgramBuilder& b) const {
return b.ty.depth_texture(dims);
}
DepthMultisampledTexture::DepthMultisampledTexture(type::TextureDimension d) : Base(d) {}
DepthMultisampledTexture::DepthMultisampledTexture(const DepthMultisampledTexture&) = default;
const ast::Type* DepthMultisampledTexture::Build(ProgramBuilder& b) const {
ast::Type DepthMultisampledTexture::Build(ProgramBuilder& b) const {
return b.ty.depth_multisampled_texture(dims);
}
@ -258,14 +258,14 @@ MultisampledTexture::MultisampledTexture(type::TextureDimension d, const Type* t
: Base(d), type(t) {}
MultisampledTexture::MultisampledTexture(const MultisampledTexture&) = default;
const ast::Type* MultisampledTexture::Build(ProgramBuilder& b) const {
ast::Type MultisampledTexture::Build(ProgramBuilder& b) const {
return b.ty.multisampled_texture(dims, type->Build(b));
}
SampledTexture::SampledTexture(type::TextureDimension d, const Type* t) : Base(d), type(t) {}
SampledTexture::SampledTexture(const SampledTexture&) = default;
const ast::Type* SampledTexture::Build(ProgramBuilder& b) const {
ast::Type SampledTexture::Build(ProgramBuilder& b) const {
return b.ty.sampled_texture(dims, type->Build(b));
}
@ -273,7 +273,7 @@ StorageTexture::StorageTexture(type::TextureDimension d, type::TexelFormat f, ty
: Base(d), format(f), access(a) {}
StorageTexture::StorageTexture(const StorageTexture&) = default;
const ast::Type* StorageTexture::Build(ProgramBuilder& b) const {
ast::Type StorageTexture::Build(ProgramBuilder& b) const {
return b.ty.storage_texture(dims, format, access);
}
@ -284,7 +284,7 @@ Named::~Named() = default;
Alias::Alias(Symbol n, const Type* ty) : Base(n), type(ty) {}
Alias::Alias(const Alias&) = default;
const ast::Type* Alias::Build(ProgramBuilder& b) const {
ast::Type Alias::Build(ProgramBuilder& b) const {
return b.ty(name);
}
@ -292,7 +292,7 @@ Struct::Struct(Symbol n, TypeList m) : Base(n), members(std::move(m)) {}
Struct::Struct(const Struct&) = default;
Struct::~Struct() = default;
const ast::Type* Struct::Build(ProgramBuilder& b) const {
ast::Type Struct::Build(ProgramBuilder& b) const {
return b.ty(name);
}

View File

@ -19,6 +19,7 @@
#include <string>
#include <vector>
#include "src/tint/ast/type.h"
#include "src/tint/castable.h"
#include "src/tint/symbol.h"
#include "src/tint/type/access.h"
@ -32,9 +33,6 @@
namespace tint {
class ProgramBuilder;
} // namespace tint
namespace tint::ast {
class Type;
} // namespace tint::ast
namespace tint::reader::spirv {
@ -50,7 +48,7 @@ class Type : public Castable<Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
virtual const ast::Type* Build(ProgramBuilder& b) const = 0;
virtual ast::Type Build(ProgramBuilder& b) const = 0;
/// @returns the inner most store type if this is a pointer, `this` otherwise
const Type* UnwrapPtr() const;
@ -102,7 +100,7 @@ using TypeList = std::vector<const Type*>;
struct Void final : public Castable<Void, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -114,7 +112,7 @@ struct Void final : public Castable<Void, Type> {
struct Bool final : public Castable<Bool, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -126,7 +124,7 @@ struct Bool final : public Castable<Bool, Type> {
struct U32 final : public Castable<U32, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -138,7 +136,7 @@ struct U32 final : public Castable<U32, Type> {
struct F32 final : public Castable<F32, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -150,7 +148,7 @@ struct F32 final : public Castable<F32, Type> {
struct I32 final : public Castable<I32, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -172,7 +170,7 @@ struct Pointer final : public Castable<Pointer, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -203,7 +201,7 @@ struct Reference final : public Castable<Reference, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -231,7 +229,7 @@ struct Vector final : public Castable<Vector, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -258,7 +256,7 @@ struct Matrix final : public Castable<Matrix, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -288,7 +286,7 @@ struct Array final : public Castable<Array, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -315,7 +313,7 @@ struct Sampler final : public Castable<Sampler, Type> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -354,7 +352,7 @@ struct DepthTexture final : public Castable<DepthTexture, Texture> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -374,7 +372,7 @@ struct DepthMultisampledTexture final : public Castable<DepthMultisampledTexture
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -395,7 +393,7 @@ struct MultisampledTexture final : public Castable<MultisampledTexture, Texture>
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -419,7 +417,7 @@ struct SampledTexture final : public Castable<SampledTexture, Texture> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -444,7 +442,7 @@ struct StorageTexture final : public Castable<StorageTexture, Texture> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
@ -493,7 +491,7 @@ struct Alias final : public Castable<Alias, Named> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
/// the aliased type
Type const* const type;
@ -515,7 +513,7 @@ struct Struct final : public Castable<Struct, Named> {
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
const ast::Type* Build(ProgramBuilder& b) const override;
ast::Type Build(ProgramBuilder& b) const override;
/// the member types
const TypeList members;

View File

@ -16,7 +16,6 @@
#include <limits>
#include "src/tint/ast/array.h"
#include "src/tint/ast/assignment_statement.h"
#include "src/tint/ast/bitcast_expression.h"
#include "src/tint/ast/break_if_statement.h"
@ -32,10 +31,8 @@
#include "src/tint/ast/return_statement.h"
#include "src/tint/ast/stage_attribute.h"
#include "src/tint/ast/switch_statement.h"
#include "src/tint/ast/type_name.h"
#include "src/tint/ast/unary_op_expression.h"
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/ast/vector.h"
#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/reader/wgsl/classify_template_args.h"
#include "src/tint/reader/wgsl/lexer.h"
@ -180,7 +177,7 @@ ParserImpl::TypedIdentifier::TypedIdentifier() = default;
ParserImpl::TypedIdentifier::TypedIdentifier(const TypedIdentifier&) = default;
ParserImpl::TypedIdentifier::TypedIdentifier(const ast::Type* type_in,
ParserImpl::TypedIdentifier::TypedIdentifier(ast::Type type_in,
std::string name_in,
Source source_in)
: type(type_in), name(std::move(name_in)), source(std::move(source_in)) {}
@ -194,7 +191,7 @@ ParserImpl::FunctionHeader::FunctionHeader(const FunctionHeader&) = default;
ParserImpl::FunctionHeader::FunctionHeader(Source src,
std::string n,
utils::VectorRef<const ast::Parameter*> p,
const ast::Type* ret_ty,
ast::Type ret_ty,
utils::VectorRef<const ast::Attribute*> ret_attrs)
: source(src),
name(n),
@ -215,7 +212,7 @@ ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
std::string name_in,
type::AddressSpace address_space_in,
type::Access access_in,
const ast::Type* type_in)
ast::Type type_in)
: source(std::move(source_in)),
name(std::move(name_in)),
address_space(address_space_in),
@ -733,7 +730,7 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
// | multisampled_texture_type LESS_THAN type_specifier GREATER_THAN
// | storage_texture_type LESS_THAN texel_format
// COMMA access_mode GREATER_THAN
Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
Maybe<ast::Type> ParserImpl::texture_and_sampler_types() {
auto type = sampler_type();
if (type.matched) {
return type;
@ -811,7 +808,7 @@ Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
// sampler_type
// : SAMPLER
// | SAMPLER_COMPARISON
Maybe<const ast::Type*> ParserImpl::sampler_type() {
Maybe<ast::Type> ParserImpl::sampler_type() {
Source source;
if (match(Token::Type::kSampler, &source)) {
return builder_.ty.sampler(source, type::SamplerKind::kSampler);
@ -861,7 +858,7 @@ Maybe<const type::TextureDimension> ParserImpl::sampled_texture_type() {
// external_texture
// : TEXTURE_EXTERNAL
Maybe<const ast::Type*> ParserImpl::external_texture() {
Maybe<ast::Type> ParserImpl::external_texture() {
Source source;
if (match(Token::Type::kTextureExternal, &source)) {
return builder_.ty.external_texture(source);
@ -908,7 +905,7 @@ Maybe<const type::TextureDimension> ParserImpl::storage_texture_type() {
// | TEXTURE_DEPTH_CUBE
// | TEXTURE_DEPTH_CUBE_ARRAY
// | TEXTURE_DEPTH_MULTISAMPLED_2D
Maybe<const ast::Type*> ParserImpl::depth_texture_type() {
Maybe<ast::Type> ParserImpl::depth_texture_type() {
Source source;
if (match(Token::Type::kTextureDepth2d, &source)) {
return builder_.ty.depth_texture(source, type::TextureDimension::k2d);
@ -958,7 +955,7 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_with_optional_type_
}
if (allow_inferred && !peek_is(Token::Type::kColon)) {
return TypedIdentifier{nullptr, ident.value, ident.source};
return TypedIdentifier{ast::Type{}, ident.value, ident.source};
}
if (!expect(use, Token::Type::kColon)) {
@ -1130,7 +1127,7 @@ Maybe<ParserImpl::MatrixDimensions> ParserImpl::mat_prefix() {
// | mat_prefix LESS_THAN type_specifier GREATER_THAN
// | vec_prefix LESS_THAN type_specifier GREATER_THAN
// | texture_and_sampler_types
Maybe<const ast::Type*> ParserImpl::type_specifier_without_ident() {
Maybe<ast::Type> ParserImpl::type_specifier_without_ident() {
auto& t = peek();
if (match(Token::Type::kBool)) {
@ -1198,7 +1195,7 @@ Maybe<const ast::Type*> ParserImpl::type_specifier_without_ident() {
// type_specifier
// : IDENTIFIER
// | type_specifier_without_ident
Maybe<const ast::Type*> ParserImpl::type_specifier() {
Maybe<ast::Type> ParserImpl::type_specifier() {
auto& t = peek();
Source source;
if (match(Token::Type::kIdentifier, &source)) {
@ -1243,7 +1240,7 @@ Expect<ENUM> ParserImpl::expect_enum(std::string_view name,
return add_error(t.source(), err.str());
}
Expect<const ast::Type*> ParserImpl::expect_type(std::string_view use) {
Expect<ast::Type> ParserImpl::expect_type(std::string_view use) {
auto type = type_specifier();
if (type.errored) {
return Failure::kErrored;
@ -1255,13 +1252,13 @@ Expect<const ast::Type*> ParserImpl::expect_type(std::string_view use) {
}
// LESS_THAN address_space COMMA type_specifier ( COMMA access_mode )? GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source& s) {
Expect<ast::Type> ParserImpl::expect_type_specifier_pointer(const Source& s) {
const char* use = "ptr declaration";
auto address_space = type::AddressSpace::kNone;
auto access = type::Access::kUndefined;
auto subtype = expect_template_arg_block(use, [&]() -> Expect<const ast::Type*> {
auto subtype = expect_template_arg_block(use, [&]() -> Expect<ast::Type> {
auto sc = expect_address_space(use);
if (sc.errored) {
return Failure::kErrored;
@ -1296,7 +1293,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source&
}
// LESS_THAN type_specifier GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_specifier_atomic(const Source& s) {
Expect<ast::Type> ParserImpl::expect_type_specifier_atomic(const Source& s) {
const char* use = "atomic declaration";
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
@ -1308,7 +1305,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_atomic(const Source&
}
// LESS_THAN type_specifier GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_specifier_vector(const Source& s, uint32_t count) {
Expect<ast::Type> ParserImpl::expect_type_specifier_vector(const Source& s, uint32_t count) {
const char* use = "vector";
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
if (ty.errored) {
@ -1319,11 +1316,11 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_vector(const Source&
}
// LESS_THAN type_specifier ( COMMA element_count_expression )? GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_specifier_array(const Source& s) {
Expect<ast::Type> ParserImpl::expect_type_specifier_array(const Source& s) {
const char* use = "array declaration";
struct TypeAndSize {
const ast::Type* type = nullptr;
ast::Type type;
const ast::Expression* size = nullptr;
};
@ -1352,11 +1349,15 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_array(const Source& s
return Failure::kErrored;
}
if (type_size->size) {
return builder_.ty.array(make_source_range_from(s), type_size->type, type_size->size);
} else {
return builder_.ty.array(make_source_range_from(s), type_size->type);
}
}
// LESS_THAN type_specifier GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_specifier_matrix(const Source& s,
Expect<ast::Type> ParserImpl::expect_type_specifier_matrix(const Source& s,
const MatrixDimensions& dims) {
const char* use = "matrix";
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
@ -1542,7 +1543,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
}
}
const ast::Type* return_type = nullptr;
ast::Type return_type;
AttributeList return_attributes;
if (match(Token::Type::kArrow)) {
@ -2417,10 +2418,7 @@ Maybe<const ast::CallStatement*> ParserImpl::func_call_statement() {
return builder_.CallStmt(
t.source(),
create<ast::CallExpression>(
t.source(),
create<ast::Identifier>(t.source(), builder_.Symbols().Register(t.to_str())),
std::move(params.value)));
builder_.Call(t.source(), builder_.Expr(t.source(), t.to_str()), std::move(params.value)));
}
// break_statement
@ -2530,7 +2528,7 @@ Maybe<const ast::BlockStatement*> ParserImpl::continuing_statement() {
// Note, `ident` is pulled out to `primary_expression` as it's the only one that
// doesn't create a `type`. Then we can just return a `type` from here on match and
// deal with `ident` in `primary_expression.
Maybe<const ast::Type*> ParserImpl::callable() {
Maybe<const ast::IdentifierExpression*> ParserImpl::callable() {
auto& t = peek();
// This _must_ match `type_specifier_without_ident` before any of the other types as they're
@ -2541,21 +2539,21 @@ Maybe<const ast::Type*> ParserImpl::callable() {
return Failure::kErrored;
}
if (ty.matched) {
return ty.value;
return ty->expr;
}
if (match(Token::Type::kArray)) {
return builder_.ty.array(make_source_range_from(t.source()), nullptr, nullptr);
return builder_.ty.array<Infer>(make_source_range_from(t.source()));
}
auto vec = vec_prefix();
if (vec.matched) {
return builder_.ty.vec(make_source_range_from(t.source()), nullptr, vec.value);
return builder_.ty.vec<Infer>(make_source_range_from(t.source()), vec.value);
}
auto mat = mat_prefix();
if (mat.matched) {
return builder_.ty.mat(make_source_range_from(t.source()), nullptr, mat.value.columns,
return builder_.ty.mat<Infer>(make_source_range_from(t.source()), mat.value.columns,
mat.value.rows);
}

View File

@ -220,12 +220,12 @@ class ParserImpl {
/// @param type_in parsed type
/// @param name_in parsed identifier
/// @param source_in source to the identifier
TypedIdentifier(const ast::Type* type_in, std::string name_in, Source source_in);
TypedIdentifier(ast::Type type_in, std::string name_in, Source source_in);
/// Destructor
~TypedIdentifier();
/// Parsed type. May be nullptr for inferred types.
const ast::Type* type = nullptr;
/// Parsed type. type.expr be nullptr for inferred types.
ast::Type type;
/// Parsed identifier.
std::string name;
/// Source to the identifier.
@ -248,7 +248,7 @@ class ParserImpl {
FunctionHeader(Source src,
std::string n,
utils::VectorRef<const ast::Parameter*> p,
const ast::Type* ret_ty,
ast::Type ret_ty,
utils::VectorRef<const ast::Attribute*> ret_attrs);
/// Destructor
~FunctionHeader();
@ -264,7 +264,7 @@ class ParserImpl {
/// Function parameters
utils::Vector<const ast::Parameter*, 8> params;
/// Function return type
const ast::Type* return_type = nullptr;
ast::Type return_type;
/// Function return type attributes
AttributeList return_type_attributes;
};
@ -286,7 +286,7 @@ class ParserImpl {
std::string name_in,
type::AddressSpace address_space_in,
type::Access access_in,
const ast::Type* type_in);
ast::Type type_in);
/// Destructor
~VarDeclInfo();
@ -299,7 +299,7 @@ class ParserImpl {
/// Variable access control
type::Access access = type::Access::kUndefined;
/// Variable type
const ast::Type* type = nullptr;
ast::Type type;
};
/// VariableQualifier contains the parsed information for a variable qualifier
@ -449,7 +449,7 @@ class ParserImpl {
Maybe<const ast::Alias*> type_alias_decl();
/// Parses a `callable` grammar element
/// @returns the type or nullptr
Maybe<const ast::Type*> callable();
Maybe<const ast::IdentifierExpression*> callable();
/// Parses a `vec_prefix` grammar element
/// @returns the vector size or nullptr
Maybe<uint32_t> vec_prefix();
@ -458,10 +458,10 @@ class ParserImpl {
Maybe<MatrixDimensions> mat_prefix();
/// Parses a `type_specifier_without_ident` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> type_specifier_without_ident();
Maybe<ast::Type> type_specifier_without_ident();
/// Parses a `type_specifier` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> type_specifier();
Maybe<ast::Type> type_specifier();
/// Parses an `address_space` grammar element, erroring on parse failure.
/// @param use a description of what was being parsed if an error was raised.
/// @returns the address space or type::AddressSpace::kNone if none matched
@ -483,10 +483,10 @@ class ParserImpl {
Maybe<const ast::Function*> function_decl(AttributeList& attrs);
/// Parses a `texture_and_sampler_types` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> texture_and_sampler_types();
Maybe<ast::Type> texture_and_sampler_types();
/// Parses a `sampler_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> sampler_type();
Maybe<ast::Type> sampler_type();
/// Parses a `multisampled_texture_type` grammar element
/// @returns returns the multisample texture dimension or kNone if none
/// matched.
@ -500,10 +500,10 @@ class ParserImpl {
Maybe<const type::TextureDimension> storage_texture_type();
/// Parses a `depth_texture_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> depth_texture_type();
Maybe<ast::Type> depth_texture_type();
/// Parses a 'texture_external_type' grammar element
/// @returns the parsed Type or nullptr if none matched
Maybe<const ast::Type*> external_texture();
Maybe<ast::Type> external_texture();
/// Parses a `texel_format` grammar element
/// @param use a description of what was being parsed if an error was raised
/// @returns returns the texel format or kNone if none matched.
@ -891,12 +891,11 @@ class ParserImpl {
/// Used to ensure that all attributes are consumed.
bool expect_attributes_consumed(utils::VectorRef<const ast::Attribute*> list);
Expect<const ast::Type*> expect_type_specifier_pointer(const Source& s);
Expect<const ast::Type*> expect_type_specifier_atomic(const Source& s);
Expect<const ast::Type*> expect_type_specifier_vector(const Source& s, uint32_t count);
Expect<const ast::Type*> expect_type_specifier_array(const Source& s);
Expect<const ast::Type*> expect_type_specifier_matrix(const Source& s,
const MatrixDimensions& dims);
Expect<ast::Type> expect_type_specifier_pointer(const Source& s);
Expect<ast::Type> expect_type_specifier_atomic(const Source& s);
Expect<ast::Type> expect_type_specifier_vector(const Source& s, uint32_t count);
Expect<ast::Type> expect_type_specifier_array(const Source& s);
Expect<ast::Type> expect_type_specifier_matrix(const Source& s, const MatrixDimensions& dims);
/// Parses the given enum, providing sensible error messages if the next token does not match
/// any of the enum values.
@ -910,7 +909,7 @@ class ParserImpl {
const char* const (&strings)[N],
std::string_view use = "");
Expect<const ast::Type*> expect_type(std::string_view use);
Expect<ast::Type> expect_type(std::string_view use);
Maybe<const ast::Statement*> non_block_statement();
Maybe<const ast::Statement*> for_header_initializer();

View File

@ -13,6 +13,7 @@
// limitations under the License.
#include "src/tint/ast/call_statement.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
@ -34,7 +35,7 @@ TEST_F(ParserImplTest, Statement_Call) {
ASSERT_TRUE(e->Is<ast::CallStatement>());
auto* c = e->As<ast::CallStatement>()->expr;
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
ast::CheckIdentifier(p->builder().Symbols(), c->target, "a");
EXPECT_EQ(c->args.Length(), 0u);
}
@ -50,7 +51,7 @@ TEST_F(ParserImplTest, Statement_Call_WithParams) {
ASSERT_TRUE(e->Is<ast::CallStatement>());
auto* c = e->As<ast::CallStatement>()->expr;
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
ast::CheckIdentifier(p->builder().Symbols(), c->target, "a");
EXPECT_EQ(c->args.Length(), 3u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
@ -69,7 +70,7 @@ TEST_F(ParserImplTest, Statement_Call_WithParams_TrailingComma) {
ASSERT_TRUE(e->Is<ast::CallStatement>());
auto* c = e->As<ast::CallStatement>()->expr;
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
ast::CheckIdentifier(p->builder().Symbols(), c->target, "a");
EXPECT_EQ(c->args.Length(), 2u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());

View File

@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
namespace {
using namespace tint::number_suffixes; // NOLINT
TEST_F(ParserImplTest, Callable_Array) {
auto p = parser("array");
auto t = p->callable();
@ -25,12 +28,8 @@ TEST_F(ParserImplTest, Callable_Array) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value->As<ast::Array>();
EXPECT_FALSE(a->IsRuntimeArray());
EXPECT_EQ(a->type, nullptr);
EXPECT_EQ(a->count, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "array");
}
TEST_F(ParserImplTest, Callable_VecPrefix) {
@ -41,11 +40,8 @@ TEST_F(ParserImplTest, Callable_VecPrefix) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Vector>());
auto* v = t.value->As<ast::Vector>();
EXPECT_EQ(v->type, nullptr);
EXPECT_EQ(v->width, 3u);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "vec3");
}
TEST_F(ParserImplTest, Callable_MatPrefix) {
@ -56,12 +52,8 @@ TEST_F(ParserImplTest, Callable_MatPrefix) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Matrix>());
auto* m = t.value->As<ast::Matrix>();
EXPECT_EQ(m->type, nullptr);
EXPECT_EQ(m->columns, 3u);
EXPECT_EQ(m->rows, 2u);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "mat3x2");
}
TEST_F(ParserImplTest, Callable_TypeDecl_Array) {
@ -72,18 +64,8 @@ TEST_F(ParserImplTest, Callable_TypeDecl_Array) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value->As<ast::Array>();
EXPECT_FALSE(a->IsRuntimeArray());
ASSERT_TRUE(a->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(a->type->As<ast::TypeName>()->name->symbol), "f32");
auto* size = a->count->As<ast::IntLiteralExpression>();
ASSERT_NE(size, nullptr);
EXPECT_EQ(size->value, 2);
EXPECT_EQ(size->suffix, ast::IntLiteralExpression::Suffix::kNone);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32", 2_a));
}
TEST_F(ParserImplTest, Callable_TypeDecl_Array_Runtime) {
@ -94,15 +76,8 @@ TEST_F(ParserImplTest, Callable_TypeDecl_Array_Runtime) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value->As<ast::Array>();
EXPECT_TRUE(a->IsRuntimeArray());
ASSERT_TRUE(a->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(a->type->As<ast::TypeName>()->name->symbol), "f32");
ASSERT_EQ(a->count, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32"));
}
TEST_F(ParserImplTest, Callable_TypeDecl_VecPrefix) {
@ -113,14 +88,8 @@ TEST_F(ParserImplTest, Callable_TypeDecl_VecPrefix) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Vector>());
auto* v = t.value->As<ast::Vector>();
ASSERT_TRUE(v->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "f32");
EXPECT_EQ(v->width, 3u);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("vec3", "f32"));
}
TEST_F(ParserImplTest, Callable_TypeDecl_MatPrefix) {
@ -131,15 +100,8 @@ TEST_F(ParserImplTest, Callable_TypeDecl_MatPrefix) {
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Matrix>());
auto* m = t.value->As<ast::Matrix>();
ASSERT_TRUE(m->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(m->type->As<ast::TypeName>()->name->symbol), "f32");
EXPECT_EQ(m->columns, 3u);
EXPECT_EQ(m->rows, 2u);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("mat3x2", "f32"));
}
TEST_F(ParserImplTest, Callable_NoMatch) {

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/depth_texture.h"
#include "src/tint/type/texture_dimension.h"
@ -33,9 +34,8 @@ TEST_F(ParserImplTest, DepthTextureType_2d) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_2d");
EXPECT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
@ -45,9 +45,8 @@ TEST_F(ParserImplTest, DepthTextureType_2dArray) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_2d_array");
EXPECT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d_array");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 23u}}));
}
@ -57,9 +56,8 @@ TEST_F(ParserImplTest, DepthTextureType_Cube) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_cube");
EXPECT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_cube");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
@ -69,9 +67,8 @@ TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_cube_array");
EXPECT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_cube_array");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
}
@ -81,9 +78,8 @@ TEST_F(ParserImplTest, DepthTextureType_Multisampled2d) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_multisampled_2d");
EXPECT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_multisampled_2d");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 30u}}));
}

View File

@ -15,6 +15,7 @@
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/ast/diagnostic_control.h"
#include "src/tint/ast/test_helper.h"
namespace tint::reader::wgsl {
namespace {
@ -29,7 +30,7 @@ TEST_F(ParserImplTest, DiagnosticAttribute_Valid) {
EXPECT_EQ(d->control.severity, ast::DiagnosticSeverity::kOff);
auto* r = d->control.rule_name;
ASSERT_NE(r, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
ast::CheckIdentifier(p->builder().Symbols(), r, "foo");
}
} // namespace

View File

@ -15,6 +15,7 @@
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/ast/diagnostic_control.h"
#include "src/tint/ast/test_helper.h"
namespace tint::reader::wgsl {
namespace {
@ -32,7 +33,7 @@ TEST_P(DiagnosticControlParserTest, DiagnosticControl_Valid) {
auto* r = e->rule_name;
ASSERT_NE(r, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
ast::CheckIdentifier(p->builder().Symbols(), r, "foo");
}
INSTANTIATE_TEST_SUITE_P(DiagnosticControlParserTest,
DiagnosticControlParserTest,
@ -50,7 +51,7 @@ TEST_F(ParserImplTest, DiagnosticControl_Valid_TrailingComma) {
auto* r = e->rule_name;
ASSERT_NE(r, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
ast::CheckIdentifier(p->builder().Symbols(), r, "foo");
}
TEST_F(ParserImplTest, DiagnosticControl_MissingOpenParen) {

View File

@ -15,6 +15,7 @@
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/ast/diagnostic_control.h"
#include "src/tint/ast/test_helper.h"
namespace tint::reader::wgsl {
namespace {
@ -32,7 +33,7 @@ TEST_F(ParserImplTest, DiagnosticDirective_Valid) {
auto* r = directive->control.rule_name;
ASSERT_NE(r, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
ast::CheckIdentifier(p->builder().Symbols(), r, "foo");
}
TEST_F(ParserImplTest, DiagnosticDirective_MissingSemicolon) {

View File

@ -13,6 +13,7 @@
// limitations under the License.
#include "src/tint/ast/stage_attribute.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
@ -310,9 +311,7 @@ TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
ast::IntLiteralExpression::Suffix::kNone);
ASSERT_NE(values[1], nullptr);
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
ASSERT_NE(y_ident, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->identifier->symbol), "height");
ast::CheckIdentifier(p->builder().Symbols(), values[1], "height");
ASSERT_EQ(values[2], nullptr);
}

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/utils/string.h"
@ -240,9 +241,7 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeAttributeList) {
EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get("main"));
ASSERT_NE(f->return_type, nullptr);
ASSERT_TRUE(f->return_type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(f->return_type->As<ast::TypeName>()->name->symbol),
"f32");
ast::CheckIdentifier(p->builder().Symbols(), f->return_type, "f32");
ASSERT_EQ(f->params.Length(), 0u);

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
@ -52,9 +53,7 @@ TEST_F(ParserImplTest, FunctionHeader_AttributeReturnType) {
EXPECT_EQ(f->name, "main");
EXPECT_EQ(f->params.Length(), 0u);
ASSERT_TRUE(f->return_type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(f->return_type->As<ast::TypeName>()->name->symbol),
"f32");
ast::CheckIdentifier(p->builder().Symbols(), f->return_type, "f32");
ASSERT_EQ(f->return_type_attributes.Length(), 1u);
auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
@ -73,9 +72,7 @@ TEST_F(ParserImplTest, FunctionHeader_InvariantReturnType) {
EXPECT_EQ(f->name, "main");
EXPECT_EQ(f->params.Length(), 0u);
ASSERT_TRUE(f->return_type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(f->return_type->As<ast::TypeName>()->name->symbol),
"f32");
ast::CheckIdentifier(p->builder().Symbols(), f->return_type, "f32");
ASSERT_EQ(f->return_type_attributes.Length(), 1u);
EXPECT_TRUE(f->return_type_attributes[0]->Is<ast::InvariantAttribute>());
}

View File

@ -13,6 +13,7 @@
// limitations under the License.
#include "src/tint/ast/id_attribute.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
@ -44,8 +45,7 @@ TEST_F(ParserImplTest, GlobalConstDecl) {
EXPECT_EQ(c->name->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(c->type, nullptr);
ASSERT_TRUE(c->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(c->type->As<ast::TypeName>()->name->symbol), "f32");
ast::CheckIdentifier(p->builder().Symbols(), c->type, "f32");
EXPECT_EQ(c->source.range.begin.line, 1u);
EXPECT_EQ(c->source.range.begin.column, 7u);
@ -121,9 +121,7 @@ TEST_F(ParserImplTest, GlobalOverrideDecl_WithId) {
EXPECT_EQ(override->name->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(override->type, nullptr);
ASSERT_TRUE(override->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(override->type->As<ast::TypeName>()->name->symbol),
"f32");
ast::CheckIdentifier(p->builder().Symbols(), override->type, "f32");
EXPECT_EQ(override->source.range.begin.line, 1u);
EXPECT_EQ(override->source.range.begin.column, 17u);
@ -153,9 +151,7 @@ TEST_F(ParserImplTest, GlobalOverrideDecl_WithId_TrailingComma) {
EXPECT_EQ(override->name->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(override->type, nullptr);
ASSERT_TRUE(override->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(override->type->As<ast::TypeName>()->name->symbol),
"f32");
ast::CheckIdentifier(p->builder().Symbols(), override->type, "f32");
EXPECT_EQ(override->source.range.begin.line, 1u);
EXPECT_EQ(override->source.range.begin.column, 18u);
@ -185,9 +181,7 @@ TEST_F(ParserImplTest, GlobalOverrideDecl_WithoutId) {
EXPECT_EQ(override->name->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(override->type, nullptr);
ASSERT_TRUE(override->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(override->type->As<ast::TypeName>()->name->symbol),
"f32");
ast::CheckIdentifier(p->builder().Symbols(), override->type, "f32");
EXPECT_EQ(override->source.range.begin.line, 1u);
EXPECT_EQ(override->source.range.begin.column, 10u);

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
@ -33,7 +34,7 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalVariable) {
auto* v = program.AST().GlobalVariables()[0];
EXPECT_EQ(v->name->symbol, program.Symbols().Get("a"));
EXPECT_TRUE(Is<ast::Vector>(v->type));
ast::CheckIdentifier(program.Symbols(), v->type, ast::Template("vec2", "i32"));
}
TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Inferred) {
@ -106,8 +107,7 @@ TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
auto program = p->program();
ASSERT_EQ(program.AST().TypeDecls().Length(), 1u);
ASSERT_TRUE(program.AST().TypeDecls()[0]->Is<ast::Alias>());
EXPECT_EQ(
program.Symbols().NameFor(program.AST().TypeDecls()[0]->As<ast::Alias>()->name->symbol),
ast::CheckIdentifier(program.Symbols(), program.AST().TypeDecls()[0]->As<ast::Alias>()->name,
"A");
}
@ -129,9 +129,7 @@ alias B = A;)");
ASSERT_TRUE(program.AST().TypeDecls()[1]->Is<ast::Alias>());
auto* alias = program.AST().TypeDecls()[1]->As<ast::Alias>();
EXPECT_EQ(alias->name->symbol, program.Symbols().Get("B"));
auto* tn = alias->type->As<ast::TypeName>();
EXPECT_NE(tn, nullptr);
EXPECT_EQ(tn->name->symbol, str->name->symbol);
ast::CheckIdentifier(program.Symbols(), alias->type, "A");
}
// TODO(crbug.com/tint/1812): DEPRECATED
@ -143,8 +141,7 @@ TEST_F(ParserImplTest, DEPRECATED_GlobalDecl_TypeAlias) {
auto program = p->program();
ASSERT_EQ(program.AST().TypeDecls().Length(), 1u);
ASSERT_TRUE(program.AST().TypeDecls()[0]->Is<ast::Alias>());
EXPECT_EQ(
program.Symbols().NameFor(program.AST().TypeDecls()[0]->As<ast::Alias>()->name->symbol),
ast::CheckIdentifier(program.Symbols(), program.AST().TypeDecls()[0]->As<ast::Alias>()->name,
"A");
}
@ -167,9 +164,7 @@ type B = A;)");
ASSERT_TRUE(program.AST().TypeDecls()[1]->Is<ast::Alias>());
auto* alias = program.AST().TypeDecls()[1]->As<ast::Alias>();
EXPECT_EQ(alias->name->symbol, program.Symbols().Get("B"));
auto* tn = alias->type->As<ast::TypeName>();
EXPECT_NE(tn, nullptr);
EXPECT_EQ(tn->name->symbol, str->name->symbol);
ast::CheckIdentifier(program.Symbols(), alias->type, "A");
}
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_MissingSemicolon) {
@ -196,7 +191,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function) {
auto program = p->program();
ASSERT_EQ(program.AST().Functions().Length(), 1u);
EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->name->symbol), "main");
ast::CheckIdentifier(program.Symbols(), program.AST().Functions()[0]->name, "main");
}
TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) {
@ -206,7 +201,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) {
auto program = p->program();
ASSERT_EQ(program.AST().Functions().Length(), 1u);
EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->name->symbol), "main");
ast::CheckIdentifier(program.Symbols(), program.AST().Functions()[0]->name, "main");
}
TEST_F(ParserImplTest, GlobalDecl_Function_Invalid) {

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
@ -29,10 +30,9 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithoutInitializer) {
auto* var = e.value->As<ast::Var>();
ASSERT_NE(var, nullptr);
EXPECT_EQ(var->name->symbol, p->builder().Symbols().Get("a"));
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
ASSERT_TRUE(var->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(var->type->As<ast::TypeName>()->name->symbol), "f32");
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
EXPECT_EQ(var->declared_address_space, type::AddressSpace::kPrivate);
@ -56,10 +56,8 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithInitializer) {
auto* var = e.value->As<ast::Var>();
ASSERT_NE(var, nullptr);
EXPECT_EQ(var->name->symbol, p->builder().Symbols().Get("a"));
ASSERT_TRUE(var->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(var->type->As<ast::TypeName>()->name->symbol), "f32");
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
EXPECT_EQ(var->declared_address_space, type::AddressSpace::kPrivate);
@ -84,11 +82,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute) {
auto* var = e.value->As<ast::Var>();
ASSERT_NE(var, nullptr);
EXPECT_EQ(var->name->symbol, p->builder().Symbols().Get("a"));
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
ASSERT_NE(var->type, nullptr);
ASSERT_TRUE(var->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(var->type->As<ast::TypeName>()->name->symbol), "f32");
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
EXPECT_EQ(var->declared_address_space, type::AddressSpace::kUniform);
@ -118,11 +115,9 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute_MulitpleGroups) {
auto* var = e.value->As<ast::Var>();
ASSERT_NE(var, nullptr);
EXPECT_EQ(var->name->symbol, p->builder().Symbols().Get("a"));
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
ASSERT_NE(var->type, nullptr);
ASSERT_TRUE(var->type->Is<ast::TypeName>());
EXPECT_EQ(p->builder().Symbols().NameFor(var->type->As<ast::TypeName>()->name->symbol), "f32");
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
EXPECT_EQ(var->declared_address_space, type::AddressSpace::kUniform);

Some files were not shown because too many files have changed in this diff Show More