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

View File

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

View File

@ -20,7 +20,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::Alias);
namespace tint::ast { 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) { : Base(pid, nid, src, n), type(subtype) {
TINT_ASSERT(AST, type); 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 // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto sym = ctx->Clone(name); auto sym = ctx->Clone(name);
auto* ty = ctx->Clone(type); auto ty = ctx->Clone(type);
return ctx->dst->create<Alias>(src, sym, ty); return ctx->dst->create<Alias>(src, sym, ty);
} }

View File

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

View File

@ -13,13 +13,7 @@
// limitations under the License. // limitations under the License.
#include "src/tint/ast/alias.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/test_helper.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/type/access.h" #include "src/tint/type/access.h"
namespace tint::ast { namespace tint::ast {
@ -28,10 +22,10 @@ namespace {
using AstAliasTest = TestHelper; using AstAliasTest = TestHelper;
TEST_F(AstAliasTest, Create) { TEST_F(AstAliasTest, Create) {
auto* u32 = ty.u32(); auto u32 = ty.u32();
auto* a = Alias("a_type", u32); auto* a = Alias("a_type", u32);
EXPECT_EQ(Symbols().NameFor(a->name->symbol), "a_type"); CheckIdentifier(Symbols(), a->name, "a_type");
EXPECT_EQ(a->type, u32); CheckIdentifier(Symbols(), a->type, "u32");
} }
} // namespace } // 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, BitcastExpression::BitcastExpression(ProgramID pid,
NodeID nid, NodeID nid,
const Source& src, const Source& src,
const Type* t, Type t,
const Expression* e) const Expression* e)
: Base(pid, nid, src), type(t), expr(e) { : Base(pid, nid, src), type(t), expr(e) {
TINT_ASSERT(AST, type); TINT_ASSERT(AST, type);
@ -37,7 +37,7 @@ BitcastExpression::~BitcastExpression() = default;
const BitcastExpression* BitcastExpression::Clone(CloneContext* ctx) const { const BitcastExpression* BitcastExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* t = ctx->Clone(type); auto t = ctx->Clone(type);
auto* e = ctx->Clone(expr); auto* e = ctx->Clone(expr);
return ctx->dst->create<BitcastExpression>(src, t, e); return ctx->dst->create<BitcastExpression>(src, t, e);
} }

View File

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

View File

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

View File

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

View File

@ -224,7 +224,7 @@ struct TextureOverloadCase {
/// @param builder the AST builder used for the test /// @param builder the AST builder used for the test
/// @returns the vector component type of the texture function return value /// @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 /// @param builder the AST builder used for the test
/// @returns a variable holding the test texture, automatically registered as /// @returns a variable holding the test texture, automatically registered as
/// a global variable. /// a global variable.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -44,11 +44,6 @@ TEST_F(IdentifierExpressionTest, Creation_WithSource) {
EXPECT_EQ(i->identifier->source.range, (Source::Range{{20, 2}})); 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) { TEST_F(IdentifierExpressionTest, Assert_InvalidSymbol) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {

View File

@ -26,7 +26,7 @@ Let::Let(ProgramID pid,
NodeID nid, NodeID nid,
const Source& src, const Source& src,
const Identifier* n, const Identifier* n,
const ast::Type* ty, Type ty,
const Expression* init, const Expression* init,
utils::VectorRef<const Attribute*> attrs) utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, init, std::move(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 { const Let* Let::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* n = ctx->Clone(name); auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type); auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer); auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Let>(src, n, ty, init, std::move(attrs)); 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, NodeID nid,
const Source& source, const Source& source,
const Identifier* name, const Identifier* name,
const ast::Type* type, Type type,
const Expression* initializer, const Expression* initializer,
utils::VectorRef<const Attribute*> attributes); 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/diagnostic_directive.h"
#include "src/tint/ast/enable.h" #include "src/tint/ast/enable.h"
#include "src/tint/ast/function.h" #include "src/tint/ast/function.h"
#include "src/tint/ast/type.h"
#include "src/tint/utils/vector.h" #include "src/tint/utils/vector.h"
namespace tint::ast { 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, NodeID nid,
const Source& src, const Source& src,
const Identifier* n, const Identifier* n,
const ast::Type* ty, Type ty,
const Expression* init, const Expression* init,
utils::VectorRef<const Attribute*> attrs) utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, init, std::move(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 { const Override* Override::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* n = ctx->Clone(name); auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type); auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer); auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Override>(src, n, ty, init, std::move(attrs)); 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, NodeID nid,
const Source& source, const Source& source,
const Identifier* name, const Identifier* name,
const ast::Type* type, Type type,
const Expression* initializer, const Expression* initializer,
utils::VectorRef<const Attribute*> attributes); utils::VectorRef<const Attribute*> attributes);

View File

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

View File

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

View File

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

View File

@ -15,12 +15,7 @@
#include "src/tint/ast/struct.h" #include "src/tint/ast/struct.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "src/tint/ast/alias.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/test_helper.h"
#include "src/tint/ast/texture.h"
#include "src/tint/ast/vector.h"
#include "src/tint/transform/add_block_attribute.h" #include "src/tint/transform/add_block_attribute.h"
namespace tint::ast { namespace tint::ast {

View File

@ -26,10 +26,15 @@ TemplatedIdentifier::TemplatedIdentifier(ProgramID pid,
NodeID nid, NodeID nid,
const Source& src, const Source& src,
const Symbol& sym, const Symbol& sym,
utils::VectorRef<const ast::Expression*> args) utils::VectorRef<const Expression*> args,
: Base(pid, nid, src, sym), arguments(std::move(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) { 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 src = ctx->Clone(source);
auto sym = ctx->Clone(symbol); auto sym = ctx->Clone(symbol);
auto args = ctx->Clone(arguments); 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 } // namespace tint::ast

View File

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

View File

@ -71,14 +71,13 @@ struct IsTemplatedIdentifierMatcher<TemplatedIdentifierMatcher<ARGS...>> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
/// A testing utility for checking that an Identifier and any optional templated arguments match the /// A testing utility for checking that an Identifier matches the expected values.
/// expected values.
/// @param symbols the symbol table /// @param symbols the symbol table
/// @param got the identifier /// @param got the identifier
/// @param expected the expected identifier name /// @param expected the expected identifier name
template <typename... ARGS> template <typename... ARGS>
void CheckIdentifier(const SymbolTable& symbols, const Identifier* got, std::string_view expected) { 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); EXPECT_EQ(symbols.NameFor(got->symbol), expected);
} }
@ -92,8 +91,8 @@ void CheckIdentifier(const SymbolTable& symbols,
const Identifier* ident, const Identifier* ident,
const TemplatedIdentifierMatcher<ARGS...>& expected) { const TemplatedIdentifierMatcher<ARGS...>& expected) {
EXPECT_EQ(symbols.NameFor(ident->symbol), expected.name); EXPECT_EQ(symbols.NameFor(ident->symbol), expected.name);
ASSERT_TRUE(ident->Is<ast::TemplatedIdentifier>()); ASSERT_TRUE(ident->Is<TemplatedIdentifier>());
auto* got = ident->As<ast::TemplatedIdentifier>(); auto* got = ident->As<TemplatedIdentifier>();
ASSERT_EQ(got->arguments.Length(), std::tuple_size_v<decltype(expected.args)>); ASSERT_EQ(got->arguments.Length(), std::tuple_size_v<decltype(expected.args)>);
size_t arg_idx = 0; size_t arg_idx = 0;
@ -103,8 +102,7 @@ void CheckIdentifier(const SymbolTable& symbols,
using T = std::decay_t<decltype(expected_arg)>; using T = std::decay_t<decltype(expected_arg)>;
if constexpr (traits::IsStringLike<T>) { if constexpr (traits::IsStringLike<T>) {
ASSERT_TRUE(got_arg->Is<IdentifierExpression>()); ASSERT_TRUE(got_arg->Is<IdentifierExpression>());
ast::CheckIdentifier(symbols, got_arg->As<IdentifierExpression>()->identifier, CheckIdentifier(symbols, got_arg->As<IdentifierExpression>()->identifier, expected_arg);
expected_arg);
} else if constexpr (IsTemplatedIdentifierMatcher<T>::value) { } else if constexpr (IsTemplatedIdentifierMatcher<T>::value) {
ASSERT_TRUE(got_arg->Is<IdentifierExpression>()); ASSERT_TRUE(got_arg->Is<IdentifierExpression>());
auto* got_ident = got_arg->As<IdentifierExpression>()->identifier; 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); 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 } // namespace tint::ast
#endif // SRC_TINT_AST_TEST_HELPER_H_ #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>()))) { PhonyExpression>()))) {
return true; // Leaf expression 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; return false;
}); });
if (!ok) { 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -13,22 +13,12 @@
// limitations under the License. // limitations under the License.
#include "src/tint/ast/type.h" #include "src/tint/ast/type.h"
#include "src/tint/ast/identifier_expression.h"
#include "src/tint/ast/alias.h" namespace tint {
#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"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Type); ProgramID ProgramIDOf(ast::Type type) {
return ProgramIDOf(type.expr);
}
namespace tint::ast { } // namespace tint
Type::Type(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
Type::Type(Type&&) = default;
Type::~Type() = default;
} // namespace tint::ast

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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -15,38 +15,38 @@
#ifndef SRC_TINT_AST_TYPE_H_ #ifndef SRC_TINT_AST_TYPE_H_
#define SRC_TINT_AST_TYPE_H_ #define SRC_TINT_AST_TYPE_H_
#include <string> #include "src/tint/program_id.h"
#include "src/tint/ast/node.h"
#include "src/tint/clone_context.h"
// Forward declarations // Forward declarations
namespace tint { namespace tint::ast {
class ProgramBuilder; class IdentifierExpression;
class SymbolTable; } // namespace tint::ast
} // namespace tint
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 /// Type is a thin wrapper around an IdentifierExpression, to help statically disambiguate known
/// @returns the name for this type that closely resembles how it would be /// type expressions from other expressions.
/// declared in WGSL. struct Type {
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0; /// The type expression
const IdentifierExpression* expr = nullptr;
protected: /// Indirection operator for accessing the type's expression
/// Constructor /// @return #expr
/// @param pid the identifier of the program that owns this node const IdentifierExpression* operator->() const { return expr; }
/// @param nid the unique node identifier
/// @param src the source of this node /// Implicit conversion operator to the type's expression
Type(ProgramID pid, NodeID nid, const Source& src); /// @return #expr
operator const IdentifierExpression*() const { return expr; }
}; };
} // namespace tint::ast } // 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_ #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, NodeID nid,
const Source& src, const Source& src,
const Identifier* n, const Identifier* n,
const ast::Type* ty, Type ty,
type::AddressSpace address_space, type::AddressSpace address_space,
type::Access access, type::Access access,
const Expression* init, const Expression* init,
@ -44,7 +44,7 @@ const char* Var::Kind() const {
const Var* Var::Clone(CloneContext* ctx) const { const Var* Var::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* n = ctx->Clone(name); auto* n = ctx->Clone(name);
auto* ty = ctx->Clone(type); auto ty = ctx->Clone(type);
auto* init = ctx->Clone(initializer); auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Var>(src, n, ty, declared_address_space, declared_access, init, 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, NodeID nid,
const Source& source, const Source& source,
const Identifier* name, const Identifier* name,
const ast::Type* type, Type type,
type::AddressSpace declared_address_space, type::AddressSpace declared_address_space,
type::Access declared_access, type::Access declared_access,
const Expression* initializer, const Expression* initializer,

View File

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

View File

@ -27,10 +27,9 @@ using VariableTest = TestHelper;
TEST_F(VariableTest, Creation) { TEST_F(VariableTest, Creation) {
auto* v = Var("my_var", ty.i32(), type::AddressSpace::kFunction); 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); EXPECT_EQ(v->declared_address_space, type::AddressSpace::kFunction);
ASSERT_TRUE(v->type->Is<ast::TypeName>()); CheckIdentifier(Symbols(), v->type, "i32");
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "i32");
EXPECT_EQ(v->source.range.begin.line, 0u); EXPECT_EQ(v->source.range.begin.line, 0u);
EXPECT_EQ(v->source.range.begin.column, 0u); EXPECT_EQ(v->source.range.begin.column, 0u);
EXPECT_EQ(v->source.range.end.line, 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", auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}, "i",
ty.f32(), type::AddressSpace::kPrivate, utils::Empty); 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); EXPECT_EQ(v->declared_address_space, type::AddressSpace::kPrivate);
ASSERT_TRUE(v->type->Is<ast::TypeName>()); CheckIdentifier(Symbols(), v->type, "f32");
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "f32");
EXPECT_EQ(v->source.range.begin.line, 27u); EXPECT_EQ(v->source.range.begin.line, 27u);
EXPECT_EQ(v->source.range.begin.column, 4u); EXPECT_EQ(v->source.range.begin.column, 4u);
EXPECT_EQ(v->source.range.end.line, 27u); 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", auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}, "a_var",
ty.i32(), type::AddressSpace::kWorkgroup, utils::Empty); 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); EXPECT_EQ(v->declared_address_space, type::AddressSpace::kWorkgroup);
ASSERT_TRUE(v->type->Is<ast::TypeName>()); CheckIdentifier(Symbols(), v->type, "i32");
EXPECT_EQ(Symbols().NameFor(v->type->As<ast::TypeName>()->name->symbol), "i32");
EXPECT_EQ(v->source.range.begin.line, 27u); EXPECT_EQ(v->source.range.begin.line, 27u);
EXPECT_EQ(v->source.range.begin.column, 4u); EXPECT_EQ(v->source.range.begin.column, 4u);
EXPECT_EQ(v->source.range.end.line, 27u); 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; return out;
} }
ast::Type CloneContext::Clone(const ast::Type& ty) {
return {Clone(ty.expr)};
}
const tint::Cloneable* CloneContext::CloneCloneable(const Cloneable* object) { const tint::Cloneable* CloneContext::CloneCloneable(const Cloneable* object) {
// If the input is nullptr, there's nothing to clone - just return nullptr. // If the input is nullptr, there's nothing to clone - just return nullptr.
if (object == nullptr) { if (object == nullptr) {

View File

@ -40,6 +40,7 @@ class ProgramBuilder;
namespace tint::ast { namespace tint::ast {
class FunctionList; class FunctionList;
class Node; class Node;
struct Type;
} // namespace tint::ast } // namespace tint::ast
namespace tint { namespace tint {
@ -142,6 +143,11 @@ class CloneContext {
return CheckedCast<T>(c); 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 /// Clones the Source `s` into #dst
/// TODO(bclayton) - Currently this 'clone' is a shallow copy. If/when /// 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 /// `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; ComponentType component;
CompositionType composition; CompositionType composition;
std::tie(component, composition) = GetParam(); 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) { if (component == ComponentType::kF16) {
Enable(ast::Extension::kF16); Enable(ast::Extension::kF16);
@ -1785,14 +1785,14 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MemberInfo{0, ty.i32()}, 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); AddResource("s_texture", s_texture_type, 2, 0);
AddSampler("s_var", 3, 0); AddSampler("s_var", 3, 0);
AddGlobalVariable("s_coords", ty.f32()); AddGlobalVariable("s_coords", ty.f32());
MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", ty.f32(), MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", ty.f32(),
utils::Empty); 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); AddResource("cs_texture", cs_depth_texture_type, 3, 1);
AddComparisonSampler("cs_var", 3, 2); AddComparisonSampler("cs_var", 3, 2);
AddGlobalVariable("cs_coords", ty.vec2<f32>()); AddGlobalVariable("cs_coords", ty.vec2<f32>());
@ -1800,14 +1800,14 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MakeComparisonSamplerReferenceBodyFunction("cs_func", "cs_texture", "cs_var", "cs_coords", MakeComparisonSamplerReferenceBodyFunction("cs_func", "cs_texture", "cs_var", "cs_coords",
"cs_depth", ty.f32(), utils::Empty); "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); AddResource("depth_ms_texture", depth_ms_texture_type, 3, 3);
Func("depth_ms_func", utils::Empty, ty.void_(), Func("depth_ms_func", utils::Empty, ty.void_(),
utils::Vector{ utils::Vector{
Ignore("depth_ms_texture"), Ignore("depth_ms_texture"),
}); });
auto* st_type = auto st_type =
MakeStorageTextureTypes(type::TextureDimension::k2d, type::TexelFormat::kR32Uint); MakeStorageTextureTypes(type::TextureDimension::k2d, type::TexelFormat::kR32Uint);
AddStorageTexture("st_var", st_type, 4, 0); AddStorageTexture("st_var", st_type, 4, 0);
MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<u32>(), utils::Empty); MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<u32>(), utils::Empty);
@ -2586,7 +2586,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) { 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); AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32()); AddGlobalVariable("foo_coords", ty.f32());
@ -2621,7 +2621,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) { 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); AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32()); AddGlobalVariable("foo_coords", ty.f32());
@ -2646,7 +2646,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) { 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); AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32()); AddGlobalVariable("foo_coords", ty.f32());
@ -2663,7 +2663,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) { 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); AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2684,7 +2684,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) { 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); AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2721,7 +2721,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) { 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); AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2747,7 +2747,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) { 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); AddResource("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2766,7 +2766,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) { 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); AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32()); AddGlobalVariable("foo_coords", ty.f32());
@ -2798,11 +2798,11 @@ TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
} }
TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) { TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
auto* sampled_texture_type = ast::Type sampled_texture_type =
ty.sampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); ty.sampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddResource("foo_texture", sampled_texture_type, 0, 0); AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); 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_coords", coord_type);
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
@ -2847,11 +2847,11 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kFloat})); inspector::ResourceBinding::SampledKind::kFloat}));
TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam, textureSample) { TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam, textureSample) {
auto* sampled_texture_type = ast::Type sampled_texture_type =
ty.sampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); ty.sampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddResource("foo_texture", sampled_texture_type, 0, 0); AddResource("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); 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_coords", coord_type);
AddGlobalVariable("foo_array_index", ty.i32()); AddGlobalVariable("foo_array_index", ty.i32());
@ -2886,10 +2886,10 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kFloat})); inspector::ResourceBinding::SampledKind::kFloat}));
TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam, textureLoad) { TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam, textureLoad) {
auto* multisampled_texture_type = ast::Type multisampled_texture_type =
ty.multisampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); ty.multisampled_texture(GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddResource("foo_texture", multisampled_texture_type, 0, 0); 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_coords", coord_type);
AddGlobalVariable("foo_sample_index", ty.i32()); AddGlobalVariable("foo_sample_index", ty.i32());
@ -2973,10 +2973,10 @@ TEST_P(InspectorGetStorageTextureResourceBindingsTestWithParam, Simple) {
ResourceBinding::SampledKind expected_kind; ResourceBinding::SampledKind expected_kind;
std::tie(format, expected_format, expected_kind) = format_params; 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); AddStorageTexture("st_var", st_type, 0, 0);
const ast::Type* dim_type = nullptr; ast::Type dim_type;
switch (dim) { switch (dim) {
case type::TextureDimension::k1d: case type::TextureDimension::k1d:
dim_type = ty.u32(); dim_type = ty.u32();
@ -3074,7 +3074,7 @@ INSTANTIATE_TEST_SUITE_P(
ResourceBinding::SampledKind::kFloat)))); ResourceBinding::SampledKind::kFloat))));
TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam, textureDimensions) { 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); AddResource("dt", depth_texture_type, 0, 0);
Func("ep", utils::Empty, ty.void_(), Func("ep", utils::Empty, ty.void_(),
@ -3111,7 +3111,7 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::TextureDimension::kCubeArray})); inspector::ResourceBinding::TextureDimension::kCubeArray}));
TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest, textureDimensions) { 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); AddResource("tex", depth_ms_texture_type, 0, 0);
Func("ep", utils::Empty, ty.void_(), Func("ep", utils::Empty, ty.void_(),
@ -3135,7 +3135,7 @@ TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest, textureDimensio
} }
TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) { 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); AddResource("et", external_texture_type, 0, 0);
Func("ep", utils::Empty, ty.void_(), 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( const ast::Function* InspectorBuilder::MakePlainGlobalReferenceBodyFunction(
std::string func, std::string func,
std::string var, std::string var,
const ast::Type* type, ast::Type type,
utils::VectorRef<const ast::Attribute*> attributes) { utils::VectorRef<const ast::Attribute*> attributes) {
utils::Vector<const ast::Statement*, 3> stmts; utils::Vector<const ast::Statement*, 3> stmts;
stmts.Push(Decl(Var("local_" + var, type))); stmts.Push(Decl(Var("local_" + var, type)));
@ -82,15 +82,14 @@ bool InspectorBuilder::ContainsName(utils::VectorRef<StageVariable> vec, const s
return false; return false;
} }
std::string InspectorBuilder::StructMemberName(size_t idx, const ast::Type* type) { std::string InspectorBuilder::StructMemberName(size_t idx, ast::Type type) {
return std::to_string(idx) + type->FriendlyName(Symbols()); return std::to_string(idx) + Symbols().NameFor(type->identifier->symbol);
} }
const ast::Struct* InspectorBuilder::MakeStructType( const ast::Struct* InspectorBuilder::MakeStructType(const std::string& name,
const std::string& name, utils::VectorRef<ast::Type> member_types) {
utils::VectorRef<const ast::Type*> member_types) {
utils::Vector<const ast::StructMember*, 8> members; utils::Vector<const ast::StructMember*, 8> members;
for (auto* type : member_types) { for (auto type : member_types) {
members.Push(MakeStructMember(members.Length(), type, {})); members.Push(MakeStructMember(members.Length(), type, {}));
} }
return MakeStructTypeFromMembers(name, std::move(members)); return MakeStructTypeFromMembers(name, std::move(members));
@ -104,37 +103,37 @@ const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(
const ast::StructMember* InspectorBuilder::MakeStructMember( const ast::StructMember* InspectorBuilder::MakeStructMember(
size_t index, size_t index,
const ast::Type* type, ast::Type type,
utils::VectorRef<const ast::Attribute*> attributes) { utils::VectorRef<const ast::Attribute*> attributes) {
return Member(StructMemberName(index, type), type, std::move(attributes)); return Member(StructMemberName(index, type), type, std::move(attributes));
} }
const ast::Struct* InspectorBuilder::MakeUniformBufferType( const ast::Struct* InspectorBuilder::MakeUniformBufferType(
const std::string& name, const std::string& name,
utils::VectorRef<const ast::Type*> member_types) { utils::VectorRef<ast::Type> member_types) {
return MakeStructType(name, member_types); return MakeStructType(name, member_types);
} }
std::function<const ast::TypeName*()> InspectorBuilder::MakeStorageBufferTypes( std::function<ast::Type()> InspectorBuilder::MakeStorageBufferTypes(
const std::string& name, const std::string& name,
utils::VectorRef<const ast::Type*> member_types) { utils::VectorRef<ast::Type> member_types) {
MakeStructType(name, member_types); MakeStructType(name, member_types);
return [this, name] { return ty(name); }; return [this, name] { return ty(name); };
} }
void InspectorBuilder::AddUniformBuffer(const std::string& name, void InspectorBuilder::AddUniformBuffer(const std::string& name,
const ast::Type* type, ast::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
GlobalVar(name, type, type::AddressSpace::kUniform, Binding(AInt(binding)), Group(AInt(group))); 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); GlobalVar(name, type, type::AddressSpace::kWorkgroup);
} }
void InspectorBuilder::AddStorageBuffer(const std::string& name, void InspectorBuilder::AddStorageBuffer(const std::string& name,
const ast::Type* type, ast::Type type,
type::Access access, type::Access access,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
@ -145,11 +144,11 @@ void InspectorBuilder::AddStorageBuffer(const std::string& name,
void InspectorBuilder::MakeStructVariableReferenceBodyFunction( void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
std::string func_name, std::string func_name,
std::string struct_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; utils::Vector<const ast::Statement*, 8> stmts;
for (auto member : members) { for (auto member : members) {
size_t member_idx; size_t member_idx;
const ast::Type* member_type; ast::Type member_type;
std::tie(member_idx, member_type) = member; std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type); std::string member_name = StructMemberName(member_idx, member_type);
@ -158,7 +157,7 @@ void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
for (auto member : members) { for (auto member : members) {
size_t member_idx; size_t member_idx;
const ast::Type* member_type; ast::Type member_type;
std::tie(member_idx, member_type) = member; std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type); 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, void InspectorBuilder::AddResource(const std::string& name,
const ast::Type* type, ast::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
GlobalVar(name, type, Binding(AInt(binding)), Group(AInt(group))); 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); GlobalVar(name, type, type::AddressSpace::kPrivate);
} }
@ -198,7 +197,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
const std::string& texture_name, const std::string& texture_name,
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const ast::Type* base_type, ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes) { utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
@ -216,7 +215,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const std::string& array_index, const std::string& array_index,
const ast::Type* base_type, ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes) { utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
@ -235,7 +234,7 @@ const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunctio
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const std::string& depth_name, const std::string& depth_name,
const ast::Type* base_type, ast::Type base_type,
utils::VectorRef<const ast::Attribute*> attributes) { utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result"; 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)); 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) { switch (sampled_kind) {
case ResourceBinding::SampledKind::kFloat: case ResourceBinding::SampledKind::kFloat:
return ty.f32(); return ty.f32();
@ -257,35 +256,34 @@ const ast::Type* InspectorBuilder::GetBaseType(ResourceBinding::SampledKind samp
case ResourceBinding::SampledKind::kUInt: case ResourceBinding::SampledKind::kUInt:
return ty.u32(); return ty.u32();
default: default:
return nullptr; return ast::Type{};
} }
} }
const ast::Type* InspectorBuilder::GetCoordsType(type::TextureDimension dim, ast::Type InspectorBuilder::GetCoordsType(type::TextureDimension dim, ast::Type scalar) {
const ast::Type* scalar) {
switch (dim) { switch (dim) {
case type::TextureDimension::k1d: case type::TextureDimension::k1d:
return scalar; return scalar;
case type::TextureDimension::k2d: case type::TextureDimension::k2d:
case type::TextureDimension::k2dArray: case type::TextureDimension::k2dArray:
return create<ast::Vector>(scalar, 2u); return ty.vec2(scalar);
case type::TextureDimension::k3d: case type::TextureDimension::k3d:
case type::TextureDimension::kCube: case type::TextureDimension::kCube:
case type::TextureDimension::kCubeArray: case type::TextureDimension::kCubeArray:
return create<ast::Vector>(scalar, 3u); return ty.vec3(scalar);
default: default:
[=]() { FAIL() << "Unsupported texture dimension: " << dim; }(); [=]() { 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) { type::TexelFormat format) {
return ty.storage_texture(dim, format, type::Access::kWrite); return ty.storage_texture(dim, format, type::Access::kWrite);
} }
void InspectorBuilder::AddStorageTexture(const std::string& name, void InspectorBuilder::AddStorageTexture(const std::string& name,
const ast::Type* type, ast::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
GlobalVar(name, type, Binding(AInt(binding)), Group(AInt(group))); 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 ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
const std::string& func_name, const std::string& func_name,
const std::string& st_name, const std::string& st_name,
const ast::Type* dim_type, ast::Type dim_type,
utils::VectorRef<const ast::Attribute*> attributes) { utils::VectorRef<const ast::Attribute*> attributes) {
utils::Vector stmts{ utils::Vector stmts{
Decl(Var("dim", dim_type)), 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)); 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) { CompositionType composition) {
std::function<const ast::Type*()> func; std::function<ast::Type()> func;
switch (component) { switch (component) {
case ComponentType::kF32: case ComponentType::kF32:
func = [this]() -> const ast::Type* { return ty.f32(); }; func = [this]() { return ty.f32(); };
break; break;
case ComponentType::kI32: case ComponentType::kI32:
func = [this]() -> const ast::Type* { return ty.i32(); }; func = [this]() { return ty.i32(); };
break; break;
case ComponentType::kU32: case ComponentType::kU32:
func = [this]() -> const ast::Type* { return ty.u32(); }; func = [this]() { return ty.u32(); };
break; break;
case ComponentType::kF16: case ComponentType::kF16:
func = [this]() -> const ast::Type* { return ty.f16(); }; func = [this]() { return ty.f16(); };
break; break;
case ComponentType::kUnknown: case ComponentType::kUnknown:
return []() -> const ast::Type* { return nullptr; }; return []() { return ast::Type{}; };
} }
uint32_t n; uint32_t n;
@ -339,10 +337,10 @@ std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(ComponentTyp
n = 4; n = 4;
break; break;
default: 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() { Inspector& InspectorBuilder::Build() {

View File

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

View File

@ -136,6 +136,15 @@ enum builtin_type {
i32 i32
u32 u32
// https://www.w3.org/TR/WGSL/#matrix-types // https://www.w3.org/TR/WGSL/#matrix-types
mat2x2
mat2x3
mat2x4
mat3x2
mat3x3
mat3x4
mat4x2
mat4x3
mat4x4
mat2x2f mat2x2f
mat2x2h mat2x2h
mat2x3f mat2x3f
@ -155,6 +164,9 @@ enum builtin_type {
mat4x4f mat4x4f
mat4x4h mat4x4h
// https://www.w3.org/TR/WGSL/#vector-types // https://www.w3.org/TR/WGSL/#vector-types
vec2
vec3
vec4
vec2f vec2f
vec2h vec2h
vec2i vec2i
@ -167,6 +179,12 @@ enum builtin_type {
vec4h vec4h
vec4i vec4i
vec4u 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 // https://www.w3.org/TR/WGSL/#sampler-type
sampler sampler
sampler_comparison sampler_comparison
@ -176,6 +194,15 @@ enum builtin_type {
texture_depth_cube texture_depth_cube
texture_depth_cube_array texture_depth_cube_array
texture_depth_multisampled_2d 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 // https://www.w3.org/TR/WGSL/#texture-storage
texture_storage_1d texture_storage_1d
texture_storage_2d texture_storage_2d

View File

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

View File

@ -18,6 +18,7 @@
#include "src/tint/demangler.h" #include "src/tint/demangler.h"
#include "src/tint/resolver/resolver.h" #include "src/tint/resolver/resolver.h"
#include "src/tint/sem/type_expression.h"
#include "src/tint/sem/value_expression.h" #include "src/tint/sem/value_expression.h"
namespace tint { namespace tint {
@ -118,21 +119,24 @@ bool Program::IsValid() const {
} }
const type::Type* Program::TypeOf(const ast::Expression* expr) const { const type::Type* Program::TypeOf(const ast::Expression* expr) const {
auto* sem = Sem().GetVal(expr); return tint::Switch(
return sem ? sem->Type() : nullptr; 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 { const type::Type* Program::TypeOf(const ast::Variable* var) const {
return Sem().Get(type); auto* sem = Sem().Get(var);
return sem ? sem->Type() : nullptr;
} }
const type::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const { const type::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const {
return Sem().Get(type_decl); 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()); 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 { std::string Program::FriendlyName(const type::Type* type) const {

View File

@ -138,11 +138,11 @@ class Program {
/// expression has no resolved type. /// expression has no resolved type.
const type::Type* TypeOf(const ast::Expression* expr) const; const type::Type* TypeOf(const ast::Expression* expr) const;
/// Helper for returning the resolved semantic type of the AST type `type`. /// Helper for returning the resolved semantic type of the variable `var`.
/// @param type the AST type /// @param var the AST variable
/// @return the resolved semantic type for the type, or nullptr if the type /// @return the resolved semantic type for the variable, or nullptr if the
/// has no resolved type. /// variable has no resolved type.
const type::Type* TypeOf(const ast::Type* type) const; const type::Type* TypeOf(const ast::Variable* var) const;
/// Helper for returning the resolved semantic type of the AST type /// Helper for returning the resolved semantic type of the AST type
/// declaration `type_decl`. /// declaration `type_decl`.
@ -152,13 +152,11 @@ class Program {
const type::Type* TypeOf(const ast::TypeDecl* type_decl) const; const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
/// @param type a type /// @param type a type
/// @returns the name for `type` that closely resembles how it would be /// @returns the name for `type` that closely resembles how it would be declared in WGSL.
/// declared in WGSL. std::string FriendlyName(ast::Type type) const;
std::string FriendlyName(const ast::Type* type) const;
/// @param type a type /// @param type a type
/// @returns the name for `type` that closely resembles how it would be /// @returns the name for `type` that closely resembles how it would be declared in WGSL.
/// declared in WGSL.
std::string FriendlyName(const type::Type* type) const; std::string FriendlyName(const type::Type* type) const;
/// Overload of FriendlyName, which removes an ambiguity when passing nullptr. /// 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/ast/variable_decl_statement.h"
#include "src/tint/debug.h" #include "src/tint/debug.h"
#include "src/tint/demangler.h" #include "src/tint/demangler.h"
#include "src/tint/sem/type_expression.h"
#include "src/tint/sem/value_expression.h" #include "src/tint/sem/value_expression.h"
#include "src/tint/sem/variable.h" #include "src/tint/sem/variable.h"
#include "src/tint/utils/compiler_macros.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 { const type::Type* ProgramBuilder::TypeOf(const ast::Expression* expr) const {
auto* sem = Sem().GetVal(expr); return tint::Switch(
return sem ? sem->Type() : nullptr; 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 { 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; 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 { const type::Type* ProgramBuilder::TypeOf(const ast::TypeDecl* type_decl) const {
return Sem().Get(type_decl); 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()); 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 { std::string ProgramBuilder::FriendlyName(const type::Type* type) const {
@ -127,10 +126,6 @@ std::string ProgramBuilder::FriendlyName(std::nullptr_t) const {
return "<null>"; 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) {} ProgramBuilder::TypesBuilder::TypesBuilder(ProgramBuilder* pb) : builder(pb) {}
const ast::Statement* ProgramBuilder::WrapInStatement(const ast::Expression* expr) { 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) { TEST_F(ProgramBuilderTest, WrapDoesntAffectInner) {
Program inner([] { Program inner([] {
ProgramBuilder builder; ProgramBuilder builder;
auto* ty = builder.ty.f32(); auto ty = builder.ty.f32();
builder.Func("a", {}, ty, {}, {}); builder.Func("a", {}, ty, {}, {});
return builder; return builder;
}()); }());
@ -54,7 +54,7 @@ TEST_F(ProgramBuilderTest, WrapDoesntAffectInner) {
EXPECT_FALSE(inner.Symbols().Get("b").IsValid()); EXPECT_FALSE(inner.Symbols().Get("b").IsValid());
EXPECT_FALSE(outer.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, {}, {}); outer.Func("b", {}, ty, {}, {});
ASSERT_EQ(inner.AST().Functions().Length(), 1u); ASSERT_EQ(inner.AST().Functions().Length(), 1u);

View File

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

View File

@ -546,7 +546,7 @@ TEST_F(SpvParserTest, ConvertType_StructTwoMembers) {
ASSERT_NE(type, nullptr); ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->Is<Struct>()); EXPECT_TRUE(type->Is<Struct>());
auto* str = type->Build(p->builder()); auto str = type->Build(p->builder());
Program program = p->program(); Program program = p->program();
EXPECT_EQ(test::ToString(program, str), "S"); EXPECT_EQ(test::ToString(program, str), "S");
} }
@ -564,7 +564,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
ASSERT_NE(type, nullptr); ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->Is<Struct>()); EXPECT_TRUE(type->Is<Struct>());
auto* str = type->Build(p->builder()); auto str = type->Build(p->builder());
Program program = p->program(); Program program = p->program();
EXPECT_EQ(test::ToString(program, str), "S"); EXPECT_EQ(test::ToString(program, str), "S");
} }
@ -586,7 +586,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
ASSERT_NE(type, nullptr); ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->Is<Struct>()); EXPECT_TRUE(type->Is<Struct>());
auto* str = type->Build(p->builder()); auto str = type->Build(p->builder());
Program program = p->program(); Program program = p->program();
EXPECT_EQ(test::ToString(program, str), "S"); 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(); 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); }, [&](const ast::Identifier* ident) { return program.Symbols().NameFor(ident->symbol); },
[&](Default) { [&](Default) {
return "<unhandled AST node type " + std::string(node->TypeInfo().name) + ">"; 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 //! @endcond
const ast::Type* Void::Build(ProgramBuilder& b) const { ast::Type Void::Build(ProgramBuilder& b) const {
return b.ty.void_(); return b.ty.void_();
} }
const ast::Type* Bool::Build(ProgramBuilder& b) const { ast::Type Bool::Build(ProgramBuilder& b) const {
return b.ty.bool_(); return b.ty.bool_();
} }
const ast::Type* U32::Build(ProgramBuilder& b) const { ast::Type U32::Build(ProgramBuilder& b) const {
return b.ty.u32(); return b.ty.u32();
} }
const ast::Type* F32::Build(ProgramBuilder& b) const { ast::Type F32::Build(ProgramBuilder& b) const {
return b.ty.f32(); return b.ty.f32();
} }
const ast::Type* I32::Build(ProgramBuilder& b) const { ast::Type I32::Build(ProgramBuilder& b) const {
return b.ty.i32(); 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) {} : type(t), address_space(s), access(a) {}
Pointer::Pointer(const Pointer&) = default; 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); auto store_type = type->Build(b);
if (!store_type) { if (!store_type) {
// TODO(crbug.com/tint/1838): We should not be constructing pointers with 'void' store // 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) {} : type(t), address_space(s), access(a) {}
Reference::Reference(const Reference&) = default; Reference::Reference(const Reference&) = default;
const ast::Type* Reference::Build(ProgramBuilder& b) const { ast::Type Reference::Build(ProgramBuilder& b) const {
return type->Build(b); return type->Build(b);
} }
Vector::Vector(const Type* t, uint32_t s) : type(t), size(s) {} Vector::Vector(const Type* t, uint32_t s) : type(t), size(s) {}
Vector::Vector(const Vector&) = default; 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); 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 Type* t, uint32_t c, uint32_t r) : type(t), columns(c), rows(r) {}
Matrix::Matrix(const Matrix&) = default; 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); 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 Type* t, uint32_t sz, uint32_t st) : type(t), size(sz), stride(st) {}
Array::Array(const Array&) = default; Array::Array(const Array&) = default;
const ast::Type* Array::Build(ProgramBuilder& b) const { ast::Type Array::Build(ProgramBuilder& b) const {
if (size > 0) { if (size > 0) {
if (stride > 0) { if (stride > 0) {
return b.ty.array(type->Build(b), u32(size), utils::Vector{b.Stride(stride)}); 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 { } else {
if (stride > 0) { 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 { } 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(type::SamplerKind k) : kind(k) {}
Sampler::Sampler(const Sampler&) = default; 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); return b.ty.sampler(kind);
} }
@ -243,14 +243,14 @@ Texture::Texture(const Texture&) = default;
DepthTexture::DepthTexture(type::TextureDimension d) : Base(d) {} DepthTexture::DepthTexture(type::TextureDimension d) : Base(d) {}
DepthTexture::DepthTexture(const DepthTexture&) = default; 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); return b.ty.depth_texture(dims);
} }
DepthMultisampledTexture::DepthMultisampledTexture(type::TextureDimension d) : Base(d) {} DepthMultisampledTexture::DepthMultisampledTexture(type::TextureDimension d) : Base(d) {}
DepthMultisampledTexture::DepthMultisampledTexture(const DepthMultisampledTexture&) = default; 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); return b.ty.depth_multisampled_texture(dims);
} }
@ -258,14 +258,14 @@ MultisampledTexture::MultisampledTexture(type::TextureDimension d, const Type* t
: Base(d), type(t) {} : Base(d), type(t) {}
MultisampledTexture::MultisampledTexture(const MultisampledTexture&) = default; 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)); return b.ty.multisampled_texture(dims, type->Build(b));
} }
SampledTexture::SampledTexture(type::TextureDimension d, const Type* t) : Base(d), type(t) {} SampledTexture::SampledTexture(type::TextureDimension d, const Type* t) : Base(d), type(t) {}
SampledTexture::SampledTexture(const SampledTexture&) = default; 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)); 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) {} : Base(d), format(f), access(a) {}
StorageTexture::StorageTexture(const StorageTexture&) = default; 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); 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(Symbol n, const Type* ty) : Base(n), type(ty) {}
Alias::Alias(const Alias&) = default; Alias::Alias(const Alias&) = default;
const ast::Type* Alias::Build(ProgramBuilder& b) const { ast::Type Alias::Build(ProgramBuilder& b) const {
return b.ty(name); 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(const Struct&) = default;
Struct::~Struct() = default; Struct::~Struct() = default;
const ast::Type* Struct::Build(ProgramBuilder& b) const { ast::Type Struct::Build(ProgramBuilder& b) const {
return b.ty(name); return b.ty(name);
} }

View File

@ -19,6 +19,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "src/tint/ast/type.h"
#include "src/tint/castable.h" #include "src/tint/castable.h"
#include "src/tint/symbol.h" #include "src/tint/symbol.h"
#include "src/tint/type/access.h" #include "src/tint/type/access.h"
@ -32,9 +33,6 @@
namespace tint { namespace tint {
class ProgramBuilder; class ProgramBuilder;
} // namespace tint } // namespace tint
namespace tint::ast {
class Type;
} // namespace tint::ast
namespace tint::reader::spirv { namespace tint::reader::spirv {
@ -50,7 +48,7 @@ class Type : public Castable<Type> {
/// @param b the ProgramBuilder used to construct the AST types /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 /// @returns the inner most store type if this is a pointer, `this` otherwise
const Type* UnwrapPtr() const; const Type* UnwrapPtr() const;
@ -102,7 +100,7 @@ using TypeList = std::vector<const Type*>;
struct Void final : public Castable<Void, Type> { struct Void final : public Castable<Void, Type> {
/// @param b the ProgramBuilder used to construct the AST types /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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> { struct Bool final : public Castable<Bool, Type> {
/// @param b the ProgramBuilder used to construct the AST types /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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> { struct U32 final : public Castable<U32, Type> {
/// @param b the ProgramBuilder used to construct the AST types /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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> { struct F32 final : public Castable<F32, Type> {
/// @param b the ProgramBuilder used to construct the AST types /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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> { struct I32 final : public Castable<I32, Type> {
/// @param b the ProgramBuilder used to construct the AST types /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 #ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only /// @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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 /// the aliased type
Type const* const 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 /// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type /// @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 /// the member types
const TypeList members; const TypeList members;

View File

@ -16,7 +16,6 @@
#include <limits> #include <limits>
#include "src/tint/ast/array.h"
#include "src/tint/ast/assignment_statement.h" #include "src/tint/ast/assignment_statement.h"
#include "src/tint/ast/bitcast_expression.h" #include "src/tint/ast/bitcast_expression.h"
#include "src/tint/ast/break_if_statement.h" #include "src/tint/ast/break_if_statement.h"
@ -32,10 +31,8 @@
#include "src/tint/ast/return_statement.h" #include "src/tint/ast/return_statement.h"
#include "src/tint/ast/stage_attribute.h" #include "src/tint/ast/stage_attribute.h"
#include "src/tint/ast/switch_statement.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/unary_op_expression.h"
#include "src/tint/ast/variable_decl_statement.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/ast/workgroup_attribute.h"
#include "src/tint/reader/wgsl/classify_template_args.h" #include "src/tint/reader/wgsl/classify_template_args.h"
#include "src/tint/reader/wgsl/lexer.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 TypedIdentifier&) = default;
ParserImpl::TypedIdentifier::TypedIdentifier(const ast::Type* type_in, ParserImpl::TypedIdentifier::TypedIdentifier(ast::Type type_in,
std::string name_in, std::string name_in,
Source source_in) Source source_in)
: type(type_in), name(std::move(name_in)), source(std::move(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, ParserImpl::FunctionHeader::FunctionHeader(Source src,
std::string n, std::string n,
utils::VectorRef<const ast::Parameter*> p, utils::VectorRef<const ast::Parameter*> p,
const ast::Type* ret_ty, ast::Type ret_ty,
utils::VectorRef<const ast::Attribute*> ret_attrs) utils::VectorRef<const ast::Attribute*> ret_attrs)
: source(src), : source(src),
name(n), name(n),
@ -215,7 +212,7 @@ ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
std::string name_in, std::string name_in,
type::AddressSpace address_space_in, type::AddressSpace address_space_in,
type::Access access_in, type::Access access_in,
const ast::Type* type_in) ast::Type type_in)
: source(std::move(source_in)), : source(std::move(source_in)),
name(std::move(name_in)), name(std::move(name_in)),
address_space(address_space_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 // | multisampled_texture_type LESS_THAN type_specifier GREATER_THAN
// | storage_texture_type LESS_THAN texel_format // | storage_texture_type LESS_THAN texel_format
// COMMA access_mode GREATER_THAN // 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(); auto type = sampler_type();
if (type.matched) { if (type.matched) {
return type; return type;
@ -811,7 +808,7 @@ Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
// sampler_type // sampler_type
// : SAMPLER // : SAMPLER
// | SAMPLER_COMPARISON // | SAMPLER_COMPARISON
Maybe<const ast::Type*> ParserImpl::sampler_type() { Maybe<ast::Type> ParserImpl::sampler_type() {
Source source; Source source;
if (match(Token::Type::kSampler, &source)) { if (match(Token::Type::kSampler, &source)) {
return builder_.ty.sampler(source, type::SamplerKind::kSampler); return builder_.ty.sampler(source, type::SamplerKind::kSampler);
@ -861,7 +858,7 @@ Maybe<const type::TextureDimension> ParserImpl::sampled_texture_type() {
// external_texture // external_texture
// : TEXTURE_EXTERNAL // : TEXTURE_EXTERNAL
Maybe<const ast::Type*> ParserImpl::external_texture() { Maybe<ast::Type> ParserImpl::external_texture() {
Source source; Source source;
if (match(Token::Type::kTextureExternal, &source)) { if (match(Token::Type::kTextureExternal, &source)) {
return builder_.ty.external_texture(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
// | TEXTURE_DEPTH_CUBE_ARRAY // | TEXTURE_DEPTH_CUBE_ARRAY
// | TEXTURE_DEPTH_MULTISAMPLED_2D // | TEXTURE_DEPTH_MULTISAMPLED_2D
Maybe<const ast::Type*> ParserImpl::depth_texture_type() { Maybe<ast::Type> ParserImpl::depth_texture_type() {
Source source; Source source;
if (match(Token::Type::kTextureDepth2d, &source)) { if (match(Token::Type::kTextureDepth2d, &source)) {
return builder_.ty.depth_texture(source, type::TextureDimension::k2d); 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)) { 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)) { if (!expect(use, Token::Type::kColon)) {
@ -1130,7 +1127,7 @@ Maybe<ParserImpl::MatrixDimensions> ParserImpl::mat_prefix() {
// | mat_prefix LESS_THAN type_specifier GREATER_THAN // | mat_prefix LESS_THAN type_specifier GREATER_THAN
// | vec_prefix LESS_THAN type_specifier GREATER_THAN // | vec_prefix LESS_THAN type_specifier GREATER_THAN
// | texture_and_sampler_types // | texture_and_sampler_types
Maybe<const ast::Type*> ParserImpl::type_specifier_without_ident() { Maybe<ast::Type> ParserImpl::type_specifier_without_ident() {
auto& t = peek(); auto& t = peek();
if (match(Token::Type::kBool)) { if (match(Token::Type::kBool)) {
@ -1198,7 +1195,7 @@ Maybe<const ast::Type*> ParserImpl::type_specifier_without_ident() {
// type_specifier // type_specifier
// : IDENTIFIER // : IDENTIFIER
// | type_specifier_without_ident // | type_specifier_without_ident
Maybe<const ast::Type*> ParserImpl::type_specifier() { Maybe<ast::Type> ParserImpl::type_specifier() {
auto& t = peek(); auto& t = peek();
Source source; Source source;
if (match(Token::Type::kIdentifier, &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()); 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(); auto type = type_specifier();
if (type.errored) { if (type.errored) {
return Failure::kErrored; 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 // 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"; const char* use = "ptr declaration";
auto address_space = type::AddressSpace::kNone; auto address_space = type::AddressSpace::kNone;
auto access = type::Access::kUndefined; 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); auto sc = expect_address_space(use);
if (sc.errored) { if (sc.errored) {
return Failure::kErrored; return Failure::kErrored;
@ -1296,7 +1293,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source&
} }
// LESS_THAN type_specifier GREATER_THAN // 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"; const char* use = "atomic declaration";
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); }); 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 // 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"; const char* use = "vector";
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); }); auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
if (ty.errored) { 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 // 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"; const char* use = "array declaration";
struct TypeAndSize { struct TypeAndSize {
const ast::Type* type = nullptr; ast::Type type;
const ast::Expression* size = nullptr; const ast::Expression* size = nullptr;
}; };
@ -1352,12 +1349,16 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_array(const Source& s
return Failure::kErrored; return Failure::kErrored;
} }
return builder_.ty.array(make_source_range_from(s), type_size->type, type_size->size); 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 // 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 MatrixDimensions& dims) {
const char* use = "matrix"; const char* use = "matrix";
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); }); auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
if (ty.errored) { if (ty.errored) {
@ -1542,7 +1543,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
} }
} }
const ast::Type* return_type = nullptr; ast::Type return_type;
AttributeList return_attributes; AttributeList return_attributes;
if (match(Token::Type::kArrow)) { if (match(Token::Type::kArrow)) {
@ -2417,10 +2418,7 @@ Maybe<const ast::CallStatement*> ParserImpl::func_call_statement() {
return builder_.CallStmt( return builder_.CallStmt(
t.source(), t.source(),
create<ast::CallExpression>( builder_.Call(t.source(), builder_.Expr(t.source(), t.to_str()), std::move(params.value)));
t.source(),
create<ast::Identifier>(t.source(), builder_.Symbols().Register(t.to_str())),
std::move(params.value)));
} }
// break_statement // 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 // 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 // doesn't create a `type`. Then we can just return a `type` from here on match and
// deal with `ident` in `primary_expression. // deal with `ident` in `primary_expression.
Maybe<const ast::Type*> ParserImpl::callable() { Maybe<const ast::IdentifierExpression*> ParserImpl::callable() {
auto& t = peek(); auto& t = peek();
// This _must_ match `type_specifier_without_ident` before any of the other types as they're // This _must_ match `type_specifier_without_ident` before any of the other types as they're
@ -2541,22 +2539,22 @@ Maybe<const ast::Type*> ParserImpl::callable() {
return Failure::kErrored; return Failure::kErrored;
} }
if (ty.matched) { if (ty.matched) {
return ty.value; return ty->expr;
} }
if (match(Token::Type::kArray)) { 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(); auto vec = vec_prefix();
if (vec.matched) { 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(); auto mat = mat_prefix();
if (mat.matched) { 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); mat.value.rows);
} }
return Failure::kNoMatch; return Failure::kNoMatch;

View File

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

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "src/tint/ast/call_statement.h" #include "src/tint/ast/call_statement.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h" #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl { namespace tint::reader::wgsl {
@ -34,7 +35,7 @@ TEST_F(ParserImplTest, Statement_Call) {
ASSERT_TRUE(e->Is<ast::CallStatement>()); ASSERT_TRUE(e->Is<ast::CallStatement>());
auto* c = e->As<ast::CallStatement>()->expr; 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); EXPECT_EQ(c->args.Length(), 0u);
} }
@ -50,7 +51,7 @@ TEST_F(ParserImplTest, Statement_Call_WithParams) {
ASSERT_TRUE(e->Is<ast::CallStatement>()); ASSERT_TRUE(e->Is<ast::CallStatement>());
auto* c = e->As<ast::CallStatement>()->expr; 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_EQ(c->args.Length(), 3u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>()); 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>()); ASSERT_TRUE(e->Is<ast::CallStatement>());
auto* c = e->As<ast::CallStatement>()->expr; 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_EQ(c->args.Length(), 2u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>()); EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());

View File

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

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h" #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/depth_texture.h" #include "src/tint/type/depth_texture.h"
#include "src/tint/type/texture_dimension.h" #include "src/tint/type/texture_dimension.h"
@ -33,9 +34,8 @@ TEST_F(ParserImplTest, DepthTextureType_2d) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_2d"); ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}})); 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_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_2d_array"); ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d_array");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 23u}})); 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_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_cube"); ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_cube");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}})); 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_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_cube_array"); ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_cube_array");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}})); 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_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(t.value->As<ast::TypeName>()->name->symbol),
"texture_depth_multisampled_2d"); ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_multisampled_2d");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 30u}})); 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/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/ast/diagnostic_control.h" #include "src/tint/ast/diagnostic_control.h"
#include "src/tint/ast/test_helper.h"
namespace tint::reader::wgsl { namespace tint::reader::wgsl {
namespace { namespace {
@ -29,7 +30,7 @@ TEST_F(ParserImplTest, DiagnosticAttribute_Valid) {
EXPECT_EQ(d->control.severity, ast::DiagnosticSeverity::kOff); EXPECT_EQ(d->control.severity, ast::DiagnosticSeverity::kOff);
auto* r = d->control.rule_name; auto* r = d->control.rule_name;
ASSERT_NE(r, nullptr); ASSERT_NE(r, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo"); ast::CheckIdentifier(p->builder().Symbols(), r, "foo");
} }
} // namespace } // namespace

View File

@ -15,6 +15,7 @@
#include "src/tint/reader/wgsl/parser_impl_test_helper.h" #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/ast/diagnostic_control.h" #include "src/tint/ast/diagnostic_control.h"
#include "src/tint/ast/test_helper.h"
namespace tint::reader::wgsl { namespace tint::reader::wgsl {
namespace { namespace {
@ -32,7 +33,7 @@ TEST_P(DiagnosticControlParserTest, DiagnosticControl_Valid) {
auto* r = e->rule_name; auto* r = e->rule_name;
ASSERT_NE(r, nullptr); 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, INSTANTIATE_TEST_SUITE_P(DiagnosticControlParserTest,
DiagnosticControlParserTest, DiagnosticControlParserTest,
@ -50,7 +51,7 @@ TEST_F(ParserImplTest, DiagnosticControl_Valid_TrailingComma) {
auto* r = e->rule_name; auto* r = e->rule_name;
ASSERT_NE(r, nullptr); 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) { TEST_F(ParserImplTest, DiagnosticControl_MissingOpenParen) {

View File

@ -15,6 +15,7 @@
#include "src/tint/reader/wgsl/parser_impl_test_helper.h" #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/ast/diagnostic_control.h" #include "src/tint/ast/diagnostic_control.h"
#include "src/tint/ast/test_helper.h"
namespace tint::reader::wgsl { namespace tint::reader::wgsl {
namespace { namespace {
@ -32,7 +33,7 @@ TEST_F(ParserImplTest, DiagnosticDirective_Valid) {
auto* r = directive->control.rule_name; auto* r = directive->control.rule_name;
ASSERT_NE(r, nullptr); 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) { TEST_F(ParserImplTest, DiagnosticDirective_MissingSemicolon) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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