ast: Add type nodes

Copy all of the type classes from src/type into ast.

Required the merging of:
* type::Struct into the existing ast::Struct - ast::Struct now has a name.
* type::AccessControl into the existing ast::AccessControl enumerator - The old ast::AccessControl enumerator is now ast::AccessControl::Access

Bug: tint:724
Change-Id: Ibb950036ed551ec769c6d3d2c8fb411809cf6931
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48383
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-04-20 15:04:21 +00:00 committed by Commit Bot service account
parent ba6f260629
commit 8a8d26bbd9
90 changed files with 4352 additions and 168 deletions

View File

@ -77,7 +77,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
for (auto* src_node : src.ASTNodes().Objects()) {
src_nodes.emplace(src_node);
}
std::unordered_set<tint::type::Type*> src_types;
std::unordered_set<tint::sem::Type*> src_types;
for (auto* src_type : src.Types()) {
src_types.emplace(src_type);
}

View File

@ -284,8 +284,12 @@ libtint_source_set("libtint_core_all_src") {
"ast/access_control.h",
"ast/access_decoration.cc",
"ast/access_decoration.h",
"ast/alias.cc",
"ast/alias.h",
"ast/array_accessor_expression.cc",
"ast/array_accessor_expression.h",
"ast/array.cc",
"ast/array.h",
"ast/assignment_statement.cc",
"ast/assignment_statement.h",
"ast/binary_expression.cc",
@ -298,12 +302,14 @@ libtint_source_set("libtint_core_all_src") {
"ast/block_statement.h",
"ast/bool_literal.cc",
"ast/bool_literal.h",
"ast/bool.cc",
"ast/bool.h",
"ast/break_statement.cc",
"ast/break_statement.h",
"ast/builtin.cc",
"ast/builtin.h",
"ast/builtin_decoration.cc",
"ast/builtin_decoration.h",
"ast/builtin.cc",
"ast/builtin.h",
"ast/call_expression.cc",
"ast/call_expression.h",
"ast/call_statement.cc",
@ -318,12 +324,16 @@ libtint_source_set("libtint_core_all_src") {
"ast/continue_statement.h",
"ast/decoration.cc",
"ast/decoration.h",
"ast/depth_texture.cc",
"ast/depth_texture.h",
"ast/discard_statement.cc",
"ast/discard_statement.h",
"ast/else_statement.cc",
"ast/else_statement.h",
"ast/expression.cc",
"ast/expression.h",
"ast/f32.cc",
"ast/f32.h",
"ast/fallthrough_statement.cc",
"ast/fallthrough_statement.h",
"ast/float_literal.cc",
@ -332,6 +342,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/function.h",
"ast/group_decoration.cc",
"ast/group_decoration.h",
"ast/i32.cc",
"ast/i32.h",
"ast/identifier_expression.cc",
"ast/identifier_expression.h",
"ast/if_statement.cc",
@ -346,16 +358,26 @@ libtint_source_set("libtint_core_all_src") {
"ast/location_decoration.h",
"ast/loop_statement.cc",
"ast/loop_statement.h",
"ast/matrix.cc",
"ast/matrix.h",
"ast/member_accessor_expression.cc",
"ast/member_accessor_expression.h",
"ast/module.cc",
"ast/module.h",
"ast/multisampled_texture.cc",
"ast/multisampled_texture.h",
"ast/node.cc",
"ast/node.h",
"ast/pipeline_stage.cc",
"ast/pipeline_stage.h",
"ast/pointer.cc",
"ast/pointer.h",
"ast/return_statement.cc",
"ast/return_statement.h",
"ast/sampled_texture.cc",
"ast/sampled_texture.h",
"ast/sampler.cc",
"ast/sampler.h",
"ast/scalar_constructor_expression.cc",
"ast/scalar_constructor_expression.h",
"ast/sint_literal.cc",
@ -366,34 +388,46 @@ libtint_source_set("libtint_core_all_src") {
"ast/statement.h",
"ast/storage_class.cc",
"ast/storage_class.h",
"ast/storage_texture.cc",
"ast/storage_texture.h",
"ast/stride_decoration.cc",
"ast/stride_decoration.h",
"ast/struct.cc",
"ast/struct.h",
"ast/struct_block_decoration.cc",
"ast/struct_block_decoration.h",
"ast/struct_member.cc",
"ast/struct_member.h",
"ast/struct_member_align_decoration.cc",
"ast/struct_member_align_decoration.h",
"ast/struct_member_offset_decoration.cc",
"ast/struct_member_offset_decoration.h",
"ast/struct_member_size_decoration.cc",
"ast/struct_member_size_decoration.h",
"ast/struct_member.cc",
"ast/struct_member.h",
"ast/struct.cc",
"ast/struct.h",
"ast/switch_statement.cc",
"ast/switch_statement.h",
"ast/texture.cc",
"ast/texture.h",
"ast/type_constructor_expression.cc",
"ast/type_constructor_expression.h",
"ast/ast_type.cc", # TODO(bclayton) - rename to type.cc
"ast/type.h",
"ast/u32.cc",
"ast/u32.h",
"ast/uint_literal.cc",
"ast/uint_literal.h",
"ast/unary_op.cc",
"ast/unary_op.h",
"ast/unary_op_expression.cc",
"ast/unary_op_expression.h",
"ast/variable.cc",
"ast/variable.h",
"ast/unary_op.cc",
"ast/unary_op.h",
"ast/variable_decl_statement.cc",
"ast/variable_decl_statement.h",
"ast/variable.cc",
"ast/variable.h",
"ast/vector.cc",
"ast/vector.h",
"ast/void.cc",
"ast/void.h",
"ast/workgroup_decoration.cc",
"ast/workgroup_decoration.h",
"block_allocator.h",
@ -419,12 +453,12 @@ libtint_source_set("libtint_core_all_src") {
"inspector/scalar.h",
"intrinsic_table.cc",
"intrinsic_table.h",
"program.cc",
"program.h",
"program_builder.cc",
"program_builder.h",
"program_id.cc",
"program_id.h",
"program.cc",
"program.h",
"reader/reader.cc",
"reader/reader.h",
"resolver/resolver.cc",
@ -474,10 +508,10 @@ libtint_source_set("libtint_core_all_src") {
"sem/void_type.h",
"source.cc",
"source.h",
"symbol.cc",
"symbol.h",
"symbol_table.cc",
"symbol_table.h",
"symbol.cc",
"symbol.h",
"traits.h",
"transform/binding_point.h",
"transform/binding_remapper.cc",
@ -510,10 +544,10 @@ libtint_source_set("libtint_core_all_src") {
"writer/append_vector.h",
"writer/float_to_string.cc",
"writer/float_to_string.h",
"writer/text.cc",
"writer/text.h",
"writer/text_generator.cc",
"writer/text_generator.h",
"writer/text.cc",
"writer/text.h",
"writer/writer.cc",
"writer/writer.h",
]

View File

@ -42,8 +42,12 @@ set(TINT_LIB_SRCS
ast/access_control.h
ast/access_decoration.cc
ast/access_decoration.h
ast/alias.cc
ast/alias.h
ast/array_accessor_expression.cc
ast/array_accessor_expression.h
ast/array.cc
ast/array.h
ast/assignment_statement.cc
ast/assignment_statement.h
ast/binary_expression.cc
@ -56,6 +60,8 @@ set(TINT_LIB_SRCS
ast/block_statement.h
ast/bool_literal.cc
ast/bool_literal.h
ast/bool.cc
ast/bool.h
ast/break_statement.cc
ast/break_statement.h
ast/builtin_decoration.cc
@ -76,12 +82,16 @@ set(TINT_LIB_SRCS
ast/continue_statement.h
ast/decoration.cc
ast/decoration.h
ast/depth_texture.cc
ast/depth_texture.h
ast/discard_statement.cc
ast/discard_statement.h
ast/else_statement.cc
ast/else_statement.h
ast/expression.cc
ast/expression.h
ast/f32.cc
ast/f32.h
ast/fallthrough_statement.cc
ast/fallthrough_statement.h
ast/float_literal.cc
@ -90,6 +100,8 @@ set(TINT_LIB_SRCS
ast/function.h
ast/group_decoration.cc
ast/group_decoration.h
ast/i32.cc
ast/i32.h
ast/identifier_expression.cc
ast/identifier_expression.h
ast/if_statement.cc
@ -104,16 +116,26 @@ set(TINT_LIB_SRCS
ast/location_decoration.h
ast/loop_statement.cc
ast/loop_statement.h
ast/matrix.cc
ast/matrix.h
ast/member_accessor_expression.cc
ast/member_accessor_expression.h
ast/module.cc
ast/module.h
ast/multisampled_texture.cc
ast/multisampled_texture.h
ast/node.cc
ast/node.h
ast/pipeline_stage.cc
ast/pipeline_stage.h
ast/pointer.cc
ast/pointer.h
ast/return_statement.cc
ast/return_statement.h
ast/sampled_texture.cc
ast/sampled_texture.h
ast/sampler.cc
ast/sampler.h
ast/scalar_constructor_expression.cc
ast/scalar_constructor_expression.h
ast/sint_literal.cc
@ -124,34 +146,46 @@ set(TINT_LIB_SRCS
ast/statement.h
ast/storage_class.cc
ast/storage_class.h
ast/storage_texture.cc
ast/storage_texture.h
ast/stride_decoration.cc
ast/stride_decoration.h
ast/struct.cc
ast/struct.h
ast/struct_block_decoration.cc
ast/struct_block_decoration.h
ast/struct_member.cc
ast/struct_member.h
ast/struct_member_align_decoration.cc
ast/struct_member_align_decoration.h
ast/struct_member_offset_decoration.cc
ast/struct_member_offset_decoration.h
ast/struct_member_size_decoration.cc
ast/struct_member_size_decoration.h
ast/struct_member.cc
ast/struct_member.h
ast/struct.cc
ast/struct.h
ast/switch_statement.cc
ast/switch_statement.h
ast/texture.cc
ast/texture.h
ast/type_constructor_expression.cc
ast/type_constructor_expression.h
ast/ast_type.cc # TODO(bclayton) - rename to type.cc
ast/type.h
ast/u32.cc
ast/u32.h
ast/uint_literal.cc
ast/uint_literal.h
ast/unary_op.cc
ast/unary_op.h
ast/unary_op_expression.cc
ast/unary_op_expression.h
ast/variable.cc
ast/variable.h
ast/unary_op.cc
ast/unary_op.h
ast/variable_decl_statement.cc
ast/variable_decl_statement.h
ast/variable.cc
ast/variable.h
ast/vector.cc
ast/vector.h
ast/void.cc
ast/void.h
ast/workgroup_decoration.cc
ast/workgroup_decoration.h
block_allocator.h
@ -163,8 +197,6 @@ set(TINT_LIB_SRCS
debug.h
demangler.cc
demangler.h
intrinsic_table.cc
intrinsic_table.h
diagnostic/diagnostic.cc
diagnostic/diagnostic.h
diagnostic/formatter.cc
@ -177,6 +209,8 @@ set(TINT_LIB_SRCS
inspector/inspector.h
inspector/scalar.cc
inspector/scalar.h
intrinsic_table.cc
intrinsic_table.h
program_builder.cc
program_builder.h
program_id.cc
@ -188,32 +222,32 @@ set(TINT_LIB_SRCS
resolver/resolver.cc
resolver/resolver.h
scope_stack.h
sem/array.h
sem/call.h
sem/call_target.h
sem/expression.h
sem/info.h
sem/intrinsic.h
sem/node.h
sem/array.cc
sem/call.cc
sem/array.h
sem/call_target.cc
sem/call_target.h
sem/call.cc
sem/call.h
sem/expression.cc
sem/member_accessor_expression.cc
sem/expression.h
sem/function.cc
sem/info.cc
sem/info.h
sem/intrinsic.cc
sem/intrinsic.h
sem/member_accessor_expression.cc
sem/node.cc
sem/node.h
sem/statement.cc
sem/struct.cc
sem/variable.cc
sem/type_mappings.h
sem/variable.cc
source.cc
source.h
symbol.cc
symbol.h
symbol_table.cc
symbol_table.h
symbol.cc
symbol.h
traits.h
transform/binding_point.h
transform/binding_remapper.cc
@ -288,10 +322,10 @@ set(TINT_LIB_SRCS
writer/append_vector.h
writer/float_to_string.cc
writer/float_to_string.h
writer/text.cc
writer/text.h
writer/text_generator.cc
writer/text_generator.h
writer/text.cc
writer/text.h
writer/writer.cc
writer/writer.h
)
@ -418,14 +452,18 @@ endif()
if(${TINT_BUILD_TESTS})
set(TINT_TEST_SRCS
ast/access_control_test.cc
ast/access_decoration_test.cc
ast/alias_test.cc
ast/array_accessor_expression_test.cc
ast/array_test.cc
ast/assignment_statement_test.cc
ast/binary_expression_test.cc
ast/binding_decoration_test.cc
ast/bitcast_expression_test.cc
ast/block_statement_test.cc
ast/bool_literal_test.cc
ast/bool_test.cc
ast/break_statement_test.cc
ast/builtin_decoration_test.cc
ast/call_expression_test.cc
@ -433,12 +471,15 @@ if(${TINT_BUILD_TESTS})
ast/case_statement_test.cc
ast/constant_id_decoration_test.cc
ast/continue_statement_test.cc
ast/depth_texture_test.cc
ast/discard_statement_test.cc
ast/else_statement_test.cc
ast/f32_test.cc
ast/fallthrough_statement_test.cc
ast/float_literal_test.cc
ast/function_test.cc
ast/group_decoration_test.cc
ast/i32_test.cc
ast/identifier_expression_test.cc
ast/if_statement_test.cc
ast/int_literal_test.cc
@ -446,13 +487,19 @@ if(${TINT_BUILD_TESTS})
ast/intrinsic_texture_helper_test.h
ast/location_decoration_test.cc
ast/loop_statement_test.cc
ast/matrix_test.cc
ast/member_accessor_expression_test.cc
ast/module_clone_test.cc
ast/module_test.cc
ast/multisampled_texture_test.cc
ast/pointer_test.cc
ast/return_statement_test.cc
ast/sampled_texture_test.cc
ast/sampler_test.cc
ast/scalar_constructor_expression_test.cc
ast/sint_literal_test.cc
ast/stage_decoration_test.cc
ast/storage_texture_test.cc
ast/stride_decoration_test.cc
ast/struct_member_align_decoration_test.cc
ast/struct_member_offset_decoration_test.cc
@ -461,11 +508,14 @@ if(${TINT_BUILD_TESTS})
ast/struct_test.cc
ast/switch_statement_test.cc
ast/test_helper.h
ast/texture_test.cc
ast/type_constructor_expression_test.cc
ast/u32_test.cc
ast/uint_literal_test.cc
ast/unary_op_expression_test.cc
ast/variable_decl_statement_test.cc
ast/variable_test.cc
ast/vector_test.cc
ast/workgroup_decoration_test.cc
block_allocator_test.cc
castable_test.cc
@ -501,7 +551,6 @@ if(${TINT_BUILD_TESTS})
sem/intrinsic_test.cc
symbol_table_test.cc
symbol_test.cc
traits_test.cc
test_main.cc
sem/access_control_type_test.cc
sem/alias_type_test.cc

View File

@ -14,10 +14,68 @@
#include "src/ast/access_control.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::AccessControl);
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, AccessControl access) {
AccessControl::AccessControl(ProgramID program_id,
const Source& source,
Access access,
Type* subtype)
: Base(program_id, source), access_(access), subtype_(subtype) {
TINT_ASSERT(subtype_);
TINT_ASSERT(!subtype_->Is<AccessControl>());
}
AccessControl::AccessControl(AccessControl&&) = default;
AccessControl::~AccessControl() = default;
std::string AccessControl::type_name() const {
std::string name = "__access_control_";
switch (access_) {
case ast::AccessControl::kReadOnly:
name += "read_only";
break;
case ast::AccessControl::kWriteOnly:
name += "write_only";
break;
case ast::AccessControl::kReadWrite:
name += "read_write";
break;
}
return name + subtype_->type_name();
}
std::string AccessControl::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "[[access(";
switch (access_) {
case ast::AccessControl::kReadOnly:
out << "read";
break;
case ast::AccessControl::kWriteOnly:
out << "write";
break;
case ast::AccessControl::kReadWrite:
out << "read_write";
break;
}
out << ")]] " << subtype_->FriendlyName(symbols);
return out.str();
}
AccessControl* AccessControl::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<AccessControl>(src, access_, ty);
}
std::ostream& operator<<(std::ostream& out, AccessControl::Access access) {
switch (access) {
case ast::AccessControl::kReadOnly: {
out << "read_only";

View File

@ -16,24 +16,73 @@
#define SRC_AST_ACCESS_CONTROL_H_
#include <ostream>
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// The access control settings
enum class AccessControl {
/// Read only
kReadOnly = 0,
/// Write only
kWriteOnly,
/// Read write
kReadWrite
/// An access control type. Holds an access setting and pointer to another type.
class AccessControl : public Castable<AccessControl, Type> {
public:
/// The access control settings
enum Access {
/// Read only
kReadOnly = 0,
/// Write only
kWriteOnly,
/// Read write
kReadWrite
};
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param access the access control setting
/// @param subtype the access controlled type
AccessControl(ProgramID program_id,
const Source& source,
Access access,
Type* subtype);
/// Move constructor
AccessControl(AccessControl&&);
~AccessControl() override;
/// @returns true if the access control is read only
bool IsReadOnly() const { return access_ == Access::kReadOnly; }
/// @returns true if the access control is write only
bool IsWriteOnly() const { return access_ == Access::kWriteOnly; }
/// @returns true if the access control is read/write
bool IsReadWrite() const { return access_ == Access::kReadWrite; }
/// @returns the access control value
Access access_control() const { return access_; }
/// @returns the subtype type
Type* type() const { return subtype_; }
/// @returns the name for this type
std::string type_name() const 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
AccessControl* Clone(CloneContext* ctx) const override;
private:
Access const access_;
Type* const subtype_;
};
/// @param out the std::ostream to write to
/// @param access the AccessControl
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, AccessControl access);
std::ostream& operator<<(std::ostream& out, AccessControl::Access access);
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,112 @@
// 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/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstAccessControlTest = TestHelper;
TEST_F(AstAccessControlTest, Create) {
auto* u32 = create<U32>();
auto* a = create<AccessControl>(AccessControl::kReadWrite, u32);
EXPECT_TRUE(a->IsReadWrite());
EXPECT_EQ(a->type(), u32);
}
TEST_F(AstAccessControlTest, Is) {
auto* i32 = create<I32>();
Type* ty = create<AccessControl>(AccessControl::kReadOnly, i32);
EXPECT_TRUE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstAccessControlTest, AccessRead) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kReadOnly, i32);
EXPECT_TRUE(ac->IsReadOnly());
EXPECT_FALSE(ac->IsWriteOnly());
EXPECT_FALSE(ac->IsReadWrite());
EXPECT_EQ(ac->type_name(), "__access_control_read_only__i32");
}
TEST_F(AstAccessControlTest, AccessWrite) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kWriteOnly, i32);
EXPECT_FALSE(ac->IsReadOnly());
EXPECT_TRUE(ac->IsWriteOnly());
EXPECT_FALSE(ac->IsReadWrite());
EXPECT_EQ(ac->type_name(), "__access_control_write_only__i32");
}
TEST_F(AstAccessControlTest, AccessReadWrite) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kReadWrite, i32);
EXPECT_FALSE(ac->IsReadOnly());
EXPECT_FALSE(ac->IsWriteOnly());
EXPECT_TRUE(ac->IsReadWrite());
EXPECT_EQ(ac->type_name(), "__access_control_read_write__i32");
}
TEST_F(AstAccessControlTest, FriendlyNameReadOnly) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kReadOnly, i32);
EXPECT_EQ(ac->FriendlyName(Symbols()), "[[access(read)]] i32");
}
TEST_F(AstAccessControlTest, FriendlyNameWriteOnly) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kWriteOnly, i32);
EXPECT_EQ(ac->FriendlyName(Symbols()), "[[access(write)]] i32");
}
TEST_F(AstAccessControlTest, FriendlyNameReadWrite) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kReadWrite, i32);
EXPECT_EQ(ac->FriendlyName(Symbols()), "[[access(read_write)]] i32");
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -23,7 +23,7 @@ namespace ast {
AccessDecoration::AccessDecoration(ProgramID program_id,
const Source& source,
AccessControl val)
AccessControl::Access val)
: Base(program_id, source), value_(val) {}
AccessDecoration::~AccessDecoration() = default;

View File

@ -30,11 +30,11 @@ class AccessDecoration : public Castable<AccessDecoration, Decoration> {
/// @param value the access value
AccessDecoration(ProgramID program_id,
const Source& source,
AccessControl value);
AccessControl::Access value);
~AccessDecoration() override;
/// @returns the access control value
AccessControl value() const { return value_; }
AccessControl::Access value() const { return value_; }
/// Outputs the decoration to the given stream
/// @param sem the semantic info for the program
@ -51,7 +51,7 @@ class AccessDecoration : public Castable<AccessDecoration, Decoration> {
AccessDecoration* Clone(CloneContext* ctx) const override;
private:
AccessControl const value_;
AccessControl::Access const value_;
};
} // namespace ast

53
src/ast/alias.cc Normal file
View File

@ -0,0 +1,53 @@
// 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/ast/alias.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Alias);
namespace tint {
namespace ast {
Alias::Alias(ProgramID program_id,
const Source& source,
const Symbol& sym,
Type* subtype)
: Base(program_id, source), symbol_(sym), subtype_(subtype) {
TINT_ASSERT(subtype_);
}
Alias::Alias(Alias&&) = default;
Alias::~Alias() = default;
std::string Alias::type_name() const {
return "__alias_" + symbol_.to_str() + subtype_->type_name();
}
std::string Alias::FriendlyName(const SymbolTable& symbols) const {
return symbols.NameFor(symbol_);
}
Alias* Alias::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto sym = ctx->Clone(symbol());
auto* ty = ctx->Clone(type());
return ctx->dst->create<Alias>(src, sym, ty);
}
} // namespace ast
} // namespace tint

68
src/ast/alias.h Normal file
View File

@ -0,0 +1,68 @@
// 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_AST_ALIAS_H_
#define SRC_AST_ALIAS_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A type alias type. Holds a name and pointer to another type.
class Alias : public Castable<Alias, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param sym the symbol for the alias
/// @param subtype the alias'd type
Alias(ProgramID program_id,
const Source& source,
const Symbol& sym,
Type* subtype);
/// Move constructor
Alias(Alias&&);
/// Destructor
~Alias() override;
/// @returns the alias symbol
Symbol symbol() const { return symbol_; }
/// @returns the alias type
Type* type() const { return subtype_; }
/// @returns the type_name for this type
std::string type_name() const 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
Alias* Clone(CloneContext* ctx) const override;
private:
Symbol const symbol_;
Type* const subtype_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_ALIAS_H_

170
src/ast/alias_test.cc Normal file
View File

@ -0,0 +1,170 @@
// 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/ast/alias.h"
#include "src/ast/access_control.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstAliasTest = TestHelper;
TEST_F(AstAliasTest, Create) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
EXPECT_EQ(a->symbol(), Symbol(1, ID()));
EXPECT_EQ(a->type(), u32);
}
TEST_F(AstAliasTest, Is) {
Type* ty = create<Alias>(Sym("a"), create<I32>());
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_TRUE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstAliasTest, TypeName) {
auto* at = create<Alias>(Sym("Particle"), create<I32>());
EXPECT_EQ(at->type_name(), "__alias_$1__i32");
}
TEST_F(AstAliasTest, FriendlyName) {
auto* at = create<Alias>(Sym("Particle"), create<I32>());
EXPECT_EQ(at->FriendlyName(Symbols()), "Particle");
}
TEST_F(AstAliasTest, UnwrapIfNeeded_Alias) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
EXPECT_EQ(a->symbol(), Symbol(1, ID()));
EXPECT_EQ(a->type(), u32);
EXPECT_EQ(a->UnwrapIfNeeded(), u32);
EXPECT_EQ(u32->UnwrapIfNeeded(), u32);
}
TEST_F(AstAliasTest, UnwrapIfNeeded_AccessControl) {
auto* u32 = create<U32>();
auto* ac = create<AccessControl>(AccessControl::kReadOnly, u32);
EXPECT_EQ(ac->type(), u32);
EXPECT_EQ(ac->UnwrapIfNeeded(), u32);
}
TEST_F(AstAliasTest, UnwrapIfNeeded_MultiLevel) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
auto* aa = create<Alias>(Sym("aa_type"), a);
EXPECT_EQ(aa->symbol(), Symbol(2, ID()));
EXPECT_EQ(aa->type(), a);
EXPECT_EQ(aa->UnwrapIfNeeded(), u32);
}
TEST_F(AstAliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
auto* ac = create<AccessControl>(AccessControl::kReadWrite, a);
EXPECT_EQ(ac->type(), a);
EXPECT_EQ(ac->UnwrapIfNeeded(), u32);
}
TEST_F(AstAliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
auto* aa = create<Alias>(Sym("aa_type"), a);
auto* paa = create<Pointer>(aa, StorageClass::kUniform);
auto* apaa = create<Alias>(Sym("paa_type"), paa);
auto* aapaa = create<Alias>(Sym("aapaa_type"), apaa);
EXPECT_EQ(aapaa->symbol(), Symbol(4, ID()));
EXPECT_EQ(aapaa->type(), apaa);
EXPECT_EQ(aapaa->UnwrapAll(), u32);
}
TEST_F(AstAliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
auto* aa = create<Alias>(Sym("aa_type"), a);
auto* paa = create<Pointer>(aa, StorageClass::kUniform);
auto* ppaa = create<Pointer>(paa, StorageClass::kUniform);
auto* appaa = create<Alias>(Sym("appaa_type"), ppaa);
EXPECT_EQ(appaa->UnwrapAll(), paa);
}
TEST_F(AstAliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym("a_type"), u32);
auto* aa = create<Alias>(Sym("aa_type"), a);
auto* paa = create<Pointer>(aa, StorageClass::kUniform);
auto* apaa = create<Alias>(Sym("apaa_type"), paa);
auto* aapaa = create<Alias>(Sym("aapaa_type"), apaa);
auto* paapaa = create<Pointer>(aapaa, StorageClass::kUniform);
auto* apaapaa = create<Alias>(Sym("apaapaa_type"), paapaa);
EXPECT_EQ(apaapaa->UnwrapAll(), paa);
}
TEST_F(AstAliasTest, UnwrapAll_AccessControlPointer) {
auto* u32 = create<U32>();
auto* a = create<AccessControl>(AccessControl::kReadOnly, u32);
auto* pa = create<Pointer>(a, StorageClass::kUniform);
EXPECT_EQ(pa->type(), a);
EXPECT_EQ(pa->UnwrapAll(), u32);
}
TEST_F(AstAliasTest, UnwrapAll_PointerAccessControl) {
auto* u32 = create<U32>();
auto* p = create<Pointer>(u32, StorageClass::kUniform);
auto* a = create<AccessControl>(AccessControl::kReadOnly, p);
EXPECT_EQ(a->type(), p);
EXPECT_EQ(a->UnwrapAll(), u32);
}
TEST_F(AstAliasTest, UnwrapAliasIfNeeded) {
auto* f32 = create<F32>();
auto* alias1 = create<Alias>(Sym("alias1"), f32);
auto* alias2 = create<Alias>(Sym("alias2"), alias1);
auto* alias3 = create<Alias>(Sym("alias3"), alias2);
EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), f32);
}
} // namespace
} // namespace ast
} // namespace tint

80
src/ast/array.cc Normal file
View File

@ -0,0 +1,80 @@
// 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/ast/array.h"
#include <cmath>
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Array);
namespace tint {
namespace ast {
Array::Array(ProgramID program_id,
const Source& source,
Type* subtype,
uint32_t size,
ast::DecorationList decorations)
: Base(program_id, source),
subtype_(subtype),
size_(size),
decos_(decorations) {}
Array::Array(Array&&) = default;
Array::~Array() = default;
std::string Array::type_name() const {
TINT_ASSERT(subtype_);
std::string type_name = "__array" + subtype_->type_name();
if (!IsRuntimeArray()) {
type_name += "_" + std::to_string(size_);
}
for (auto* deco : decos_) {
if (auto* stride = deco->As<ast::StrideDecoration>()) {
type_name += "_stride_" + std::to_string(stride->stride());
}
}
return type_name;
}
std::string Array::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
for (auto* deco : decos_) {
if (auto* stride = deco->As<ast::StrideDecoration>()) {
out << "[[stride(" << stride->stride() << ")]] ";
}
}
out << "array<" << subtype_->FriendlyName(symbols);
if (!IsRuntimeArray()) {
out << ", " << size_;
}
out << ">";
return out.str();
}
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 decos = ctx->Clone(decorations());
return ctx->dst->create<Array>(src, ty, size_, decos);
}
} // namespace ast
} // namespace tint

79
src/ast/array.h Normal file
View File

@ -0,0 +1,79 @@
// 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_AST_ARRAY_H_
#define SRC_AST_ARRAY_H_
#include <string>
#include "src/ast/decoration.h"
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// An array type. If size is zero then it is a runtime array.
class Array : public Castable<Array, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param subtype the type of the array elements
/// @param size the number of elements in the array. `0` represents a
/// runtime-sized array.
/// @param decorations the array decorations
Array(ProgramID program_id,
const Source& source,
Type* subtype,
uint32_t size,
ast::DecorationList decorations);
/// 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 size_ == 0; }
/// @returns the array decorations
const ast::DecorationList& decorations() const { return decos_; }
/// @returns the array type
Type* type() const { return subtype_; }
/// @returns the array size. Size is 0 for a runtime array
uint32_t size() const { return size_; }
/// @returns the name for the type
std::string type_name() const 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
Array* Clone(CloneContext* ctx) const override;
private:
Type* const subtype_;
uint32_t const size_;
ast::DecorationList const decos_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_ARRAY_H_

112
src/ast/array_test.cc Normal file
View File

@ -0,0 +1,112 @@
// 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/ast/array.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstArrayTest = TestHelper;
TEST_F(AstArrayTest, CreateSizedArray) {
auto* u32 = create<U32>();
auto* arr = create<Array>(u32, 3, DecorationList{});
EXPECT_EQ(arr->type(), u32);
EXPECT_EQ(arr->size(), 3u);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_FALSE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, CreateRuntimeArray) {
auto* u32 = create<U32>();
auto* arr = create<Array>(u32, 0, DecorationList{});
EXPECT_EQ(arr->type(), u32);
EXPECT_EQ(arr->size(), 0u);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_TRUE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, Is) {
auto* i32 = create<I32>();
Type* ty = create<Array>(i32, 3, DecorationList{});
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_TRUE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstArrayTest, TypeName) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, 0, DecorationList{});
EXPECT_EQ(arr->type_name(), "__array__i32");
}
TEST_F(AstArrayTest, FriendlyNameRuntimeSized) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, 0, DecorationList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
}
TEST_F(AstArrayTest, FriendlyNameStaticSized) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, 5, DecorationList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
}
TEST_F(AstArrayTest, FriendlyNameWithStride) {
auto* i32 = create<I32>();
auto* arr =
create<Array>(i32, 5, DecorationList{create<StrideDecoration>(32)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "[[stride(32)]] array<i32, 5>");
}
TEST_F(AstArrayTest, TypeName_RuntimeArray) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, 3, DecorationList{});
EXPECT_EQ(arr->type_name(), "__array__i32_3");
}
TEST_F(AstArrayTest, TypeName_WithStride) {
auto* i32 = create<I32>();
auto* arr =
create<Array>(i32, 3, DecorationList{create<StrideDecoration>(16)});
EXPECT_EQ(arr->type_name(), "__array__i32_3_stride_16");
}
} // namespace
} // namespace ast
} // namespace tint

142
src/ast/ast_type.cc Normal file
View File

@ -0,0 +1,142 @@
// 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/ast/type.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Type);
namespace tint {
namespace ast {
Type::Type(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
Type::Type(Type&&) = default;
Type::~Type() = default;
Type* Type::UnwrapPtrIfNeeded() {
if (auto* ptr = As<Pointer>()) {
return ptr->type();
}
return this;
}
Type* Type::UnwrapAliasIfNeeded() {
Type* unwrapped = this;
while (auto* ptr = unwrapped->As<Alias>()) {
unwrapped = ptr->type();
}
return unwrapped;
}
Type* Type::UnwrapIfNeeded() {
auto* where = this;
while (true) {
if (auto* alias = where->As<Alias>()) {
where = alias->type();
} else if (auto* access = where->As<AccessControl>()) {
where = access->type();
} else {
break;
}
}
return where;
}
Type* Type::UnwrapAll() {
return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
}
bool Type::is_scalar() const {
return IsAnyOf<F32, U32, I32, Bool>();
}
bool Type::is_float_scalar() const {
return Is<F32>();
}
bool Type::is_float_matrix() const {
return Is<Matrix>(
[](const Matrix* m) { return m->type()->is_float_scalar(); });
}
bool Type::is_float_vector() const {
return Is<Vector>(
[](const Vector* v) { return v->type()->is_float_scalar(); });
}
bool Type::is_float_scalar_or_vector() const {
return is_float_scalar() || is_float_vector();
}
bool Type::is_float_scalar_or_vector_or_matrix() const {
return is_float_scalar() || is_float_vector() || is_float_matrix();
}
bool Type::is_integer_scalar() const {
return IsAnyOf<U32, I32>();
}
bool Type::is_unsigned_integer_vector() const {
return Is<Vector>([](const Vector* v) { return v->type()->Is<U32>(); });
}
bool Type::is_signed_integer_vector() const {
return Is<Vector>([](const Vector* v) { return v->type()->Is<I32>(); });
}
bool Type::is_unsigned_scalar_or_vector() const {
return Is<U32>() || is_unsigned_integer_vector();
}
bool Type::is_signed_scalar_or_vector() const {
return Is<I32>() || is_signed_integer_vector();
}
bool Type::is_integer_scalar_or_vector() const {
return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector();
}
bool Type::is_bool_vector() const {
return Is<Vector>([](const Vector* v) { return v->type()->Is<Bool>(); });
}
bool Type::is_bool_scalar_or_vector() const {
return Is<Bool>() || is_bool_vector();
}
bool Type::is_handle() const {
return IsAnyOf<Sampler, Texture>();
}
void Type::to_str(const sem::Info&, std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << type_name();
}
} // namespace ast
} // namespace tint

45
src/ast/bool.cc Normal file
View File

@ -0,0 +1,45 @@
// 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/ast/bool.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Bool);
namespace tint {
namespace ast {
Bool::Bool(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
Bool::Bool(Bool&&) = default;
Bool::~Bool() = default;
std::string Bool::type_name() const {
return "__bool";
}
std::string Bool::FriendlyName(const SymbolTable&) const {
return "bool";
}
Bool* Bool::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<Bool>(src);
}
} // namespace ast
} // namespace tint

59
src/ast/bool.h Normal file
View File

@ -0,0 +1,59 @@
// 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_AST_BOOL_H_
#define SRC_AST_BOOL_H_
#include <string>
#include "src/ast/type.h"
// X11 likes to #define Bool leading to confusing error messages.
// If its defined, undefine it.
#ifdef Bool
#undef Bool
#endif
namespace tint {
namespace ast {
/// A boolean type
class Bool : public Castable<Bool, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
Bool(ProgramID program_id, const Source& source);
/// Move constructor
Bool(Bool&&);
~Bool() override;
/// @returns the name for this type
std::string type_name() const 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
Bool* Clone(CloneContext* ctx) const override;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_BOOL_H_

65
src/ast/bool_test.cc Normal file
View File

@ -0,0 +1,65 @@
// 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/ast/bool.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstBoolTest = TestHelper;
TEST_F(AstBoolTest, Is) {
Type* ty = create<Bool>();
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_TRUE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstBoolTest, TypeName) {
auto* b = create<Bool>();
EXPECT_EQ(b->type_name(), "__bool");
}
TEST_F(AstBoolTest, FriendlyName) {
auto* b = create<Bool>();
EXPECT_EQ(b->FriendlyName(Symbols()), "bool");
}
} // namespace
} // namespace ast
} // namespace tint

61
src/ast/depth_texture.cc Normal file
View File

@ -0,0 +1,61 @@
// 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/ast/depth_texture.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::DepthTexture);
namespace tint {
namespace ast {
namespace {
bool IsValidDepthDimension(TextureDimension dim) {
return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
}
} // namespace
DepthTexture::DepthTexture(ProgramID program_id,
const Source& source,
TextureDimension dim)
: Base(program_id, source, dim) {
TINT_ASSERT(IsValidDepthDimension(dim));
}
DepthTexture::DepthTexture(DepthTexture&&) = default;
DepthTexture::~DepthTexture() = default;
std::string DepthTexture::type_name() const {
std::ostringstream out;
out << "__depth_texture_" << dim();
return out.str();
}
std::string DepthTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_depth_" << dim();
return out.str();
}
DepthTexture* DepthTexture::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<DepthTexture>(src, dim());
}
} // namespace ast
} // namespace tint

56
src/ast/depth_texture.h Normal file
View File

@ -0,0 +1,56 @@
// 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_AST_DEPTH_TEXTURE_H_
#define SRC_AST_DEPTH_TEXTURE_H_
#include <string>
#include "src/ast/texture.h"
namespace tint {
namespace ast {
/// A depth texture type.
class DepthTexture : public Castable<DepthTexture, Texture> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param dim the dimensionality of the texture
DepthTexture(ProgramID program_id,
const Source& source,
TextureDimension dim);
/// Move constructor
DepthTexture(DepthTexture&&);
~DepthTexture() override;
/// @returns the name for this type
std::string type_name() const 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
DepthTexture* Clone(CloneContext* ctx) const override;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_DEPTH_TEXTURE_H_

View File

@ -0,0 +1,80 @@
// 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/ast/depth_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h"
#include "src/ast/storage_texture.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstDepthTextureTest = TestHelper;
TEST_F(AstDepthTextureTest, Is) {
Type* ty = create<DepthTexture>(TextureDimension::kCube);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_TRUE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstDepthTextureTest, IsTexture) {
Texture* ty = create<DepthTexture>(TextureDimension::kCube);
EXPECT_TRUE(ty->Is<DepthTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
}
TEST_F(AstDepthTextureTest, Dim) {
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->dim(), TextureDimension::kCube);
}
TEST_F(AstDepthTextureTest, TypeName) {
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->type_name(), "__depth_texture_cube");
}
TEST_F(AstDepthTextureTest, FriendlyName) {
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_cube");
}
} // namespace
} // namespace ast
} // namespace tint

45
src/ast/f32.cc Normal file
View File

@ -0,0 +1,45 @@
// 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/ast/f32.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::F32);
namespace tint {
namespace ast {
F32::F32(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
F32::F32(F32&&) = default;
F32::~F32() = default;
std::string F32::type_name() const {
return "__f32";
}
std::string F32::FriendlyName(const SymbolTable&) const {
return "f32";
}
F32* F32::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<F32>(src);
}
} // namespace ast
} // namespace tint

53
src/ast/f32.h Normal file
View File

@ -0,0 +1,53 @@
// 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_AST_F32_H_
#define SRC_AST_F32_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A float 32 type
class F32 : public Castable<F32, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
F32(ProgramID program_id, const Source& source);
/// Move constructor
F32(F32&&);
~F32() override;
/// @returns the name for this type
std::string type_name() const 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
F32* Clone(CloneContext* ctx) const override;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_F32_H_

65
src/ast/f32_test.cc Normal file
View File

@ -0,0 +1,65 @@
// 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/ast/f32.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstF32Test = TestHelper;
TEST_F(AstF32Test, Is) {
Type* ty = create<F32>();
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_TRUE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstF32Test, TypeName) {
auto* f = create<F32>();
EXPECT_EQ(f->type_name(), "__f32");
}
TEST_F(AstF32Test, FriendlyName) {
auto* f = create<F32>();
EXPECT_EQ(f->FriendlyName(Symbols()), "f32");
}
} // namespace
} // namespace ast
} // namespace tint

45
src/ast/i32.cc Normal file
View File

@ -0,0 +1,45 @@
// 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/ast/i32.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::I32);
namespace tint {
namespace ast {
I32::I32(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
I32::I32(I32&&) = default;
I32::~I32() = default;
std::string I32::type_name() const {
return "__i32";
}
std::string I32::FriendlyName(const SymbolTable&) const {
return "i32";
}
I32* I32::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<I32>(src);
}
} // namespace ast
} // namespace tint

53
src/ast/i32.h Normal file
View File

@ -0,0 +1,53 @@
// 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_AST_I32_H_
#define SRC_AST_I32_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A signed int 32 type.
class I32 : public Castable<I32, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
I32(ProgramID program_id, const Source& source);
/// Move constructor
I32(I32&&);
~I32() override;
/// @returns the name for this type
std::string type_name() const 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
I32* Clone(CloneContext* ctx) const override;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_I32_H_

66
src/ast/i32_test.cc Normal file
View File

@ -0,0 +1,66 @@
// 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/ast/i32.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstI32Test = TestHelper;
TEST_F(AstI32Test, Is) {
Type* ty = create<I32>();
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_TRUE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstI32Test, TypeName) {
auto* i = create<I32>();
EXPECT_EQ(i->type_name(), "__i32");
}
TEST_F(AstI32Test, FriendlyName) {
auto* i = create<I32>();
EXPECT_EQ(i->FriendlyName(Symbols()), "i32");
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -63,7 +63,7 @@ TextureOverloadCase::TextureOverloadCase(
TextureOverloadCase::TextureOverloadCase(
ValidTextureOverload o,
const char* d,
AccessControl access,
AccessControl::Access access,
sem::ImageFormat i,
sem::TextureDimension dims,
TextureDataType datatype,

View File

@ -198,7 +198,7 @@ struct TextureOverloadCase {
/// Constructor for textureLoad() with storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
AccessControl,
AccessControl::Access,
sem::ImageFormat,
sem::TextureDimension,
TextureDataType,
@ -236,7 +236,7 @@ struct TextureOverloadCase {
sem::SamplerKind const sampler_kind = sem::SamplerKind::kSampler;
/// The access control for the storage texture
/// Used only when texture_kind is kStorage
AccessControl const access_control = AccessControl::kReadWrite;
AccessControl::Access const access_control = AccessControl::kReadWrite;
/// The image format for the storage texture
/// Used only when texture_kind is kStorage
sem::ImageFormat const image_format = sem::ImageFormat::kNone;

63
src/ast/matrix.cc Normal file
View File

@ -0,0 +1,63 @@
// 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/ast/matrix.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Matrix);
namespace tint {
namespace ast {
Matrix::Matrix(ProgramID program_id,
const Source& source,
Type* subtype,
uint32_t rows,
uint32_t columns)
: Base(program_id, source),
subtype_(subtype),
rows_(rows),
columns_(columns) {
TINT_ASSERT(rows > 1);
TINT_ASSERT(rows < 5);
TINT_ASSERT(columns > 1);
TINT_ASSERT(columns < 5);
}
Matrix::Matrix(Matrix&&) = default;
Matrix::~Matrix() = default;
std::string Matrix::type_name() const {
return "__mat_" + std::to_string(rows_) + "_" + std::to_string(columns_) +
subtype_->type_name();
}
std::string Matrix::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "mat" << columns_ << "x" << rows_ << "<"
<< subtype_->FriendlyName(symbols) << ">";
return out.str();
}
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 ast
} // namespace tint

72
src/ast/matrix.h Normal file
View File

@ -0,0 +1,72 @@
// 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_AST_MATRIX_H_
#define SRC_AST_MATRIX_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A matrix type
class Matrix : public Castable<Matrix, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param subtype type matrix type
/// @param rows the number of rows in the matrix
/// @param columns the number of columns in the matrix
Matrix(ProgramID program_id,
const Source& source,
Type* subtype,
uint32_t rows,
uint32_t columns);
/// Move constructor
Matrix(Matrix&&);
~Matrix() override;
/// @returns the type of the matrix
Type* type() const { return subtype_; }
/// @returns the number of rows in the matrix
uint32_t rows() const { return rows_; }
/// @returns the number of columns in the matrix
uint32_t columns() const { return columns_; }
/// @returns the name for this type
std::string type_name() const 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
Matrix* Clone(CloneContext* ctx) const override;
private:
Type* const subtype_;
uint32_t const rows_;
uint32_t const columns_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_MATRIX_H_

76
src/ast/matrix_test.cc Normal file
View File

@ -0,0 +1,76 @@
// 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/ast/matrix.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstMatrixTest = TestHelper;
TEST_F(AstMatrixTest, Creation) {
auto* i32 = create<I32>();
auto* m = create<Matrix>(i32, 2, 4);
EXPECT_EQ(m->type(), i32);
EXPECT_EQ(m->rows(), 2u);
EXPECT_EQ(m->columns(), 4u);
}
TEST_F(AstMatrixTest, Is) {
auto* i32 = create<I32>();
Type* ty = create<Matrix>(i32, 2, 3);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_TRUE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstMatrixTest, TypeName) {
auto* i32 = create<I32>();
auto* m = create<Matrix>(i32, 2, 3);
EXPECT_EQ(m->type_name(), "__mat_2_3__i32");
}
TEST_F(AstMatrixTest, FriendlyName) {
auto* i32 = create<I32>();
auto* m = create<Matrix>(i32, 3, 2);
EXPECT_EQ(m->FriendlyName(Symbols()), "mat2x3<i32>");
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -89,7 +89,6 @@ void Module::to_str(const sem::Info& sem,
str->impl()->to_str(sem, out, indent);
}
} else if (auto* str = ty->As<sem::StructType>()) {
out << str->symbol().to_str() << " ";
str->impl()->to_str(sem, out, indent);
}
}

View File

@ -0,0 +1,58 @@
// 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/ast/multisampled_texture.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::MultisampledTexture);
namespace tint {
namespace ast {
MultisampledTexture::MultisampledTexture(ProgramID program_id,
const Source& source,
TextureDimension dim,
Type* type)
: Base(program_id, source, dim), type_(type) {
TINT_ASSERT(type_);
}
MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;
MultisampledTexture::~MultisampledTexture() = default;
std::string MultisampledTexture::type_name() const {
std::ostringstream out;
out << "__multisampled_texture_" << dim() << type_->type_name();
return out.str();
}
std::string MultisampledTexture::FriendlyName(
const SymbolTable& symbols) const {
std::ostringstream out;
out << "texture_multisampled_" << dim() << "<" << type_->FriendlyName(symbols)
<< ">";
return out.str();
}
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 ast
} // namespace tint

View File

@ -0,0 +1,64 @@
// 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_AST_MULTISAMPLED_TEXTURE_H_
#define SRC_AST_MULTISAMPLED_TEXTURE_H_
#include <string>
#include "src/ast/texture.h"
namespace tint {
namespace ast {
/// A multisampled texture type.
class MultisampledTexture : public Castable<MultisampledTexture, Texture> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param dim the dimensionality of the texture
/// @param type the data type of the multisampled texture
MultisampledTexture(ProgramID program_id,
const Source& source,
TextureDimension dim,
Type* type);
/// Move constructor
MultisampledTexture(MultisampledTexture&&);
~MultisampledTexture() override;
/// @returns the subtype of the sampled texture
Type* type() const { return type_; }
/// @returns the name for this type
std::string type_name() const 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
MultisampledTexture* Clone(CloneContext* ctx) const override;
private:
Type* const type_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_MULTISAMPLED_TEXTURE_H_

View File

@ -0,0 +1,94 @@
// 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/ast/multisampled_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h"
#include "src/ast/storage_texture.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstMultisampledTextureTest = TestHelper;
TEST_F(AstMultisampledTextureTest, Is) {
auto* f32 = create<F32>();
Type* ty = create<MultisampledTexture>(TextureDimension::kCube, f32);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_TRUE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstMultisampledTextureTest, IsTexture) {
auto* f32 = create<F32>();
Texture* ty = create<MultisampledTexture>(TextureDimension::kCube, f32);
EXPECT_FALSE(ty->Is<DepthTexture>());
EXPECT_TRUE(ty->Is<MultisampledTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
}
TEST_F(AstMultisampledTextureTest, Dim) {
auto* f32 = create<F32>();
auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->dim(), TextureDimension::k3d);
}
TEST_F(AstMultisampledTextureTest, Type) {
auto* f32 = create<F32>();
auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->type(), f32);
}
TEST_F(AstMultisampledTextureTest, TypeName) {
auto* f32 = create<F32>();
auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->type_name(), "__multisampled_texture_3d__f32");
}
TEST_F(AstMultisampledTextureTest, FriendlyName) {
auto* f32 = create<F32>();
auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->FriendlyName(Symbols()), "texture_multisampled_3d<f32>");
}
} // namespace
} // namespace ast
} // namespace tint

60
src/ast/pointer.cc Normal file
View File

@ -0,0 +1,60 @@
// 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/ast/pointer.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Pointer);
namespace tint {
namespace ast {
Pointer::Pointer(ProgramID program_id,
const Source& source,
Type* subtype,
ast::StorageClass storage_class)
: Base(program_id, source),
subtype_(subtype),
storage_class_(storage_class) {}
std::string Pointer::type_name() const {
std::ostringstream out;
out << "__ptr_" << storage_class_ << subtype_->type_name();
return out.str();
}
std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "ptr<";
if (storage_class_ != ast::StorageClass::kNone) {
out << storage_class_ << ", ";
}
out << subtype_->FriendlyName(symbols) << ">";
return out.str();
}
Pointer::Pointer(Pointer&&) = default;
Pointer::~Pointer() = default;
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, storage_class_);
}
} // namespace ast
} // namespace tint

68
src/ast/pointer.h Normal file
View File

@ -0,0 +1,68 @@
// 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_AST_POINTER_H_
#define SRC_AST_POINTER_H_
#include <string>
#include "src/ast/storage_class.h"
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A pointer type.
class Pointer : public Castable<Pointer, Type> {
public:
/// Construtor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param subtype the pointee type
/// @param storage_class the storage class of the pointer
Pointer(ProgramID program_id,
const Source& source,
Type* subtype,
ast::StorageClass storage_class);
/// Move constructor
Pointer(Pointer&&);
~Pointer() override;
/// @returns the pointee type
Type* type() const { return subtype_; }
/// @returns the storage class of the pointer
ast::StorageClass storage_class() const { return storage_class_; }
/// @returns the name for this type
std::string type_name() const 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
Pointer* Clone(CloneContext* ctx) const override;
private:
Type* const subtype_;
ast::StorageClass const storage_class_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_POINTER_H_

81
src/ast/pointer_test.cc Normal file
View File

@ -0,0 +1,81 @@
// 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/ast/pointer.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstPointerTest = TestHelper;
TEST_F(AstPointerTest, Creation) {
auto* i32 = create<I32>();
auto* p = create<Pointer>(i32, ast::StorageClass::kStorage);
EXPECT_EQ(p->type(), i32);
EXPECT_EQ(p->storage_class(), ast::StorageClass::kStorage);
}
TEST_F(AstPointerTest, Is) {
auto* i32 = create<I32>();
Type* ty = create<Pointer>(i32, ast::StorageClass::kFunction);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_TRUE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstPointerTest, TypeName) {
auto* i32 = create<I32>();
auto* p = create<Pointer>(i32, ast::StorageClass::kWorkgroup);
EXPECT_EQ(p->type_name(), "__ptr_workgroup__i32");
}
TEST_F(AstPointerTest, FriendlyNameWithStorageClass) {
auto* i32 = create<I32>();
auto* p = create<Pointer>(i32, ast::StorageClass::kWorkgroup);
EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<workgroup, i32>");
}
TEST_F(AstPointerTest, FriendlyNameWithoutStorageClass) {
auto* i32 = create<I32>();
auto* p = create<Pointer>(i32, ast::StorageClass::kNone);
EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<i32>");
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,56 @@
// 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/ast/sampled_texture.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::SampledTexture);
namespace tint {
namespace ast {
SampledTexture::SampledTexture(ProgramID program_id,
const Source& source,
TextureDimension dim,
Type* type)
: Base(program_id, source, dim), type_(type) {
TINT_ASSERT(type_);
}
SampledTexture::SampledTexture(SampledTexture&&) = default;
SampledTexture::~SampledTexture() = default;
std::string SampledTexture::type_name() const {
std::ostringstream out;
out << "__sampled_texture_" << dim() << type_->type_name();
return out.str();
}
std::string SampledTexture::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "texture_" << dim() << "<" << type_->FriendlyName(symbols) << ">";
return out.str();
}
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 ast
} // namespace tint

64
src/ast/sampled_texture.h Normal file
View File

@ -0,0 +1,64 @@
// 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_AST_SAMPLED_TEXTURE_H_
#define SRC_AST_SAMPLED_TEXTURE_H_
#include <string>
#include "src/ast/texture.h"
namespace tint {
namespace ast {
/// A sampled texture type.
class SampledTexture : public Castable<SampledTexture, Texture> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param dim the dimensionality of the texture
/// @param type the data type of the sampled texture
SampledTexture(ProgramID program_id,
const Source& source,
TextureDimension dim,
Type* type);
/// Move constructor
SampledTexture(SampledTexture&&);
~SampledTexture() override;
/// @returns the subtype of the sampled texture
Type* type() const { return type_; }
/// @returns the name for this type
std::string type_name() const 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
SampledTexture* Clone(CloneContext* ctx) const override;
private:
Type* const type_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_SAMPLED_TEXTURE_H_

View File

@ -0,0 +1,92 @@
// 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/ast/sampled_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/storage_texture.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstSampledTextureTest = TestHelper;
TEST_F(AstSampledTextureTest, Is) {
auto* f32 = create<F32>();
Type* ty = create<SampledTexture>(TextureDimension::kCube, f32);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_TRUE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstSampledTextureTest, IsTexture) {
auto* f32 = create<F32>();
Texture* ty = create<SampledTexture>(TextureDimension::kCube, f32);
EXPECT_FALSE(ty->Is<DepthTexture>());
EXPECT_TRUE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
}
TEST_F(AstSampledTextureTest, Dim) {
auto* f32 = create<F32>();
auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->dim(), TextureDimension::k3d);
}
TEST_F(AstSampledTextureTest, Type) {
auto* f32 = create<F32>();
auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->type(), f32);
}
TEST_F(AstSampledTextureTest, TypeName) {
auto* f32 = create<F32>();
auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->type_name(), "__sampled_texture_3d__f32");
}
TEST_F(AstSampledTextureTest, FriendlyName) {
auto* f32 = create<F32>();
auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
EXPECT_EQ(s->FriendlyName(Symbols()), "texture_3d<f32>");
}
} // namespace
} // namespace ast
} // namespace tint

58
src/ast/sampler.cc Normal file
View File

@ -0,0 +1,58 @@
// 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/ast/sampler.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Sampler);
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, SamplerKind kind) {
switch (kind) {
case SamplerKind::kSampler:
out << "sampler";
break;
case SamplerKind::kComparisonSampler:
out << "comparison_sampler";
break;
}
return out;
}
Sampler::Sampler(ProgramID program_id, const Source& source, SamplerKind kind)
: Base(program_id, source), kind_(kind) {}
Sampler::Sampler(Sampler&&) = default;
Sampler::~Sampler() = default;
std::string Sampler::type_name() const {
return std::string("__sampler_") +
(kind_ == SamplerKind::kSampler ? "sampler" : "comparison");
}
std::string Sampler::FriendlyName(const SymbolTable&) const {
return kind_ == SamplerKind::kSampler ? "sampler" : "sampler_comparison";
}
Sampler* Sampler::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<Sampler>(src, kind_);
}
} // namespace ast
} // namespace tint

76
src/ast/sampler.h Normal file
View File

@ -0,0 +1,76 @@
// 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_AST_SAMPLER_H_
#define SRC_AST_SAMPLER_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// The different kinds of samplers
enum class SamplerKind {
/// A regular sampler
kSampler,
/// A comparison sampler
kComparisonSampler
};
/// @param out the std::ostream to write to
/// @param kind the SamplerKind
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, SamplerKind kind);
/// A sampler type.
class Sampler : public Castable<Sampler, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param kind the kind of sampler
Sampler(ProgramID program_id, const Source& source, SamplerKind kind);
/// Move constructor
Sampler(Sampler&&);
~Sampler() override;
/// @returns the sampler type
SamplerKind kind() const { return kind_; }
/// @returns true if this is a comparison sampler
bool IsComparison() const { return kind_ == SamplerKind::kComparisonSampler; }
/// @returns the name for this type
std::string type_name() const 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
Sampler* Clone(CloneContext* ctx) const override;
private:
SamplerKind const kind_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_SAMPLER_H_

86
src/ast/sampler_test.cc Normal file
View File

@ -0,0 +1,86 @@
// 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/ast/sampler.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstSamplerTest = TestHelper;
TEST_F(AstSamplerTest, Creation) {
auto* s = create<Sampler>(SamplerKind::kSampler);
EXPECT_EQ(s->kind(), SamplerKind::kSampler);
}
TEST_F(AstSamplerTest, Creation_ComparisonSampler) {
auto* s = create<Sampler>(SamplerKind::kComparisonSampler);
EXPECT_EQ(s->kind(), SamplerKind::kComparisonSampler);
EXPECT_TRUE(s->IsComparison());
}
TEST_F(AstSamplerTest, Is) {
Type* ty = create<Sampler>(SamplerKind::kSampler);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_TRUE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstSamplerTest, TypeName_Sampler) {
auto* s = create<Sampler>(SamplerKind::kSampler);
EXPECT_EQ(s->type_name(), "__sampler_sampler");
}
TEST_F(AstSamplerTest, TypeName_Comparison) {
auto* s = create<Sampler>(SamplerKind::kComparisonSampler);
EXPECT_EQ(s->type_name(), "__sampler_comparison");
}
TEST_F(AstSamplerTest, FriendlyNameSampler) {
auto* s = create<Sampler>(SamplerKind::kSampler);
EXPECT_EQ(s->FriendlyName(Symbols()), "sampler");
}
TEST_F(AstSamplerTest, FriendlyNameComparisonSampler) {
auto* s = create<Sampler>(SamplerKind::kComparisonSampler);
EXPECT_EQ(s->FriendlyName(Symbols()), "sampler_comparison");
}
} // namespace
} // namespace ast
} // namespace tint

227
src/ast/storage_texture.cc Normal file
View File

@ -0,0 +1,227 @@
// 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/ast/storage_texture.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/u32.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StorageTexture);
namespace tint {
namespace ast {
// Note, these names match the names in the WGSL spec. This behaviour is used
// in the WGSL writer to emit the texture format names.
std::ostream& operator<<(std::ostream& out, ImageFormat format) {
switch (format) {
case ImageFormat::kNone:
out << "none";
break;
case ImageFormat::kR8Unorm:
out << "r8unorm";
break;
case ImageFormat::kR8Snorm:
out << "r8snorm";
break;
case ImageFormat::kR8Uint:
out << "r8uint";
break;
case ImageFormat::kR8Sint:
out << "r8sint";
break;
case ImageFormat::kR16Uint:
out << "r16uint";
break;
case ImageFormat::kR16Sint:
out << "r16sint";
break;
case ImageFormat::kR16Float:
out << "r16float";
break;
case ImageFormat::kRg8Unorm:
out << "rg8unorm";
break;
case ImageFormat::kRg8Snorm:
out << "rg8snorm";
break;
case ImageFormat::kRg8Uint:
out << "rg8uint";
break;
case ImageFormat::kRg8Sint:
out << "rg8sint";
break;
case ImageFormat::kR32Uint:
out << "r32uint";
break;
case ImageFormat::kR32Sint:
out << "r32sint";
break;
case ImageFormat::kR32Float:
out << "r32float";
break;
case ImageFormat::kRg16Uint:
out << "rg16uint";
break;
case ImageFormat::kRg16Sint:
out << "rg16sint";
break;
case ImageFormat::kRg16Float:
out << "rg16float";
break;
case ImageFormat::kRgba8Unorm:
out << "rgba8unorm";
break;
case ImageFormat::kRgba8UnormSrgb:
out << "rgba8unorm_srgb";
break;
case ImageFormat::kRgba8Snorm:
out << "rgba8snorm";
break;
case ImageFormat::kRgba8Uint:
out << "rgba8uint";
break;
case ImageFormat::kRgba8Sint:
out << "rgba8sint";
break;
case ImageFormat::kBgra8Unorm:
out << "bgra8unorm";
break;
case ImageFormat::kBgra8UnormSrgb:
out << "bgra8unorm_srgb";
break;
case ImageFormat::kRgb10A2Unorm:
out << "rgb10a2unorm";
break;
case ImageFormat::kRg11B10Float:
out << "rg11b10float";
break;
case ImageFormat::kRg32Uint:
out << "rg32uint";
break;
case ImageFormat::kRg32Sint:
out << "rg32sint";
break;
case ImageFormat::kRg32Float:
out << "rg32float";
break;
case ImageFormat::kRgba16Uint:
out << "rgba16uint";
break;
case ImageFormat::kRgba16Sint:
out << "rgba16sint";
break;
case ImageFormat::kRgba16Float:
out << "rgba16float";
break;
case ImageFormat::kRgba32Uint:
out << "rgba32uint";
break;
case ImageFormat::kRgba32Sint:
out << "rgba32sint";
break;
case ImageFormat::kRgba32Float:
out << "rgba32float";
break;
}
return out;
}
StorageTexture::StorageTexture(ProgramID program_id,
const Source& source,
TextureDimension dim,
ImageFormat format,
Type* subtype)
: Base(program_id, source, dim), image_format_(format), subtype_(subtype) {}
StorageTexture::StorageTexture(StorageTexture&&) = default;
StorageTexture::~StorageTexture() = default;
std::string StorageTexture::type_name() const {
std::ostringstream out;
out << "__storage_texture_" << dim() << "_" << image_format_;
return out.str();
}
std::string StorageTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_storage_" << dim() << "<" << image_format_ << ">";
return out.str();
}
StorageTexture* StorageTexture::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<StorageTexture>(src, dim(), image_format_, ty);
}
Type* StorageTexture::SubtypeFor(ImageFormat format, ProgramBuilder& builder) {
switch (format) {
case ImageFormat::kR8Uint:
case ImageFormat::kR16Uint:
case ImageFormat::kRg8Uint:
case ImageFormat::kR32Uint:
case ImageFormat::kRg16Uint:
case ImageFormat::kRgba8Uint:
case ImageFormat::kRg32Uint:
case ImageFormat::kRgba16Uint:
case ImageFormat::kRgba32Uint: {
return builder.create<U32>();
}
case ImageFormat::kR8Sint:
case ImageFormat::kR16Sint:
case ImageFormat::kRg8Sint:
case ImageFormat::kR32Sint:
case ImageFormat::kRg16Sint:
case ImageFormat::kRgba8Sint:
case ImageFormat::kRg32Sint:
case ImageFormat::kRgba16Sint:
case ImageFormat::kRgba32Sint: {
return builder.create<I32>();
}
case ImageFormat::kR8Unorm:
case ImageFormat::kRg8Unorm:
case ImageFormat::kRgba8Unorm:
case ImageFormat::kRgba8UnormSrgb:
case ImageFormat::kBgra8Unorm:
case ImageFormat::kBgra8UnormSrgb:
case ImageFormat::kRgb10A2Unorm:
case ImageFormat::kR8Snorm:
case ImageFormat::kRg8Snorm:
case ImageFormat::kRgba8Snorm:
case ImageFormat::kR16Float:
case ImageFormat::kR32Float:
case ImageFormat::kRg16Float:
case ImageFormat::kRg11B10Float:
case ImageFormat::kRg32Float:
case ImageFormat::kRgba16Float:
case ImageFormat::kRgba32Float: {
return builder.create<F32>();
}
case ImageFormat::kNone:
break;
}
return nullptr;
}
} // namespace ast
} // namespace tint

123
src/ast/storage_texture.h Normal file
View File

@ -0,0 +1,123 @@
// 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_AST_STORAGE_TEXTURE_H_
#define SRC_AST_STORAGE_TEXTURE_H_
#include <string>
#include "src/ast/texture.h"
namespace tint {
namespace ast {
class Manager;
/// The image format in the storage texture
enum class ImageFormat {
kNone = -1,
kR8Unorm,
kR8Snorm,
kR8Uint,
kR8Sint,
kR16Uint,
kR16Sint,
kR16Float,
kRg8Unorm,
kRg8Snorm,
kRg8Uint,
kRg8Sint,
kR32Uint,
kR32Sint,
kR32Float,
kRg16Uint,
kRg16Sint,
kRg16Float,
kRgba8Unorm,
kRgba8UnormSrgb,
kRgba8Snorm,
kRgba8Uint,
kRgba8Sint,
kBgra8Unorm,
kBgra8UnormSrgb,
kRgb10A2Unorm,
kRg11B10Float,
kRg32Uint,
kRg32Sint,
kRg32Float,
kRgba16Uint,
kRgba16Sint,
kRgba16Float,
kRgba32Uint,
kRgba32Sint,
kRgba32Float,
};
/// @param out the std::ostream to write to
/// @param format the ImageFormat
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, ImageFormat format);
/// A storage texture type.
class StorageTexture : public Castable<StorageTexture, Texture> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param dim the dimensionality of the texture
/// @param format the image format of the texture
/// @param subtype the storage subtype. Use SubtypeFor() to calculate this.
StorageTexture(ProgramID program_id,
const Source& source,
TextureDimension dim,
ImageFormat format,
Type* subtype);
/// Move constructor
StorageTexture(StorageTexture&&);
~StorageTexture() override;
/// @returns the storage subtype
Type* type() const { return subtype_; }
/// @returns the image format
ImageFormat image_format() const { return image_format_; }
/// @returns the name for this type
std::string type_name() const 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
StorageTexture* Clone(CloneContext* ctx) const override;
/// @param format the storage texture image format
/// @param builder the ProgramBuilder used to build the returned type
/// @returns the storage texture subtype for the given ImageFormat
static Type* SubtypeFor(ImageFormat format, ProgramBuilder& builder);
private:
ImageFormat const image_format_;
Type* const subtype_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_STORAGE_TEXTURE_H_

View File

@ -0,0 +1,128 @@
// 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/ast/storage_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstStorageTextureTest = TestHelper;
TEST_F(AstStorageTextureTest, Is) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
Type* ty = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_TRUE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstStorageTextureTest, IsTexture) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
Texture* ty = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
EXPECT_FALSE(ty->Is<DepthTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_TRUE(ty->Is<StorageTexture>());
}
TEST_F(AstStorageTextureTest, Dim) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
EXPECT_EQ(s->dim(), TextureDimension::k2dArray);
}
TEST_F(AstStorageTextureTest, Format) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
EXPECT_EQ(s->image_format(), ImageFormat::kRgba32Float);
}
TEST_F(AstStorageTextureTest, TypeName) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
EXPECT_EQ(s->type_name(), "__storage_texture_2d_array_rgba32float");
}
TEST_F(AstStorageTextureTest, FriendlyName) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
EXPECT_EQ(s->FriendlyName(Symbols()),
"texture_storage_2d_array<rgba32float>");
}
TEST_F(AstStorageTextureTest, F32) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
Type* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype);
ASSERT_TRUE(s->Is<Texture>());
ASSERT_TRUE(s->Is<StorageTexture>());
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<F32>());
}
TEST_F(AstStorageTextureTest, U32) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRg32Uint, *this);
Type* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRg32Uint, subtype);
ASSERT_TRUE(s->Is<Texture>());
ASSERT_TRUE(s->Is<StorageTexture>());
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<U32>());
}
TEST_F(AstStorageTextureTest, I32) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Sint, *this);
Type* s = create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Sint, subtype);
ASSERT_TRUE(s->Is<Texture>());
ASSERT_TRUE(s->Is<StorageTexture>());
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<I32>());
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -14,6 +14,8 @@
#include "src/ast/struct.h"
#include <string>
#include "src/ast/struct_block_decoration.h"
#include "src/program_builder.h"
@ -24,9 +26,11 @@ namespace ast {
Struct::Struct(ProgramID program_id,
const Source& source,
Symbol name,
StructMemberList members,
DecorationList decorations)
: Base(program_id, source),
name_(name),
members_(std::move(members)),
decorations_(std::move(decorations)) {
for (auto* mem : members_) {
@ -59,15 +63,16 @@ bool Struct::IsBlockDecorated() const {
Struct* Struct::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto n = ctx->Clone(name());
auto mem = ctx->Clone(members());
auto decos = ctx->Clone(decorations());
return ctx->dst->create<Struct>(src, mem, decos);
return ctx->dst->create<Struct>(src, n, mem, decos);
}
void Struct::to_str(const sem::Info& sem,
std::ostream& out,
size_t indent) const {
out << "Struct{" << std::endl;
out << "Struct " << name().to_str() << " {" << std::endl;
for (auto* deco : decorations_) {
make_indent(out, indent + 2);
out << "[[";
@ -81,5 +86,13 @@ void Struct::to_str(const sem::Info& sem,
out << "}" << std::endl;
}
std::string Struct::type_name() const {
return "__struct_" + name().to_str();
}
std::string Struct::FriendlyName(const SymbolTable& symbols) const {
return symbols.NameFor(name());
}
} // namespace ast
} // namespace tint

View File

@ -15,24 +15,28 @@
#ifndef SRC_AST_STRUCT_H_
#define SRC_AST_STRUCT_H_
#include <string>
#include <utility>
#include "src/ast/decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A struct statement.
class Struct : public Castable<Struct, Node> {
class Struct : public Castable<Struct, Type> {
public:
/// Create a new struct statement
/// @param program_id the identifier of the program that owns this node
/// @param source The input source for the import statement
/// @param name The name of the structure
/// @param members The struct members
/// @param decorations The struct decorations
Struct(ProgramID program_id,
const Source& source,
Symbol name,
StructMemberList members,
DecorationList decorations);
/// Move constructor
@ -40,6 +44,9 @@ class Struct : public Castable<Struct, Node> {
~Struct() override;
/// @returns the name of the structure
Symbol name() const { return name_; }
/// @returns the struct decorations
const DecorationList& decorations() const { return decorations_; }
@ -68,9 +75,18 @@ class Struct : public Castable<Struct, Node> {
std::ostream& out,
size_t indent) const override;
/// @returns the name for the type
std::string type_name() const 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;
private:
Struct(const Struct&) = delete;
Symbol const name_;
StructMemberList const members_;
DecorationList const decorations_;
};

View File

@ -12,19 +12,33 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/struct.h"
#include "gtest/gtest-spi.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct_block_decoration.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using StructTest = TestHelper;
using AstStructTest = TestHelper;
TEST_F(StructTest, Creation) {
auto* s =
create<Struct>(StructMemberList{Member("a", ty.i32())}, DecorationList{});
TEST_F(AstStructTest, Creation) {
auto name = Sym("s");
auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())},
DecorationList{});
EXPECT_EQ(s->name(), name);
EXPECT_EQ(s->members().size(), 1u);
EXPECT_TRUE(s->decorations().empty());
EXPECT_EQ(s->source().range.begin.line, 0u);
@ -33,11 +47,14 @@ TEST_F(StructTest, Creation) {
EXPECT_EQ(s->source().range.end.column, 0u);
}
TEST_F(StructTest, Creation_WithDecorations) {
TEST_F(AstStructTest, Creation_WithDecorations) {
auto name = Sym("s");
DecorationList decos;
decos.push_back(create<StructBlockDecoration>());
auto* s = create<Struct>(StructMemberList{Member("a", ty.i32())}, decos);
auto* s =
create<Struct>(name, StructMemberList{Member("a", ty.i32())}, decos);
EXPECT_EQ(s->name(), name);
EXPECT_EQ(s->members().size(), 1u);
ASSERT_EQ(s->decorations().size(), 1u);
EXPECT_TRUE(s->decorations()[0]->Is<StructBlockDecoration>());
@ -47,13 +64,13 @@ TEST_F(StructTest, Creation_WithDecorations) {
EXPECT_EQ(s->source().range.end.column, 0u);
}
TEST_F(StructTest, CreationWithSourceAndDecorations) {
DecorationList decos;
decos.push_back(create<StructBlockDecoration>());
TEST_F(AstStructTest, CreationWithSourceAndDecorations) {
auto name = Sym("s");
auto* s = create<Struct>(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
StructMemberList{Member("a", ty.i32())}, decos);
name, StructMemberList{Member("a", ty.i32())},
DecorationList{create<StructBlockDecoration>()});
EXPECT_EQ(s->name(), name);
EXPECT_EQ(s->members().size(), 1u);
ASSERT_EQ(s->decorations().size(), 1u);
EXPECT_TRUE(s->decorations()[0]->Is<StructBlockDecoration>());
@ -63,60 +80,95 @@ TEST_F(StructTest, CreationWithSourceAndDecorations) {
EXPECT_EQ(s->source().range.end.column, 8u);
}
TEST_F(StructTest, Assert_Null_StructMember) {
TEST_F(AstStructTest, Assert_Null_StructMember) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<Struct>(StructMemberList{b.Member("a", b.ty.i32()), nullptr},
b.create<Struct>(b.Sym("S"),
StructMemberList{b.Member("a", b.ty.i32()), nullptr},
DecorationList{});
},
"internal compiler error");
}
TEST_F(StructTest, Assert_Null_Decoration) {
TEST_F(AstStructTest, Assert_Null_Decoration) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<Struct>(StructMemberList{b.Member("a", b.ty.i32())},
b.create<Struct>(b.Sym("S"),
StructMemberList{b.Member("a", b.ty.i32())},
DecorationList{nullptr});
},
"internal compiler error");
}
TEST_F(StructTest, Assert_DifferentProgramID_StructMember) {
TEST_F(AstStructTest, Assert_DifferentProgramID_StructMember) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<Struct>(StructMemberList{b2.Member("a", b2.ty.i32())},
b1.create<Struct>(b2.Sym("S"),
StructMemberList{b2.Member("a", b2.ty.i32())},
DecorationList{});
},
"internal compiler error");
}
TEST_F(StructTest, Assert_DifferentProgramID_Decoration) {
TEST_F(AstStructTest, Assert_DifferentProgramID_Decoration) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<Struct>(StructMemberList{b1.Member("a", b1.ty.i32())},
b1.create<Struct>(b1.Sym("S"),
StructMemberList{b1.Member("a", b1.ty.i32())},
DecorationList{b2.create<StructBlockDecoration>()});
},
"internal compiler error");
}
TEST_F(StructTest, ToStr) {
DecorationList decos;
decos.push_back(create<StructBlockDecoration>());
auto* s = create<Struct>(StructMemberList{Member("a", ty.i32())}, decos);
TEST_F(AstStructTest, ToStr) {
auto* s = create<Struct>(Sym("S"), StructMemberList{Member("a", ty.i32())},
DecorationList{create<StructBlockDecoration>()});
EXPECT_EQ(str(s), R"(Struct{
EXPECT_EQ(str(s), R"(Struct S {
[[block]]
StructMember{a: __i32}
}
)");
}
TEST_F(AstStructTest, Is) {
Type* ty = create<ast::Struct>(Sym("S"), ast::StructMemberList{},
ast::DecorationList{});
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_TRUE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstStructTest, TypeName) {
auto name = Sym("my_struct");
auto* s =
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
EXPECT_EQ(s->type_name(), "__struct_$1");
}
TEST_F(AstStructTest, FriendlyName) {
auto name = Sym("my_struct");
auto* s =
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
}
} // namespace
} // namespace ast
} // namespace tint

91
src/ast/texture.cc Normal file
View File

@ -0,0 +1,91 @@
// 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/ast/texture.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Texture);
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, TextureDimension dim) {
switch (dim) {
case TextureDimension::kNone:
out << "None";
break;
case TextureDimension::k1d:
out << "1d";
break;
case TextureDimension::k2d:
out << "2d";
break;
case TextureDimension::k2dArray:
out << "2d_array";
break;
case TextureDimension::k3d:
out << "3d";
break;
case TextureDimension::kCube:
out << "cube";
break;
case TextureDimension::kCubeArray:
out << "cube_array";
break;
}
return out;
}
bool IsTextureArray(TextureDimension dim) {
switch (dim) {
case TextureDimension::k2dArray:
case TextureDimension::kCubeArray:
return true;
case TextureDimension::k2d:
case TextureDimension::kNone:
case TextureDimension::k1d:
case TextureDimension::k3d:
case TextureDimension::kCube:
return false;
}
return false;
}
int NumCoordinateAxes(TextureDimension dim) {
switch (dim) {
case TextureDimension::kNone:
return 0;
case TextureDimension::k1d:
return 1;
case TextureDimension::k2d:
case TextureDimension::k2dArray:
return 2;
case TextureDimension::k3d:
case TextureDimension::kCube:
case TextureDimension::kCubeArray:
return 3;
}
return 0;
}
Texture::Texture(ProgramID program_id,
const Source& source,
TextureDimension dim)
: Base(program_id, source), dim_(dim) {}
Texture::Texture(Texture&&) = default;
Texture::~Texture() = default;
} // namespace ast
} // namespace tint

81
src/ast/texture.h Normal file
View File

@ -0,0 +1,81 @@
// 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_AST_TEXTURE_H_
#define SRC_AST_TEXTURE_H_
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// The dimensionality of the texture
enum class TextureDimension {
/// Invalid texture
kNone = -1,
/// 1 dimensional texture
k1d,
/// 2 dimensional texture
k2d,
/// 2 dimensional array texture
k2dArray,
/// 3 dimensional texture
k3d,
/// cube texture
kCube,
/// cube array texture
kCubeArray,
};
/// @param out the std::ostream to write to
/// @param dim the TextureDimension
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, TextureDimension dim);
/// @param dim the TextureDimension to query
/// @return true if the given TextureDimension is an array texture
bool IsTextureArray(TextureDimension dim);
/// Returns the number of axes in the coordinate for a dimensionality.
/// None -> 0
/// 1D -> 1
/// 2D, 2DArray -> 2
/// 3D, Cube, CubeArray -> 3
/// @param dim the TextureDimension to query
/// @return number of dimensions in a coordinate for the dimensionality
int NumCoordinateAxes(TextureDimension dim);
/// A texture type.
class Texture : public Castable<Texture, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param dim the dimensionality of the texture
Texture(ProgramID program_id, const Source& source, TextureDimension dim);
/// Move constructor
Texture(Texture&&);
~Texture() override;
/// @returns the texture dimension
TextureDimension dim() const { return dim_; }
private:
TextureDimension const dim_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_TEXTURE_H_

58
src/ast/texture_test.cc Normal file
View File

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

124
src/ast/type.h Normal file
View File

@ -0,0 +1,124 @@
// 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_AST_TYPE_H_
#define SRC_AST_TYPE_H_
#include <string>
#include "src/ast/node.h"
#include "src/clone_context.h"
namespace tint {
// Forward declarations
class ProgramBuilder;
class SymbolTable;
namespace ast {
/// Base class for a type in the system
class Type : public Castable<Type, Node> {
public:
/// Move constructor
Type(Type&&);
~Type() override;
/// @returns the name for this type. The type name is unique over all types.
virtual std::string type_name() const = 0;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
/// @returns the pointee type if this is a pointer, `this` otherwise
Type* UnwrapPtrIfNeeded();
/// @returns the most deeply nested aliased type if this is an alias, `this`
/// otherwise
Type* UnwrapAliasIfNeeded();
/// Removes all levels of aliasing and access control.
/// This is just enough to assist with WGSL translation
/// in that you want see through one level of pointer to get from an
/// identifier-like expression as an l-value to its corresponding r-value,
/// plus see through the wrappers on either side.
/// @returns the completely unaliased type.
Type* UnwrapIfNeeded();
/// Returns the type found after:
/// - removing all layers of aliasing and access control if they exist, then
/// - removing the pointer, if it exists, then
/// - removing all further layers of aliasing or access control, if they exist
/// @returns the unwrapped type
Type* UnwrapAll();
/// @returns true if this type is a scalar
bool is_scalar() const;
/// @returns true if this type is a float scalar
bool is_float_scalar() const;
/// @returns true if this type is a float matrix
bool is_float_matrix() const;
/// @returns true if this type is a float vector
bool is_float_vector() const;
/// @returns true if this type is a float scalar or vector
bool is_float_scalar_or_vector() const;
/// @returns true if this type is a float scalar or vector or matrix
bool is_float_scalar_or_vector_or_matrix() const;
/// @returns true if this type is an integer scalar
bool is_integer_scalar() const;
/// @returns true if this type is a signed integer vector
bool is_signed_integer_vector() const;
/// @returns true if this type is an unsigned vector
bool is_unsigned_integer_vector() const;
/// @returns true if this type is an unsigned scalar or vector
bool is_unsigned_scalar_or_vector() const;
/// @returns true if this type is a signed scalar or vector
bool is_signed_scalar_or_vector() const;
/// @returns true if this type is an integer scalar or vector
bool is_integer_scalar_or_vector() const;
/// @returns true if this type is a boolean vector
bool is_bool_vector() const;
/// @returns true if this type is boolean scalar or vector
bool is_bool_scalar_or_vector() const;
/// @returns true if this type is a handle type
bool is_handle() const;
/// Writes a representation of the node to the output stream
/// @param sem the semantic info for the program
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(const sem::Info& sem,
std::ostream& out,
size_t indent) const override;
protected:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
Type(ProgramID program_id, const Source& source);
};
/// @returns the ProgramID of the given type.
inline ProgramID ProgramIDOf(const Type*) {
/// TODO(crbug.com/tint/724): Actually implement this once we split the `type`
/// namespace into ast::Type and sem::Type.
return ProgramID();
}
} // namespace ast
} // namespace tint
#endif // SRC_AST_TYPE_H_

45
src/ast/u32.cc Normal file
View File

@ -0,0 +1,45 @@
// 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/ast/u32.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::U32);
namespace tint {
namespace ast {
U32::U32(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
U32::~U32() = default;
U32::U32(U32&&) = default;
std::string U32::type_name() const {
return "__u32";
}
std::string U32::FriendlyName(const SymbolTable&) const {
return "u32";
}
U32* U32::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<U32>(src);
}
} // namespace ast
} // namespace tint

53
src/ast/u32.h Normal file
View File

@ -0,0 +1,53 @@
// 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_AST_U32_H_
#define SRC_AST_U32_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A unsigned int 32 type.
class U32 : public Castable<U32, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
U32(ProgramID program_id, const Source& source);
/// Move constructor
U32(U32&&);
~U32() override;
/// @returns the name for th type
std::string type_name() const 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
U32* Clone(CloneContext* ctx) const override;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_U32_H_

66
src/ast/u32_test.cc Normal file
View File

@ -0,0 +1,66 @@
// 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/ast/u32.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstU32Test = TestHelper;
TEST_F(AstU32Test, Is) {
Type* ty = create<U32>();
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_TRUE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
TEST_F(AstU32Test, TypeName) {
auto* u = create<U32>();
EXPECT_EQ(u->type_name(), "__u32");
}
TEST_F(AstU32Test, FriendlyName) {
auto* u = create<U32>();
EXPECT_EQ(u->FriendlyName(Symbols()), "u32");
}
} // namespace
} // namespace ast
} // namespace tint

55
src/ast/vector.cc Normal file
View File

@ -0,0 +1,55 @@
// 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/ast/vector.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Vector);
namespace tint {
namespace ast {
Vector::Vector(ProgramID program_id,
const Source& source,
Type* subtype,
uint32_t size)
: Base(program_id, source), subtype_(subtype), size_(size) {
TINT_ASSERT(size_ > 1);
TINT_ASSERT(size_ < 5);
}
Vector::Vector(Vector&&) = default;
Vector::~Vector() = default;
std::string Vector::type_name() const {
return "__vec_" + std::to_string(size_) + subtype_->type_name();
}
std::string Vector::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "vec" << size_ << "<" << subtype_->FriendlyName(symbols) << ">";
return out.str();
}
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, size_);
}
} // namespace ast
} // namespace tint

67
src/ast/vector.h Normal file
View File

@ -0,0 +1,67 @@
// 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_AST_VECTOR_H_
#define SRC_AST_VECTOR_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A vector type.
class Vector : public Castable<Vector, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param subtype the vector element type
/// @param size the number of elements in the vector
Vector(ProgramID program_id,
const Source& source,
Type* subtype,
uint32_t size);
/// Move constructor
Vector(Vector&&);
~Vector() override;
/// @returns the type of the vector elements
Type* type() const { return subtype_; }
/// @returns the size of the vector
uint32_t size() const { return size_; }
/// @returns the name for th type
std::string type_name() const 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
Vector* Clone(CloneContext* ctx) const override;
private:
Type* const subtype_;
uint32_t const size_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_VECTOR_H_

74
src/ast/vector_test.cc Normal file
View File

@ -0,0 +1,74 @@
// 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/ast/vector.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
namespace tint {
namespace ast {
namespace {
using AstVectorTest = TestHelper;
TEST_F(AstVectorTest, Creation) {
auto* i32 = create<I32>();
auto* v = create<Vector>(i32, 2);
EXPECT_EQ(v->type(), i32);
EXPECT_EQ(v->size(), 2u);
}
TEST_F(AstVectorTest, Is) {
auto* i32 = create<I32>();
Type* ty = create<Vector>(i32, 4);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_TRUE(ty->Is<Vector>());
}
TEST_F(AstVectorTest, TypeName) {
auto* i32 = create<I32>();
auto* v = create<Vector>(i32, 3);
EXPECT_EQ(v->type_name(), "__vec_3__i32");
}
TEST_F(AstVectorTest, FriendlyName) {
auto* v = ty.vec3<f32>();
EXPECT_EQ(v->FriendlyName(Symbols()), "vec3<f32>");
}
} // namespace
} // namespace ast
} // namespace tint

45
src/ast/void.cc Normal file
View File

@ -0,0 +1,45 @@
// 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/ast/void.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Void);
namespace tint {
namespace ast {
Void::Void(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
Void::Void(Void&&) = default;
Void::~Void() = default;
std::string Void::type_name() const {
return "__void";
}
std::string Void::FriendlyName(const SymbolTable&) const {
return "void";
}
Void* Void::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source());
return ctx->dst->create<Void>(src);
}
} // namespace ast
} // namespace tint

53
src/ast/void.h Normal file
View File

@ -0,0 +1,53 @@
// 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_AST_VOID_H_
#define SRC_AST_VOID_H_
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// A void type
class Void : public Castable<Void, Type> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
Void(ProgramID program_id, const Source& source);
/// Move constructor
Void(Void&&);
~Void() override;
/// @returns the name for this type
std::string type_name() const 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
Void* Clone(CloneContext* ctx) const override;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_VOID_H_

View File

@ -225,8 +225,9 @@ class InspectorHelper : public ProgramBuilder {
decos.push_back(create<ast::StructBlockDecoration>());
}
auto* str = create<ast::Struct>(members, decos);
auto* str_ty = ty.struct_(name, str);
auto sym = Sym(name);
auto* str = create<ast::Struct>(sym, members, decos);
auto* str_ty = ty.struct_(sym, str);
AST().AddConstructedType(str_ty);
return str_ty;
}
@ -1824,6 +1825,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MissingBlockDeco) {
ast::DecorationList decos;
auto* str = create<ast::Struct>(
Sym("foo_type"),
ast::StructMemberList{Member(StructMemberName(0, ty.i32()), ty.i32())},
decos);

View File

@ -603,7 +603,7 @@ class SamplerBuilder : public Builder {
/// AccessControlBuilder is a Matcher / Builder for AccessControl types
class AccessControlBuilder : public Builder {
public:
explicit AccessControlBuilder(ast::AccessControl access_control,
explicit AccessControlBuilder(ast::AccessControl::Access access_control,
Builder* type)
: access_control_(access_control), type_(type) {}
@ -628,7 +628,7 @@ class AccessControlBuilder : public Builder {
}
private:
ast::AccessControl const access_control_;
ast::AccessControl::Access const access_control_;
Builder* const type_;
};
@ -765,7 +765,8 @@ class Impl : public IntrinsicTable {
}
/// @returns a Matcher / Builder that matches an access control type
Builder* access_control(ast::AccessControl access_control, Builder* type) {
Builder* access_control(ast::AccessControl::Access access_control,
Builder* type) {
return matcher_allocator_.Create<AccessControlBuilder>(access_control,
type);
}

View File

@ -535,7 +535,7 @@ class ProgramBuilder {
/// @param access the access control
/// @param type the inner type
/// @returns the access control qualifier type
sem::AccessControl* access(ast::AccessControl access,
sem::AccessControl* access(ast::AccessControl::Access access,
sem::Type* type) const {
return builder->create<sem::AccessControl>(access, type);
}
@ -1185,9 +1185,10 @@ class ProgramBuilder {
NAME&& name,
ast::StructMemberList members,
ast::DecorationList decorations = {}) {
auto* impl =
create<ast::Struct>(source, std::move(members), std::move(decorations));
auto* type = ty.struct_(Sym(std::forward<NAME>(name)), impl);
auto sym = Sym(std::forward<NAME>(name));
auto* impl = create<ast::Struct>(source, sym, std::move(members),
std::move(decorations));
auto* type = ty.struct_(sym, impl);
AST().AddConstructedType(type);
return type;
}
@ -1202,9 +1203,10 @@ class ProgramBuilder {
sem::StructType* Structure(NAME&& name,
ast::StructMemberList members,
ast::DecorationList decorations = {}) {
auto sym = Sym(std::forward<NAME>(name));
auto* impl =
create<ast::Struct>(std::move(members), std::move(decorations));
auto* type = ty.struct_(Sym(std::forward<NAME>(name)), impl);
create<ast::Struct>(sym, std::move(members), std::move(decorations));
auto* type = ty.struct_(sym, impl);
AST().AddConstructedType(type);
return type;
}

View File

@ -1338,7 +1338,8 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
if (top->ContainsPos(target0_pos) &&
top->ContainsPos(target1_pos)) {
// Insert a synthetic if-selection
top = push_construct(depth+1, Construct::kIfSelection, header, ct);
top = push_construct(depth + 1, Construct::kIfSelection, header,
ct);
}
}
}

View File

@ -798,7 +798,7 @@ TEST_F(SpvParserTest, RemapStorageBuffer_TypesAndVarDeclarations) {
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
RTArr -> __array__u32_stride_4
S Struct{
Struct S {
[[block]]
StructMember{[[ offset 0 ]] field0: __u32}
StructMember{[[ offset 4 ]] field1: __alias_RTArr__array__u32_stride_4}

View File

@ -551,7 +551,7 @@ Source ParserImpl::GetSourceForInst(
if (where == inst_source_.end()) {
return {};
}
return Source{where->second };
return Source{where->second};
}
bool ParserImpl::ParseInternalModuleExceptFunctions() {
@ -940,15 +940,16 @@ sem::Type* ParserImpl::ConvertType(
return nullptr;
}
// Now make the struct.
auto* ast_struct = create<ast::Struct>(Source{}, std::move(ast_members),
std::move(ast_struct_decorations));
namer_.SuggestSanitizedName(type_id, "S");
auto name = namer_.GetName(type_id);
auto* result = builder_.create<sem::StructType>(
builder_.Symbols().Register(name), ast_struct);
// Now make the struct.
auto sym = builder_.Symbols().Register(name);
auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members),
std::move(ast_struct_decorations));
auto* result = builder_.create<sem::StructType>(sym, ast_struct);
id_to_type_[type_id] = result;
if (num_non_writable_members == members.size()) {
read_only_struct_types_.insert(result);

View File

@ -553,7 +553,7 @@ TEST_F(SpvParserTest, ConvertType_StructTwoMembers) {
EXPECT_TRUE(type->Is<sem::StructType>());
Program program = p->program();
EXPECT_THAT(program.str(type->As<sem::StructType>()->impl()), Eq(R"(Struct{
EXPECT_THAT(program.str(type->As<sem::StructType>()->impl()), Eq(R"(Struct S {
StructMember{field0: __u32}
StructMember{field1: __f32}
}
@ -574,7 +574,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
EXPECT_TRUE(type->Is<sem::StructType>());
Program program = p->program();
EXPECT_THAT(program.str(type->As<sem::StructType>()->impl()), Eq(R"(Struct{
EXPECT_THAT(program.str(type->As<sem::StructType>()->impl()), Eq(R"(Struct S {
[[block]]
StructMember{field0: __u32}
}
@ -599,7 +599,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
EXPECT_TRUE(type->Is<sem::StructType>());
Program program = p->program();
EXPECT_THAT(program.str(type->As<sem::StructType>()->impl()), Eq(R"(Struct{
EXPECT_THAT(program.str(type->As<sem::StructType>()->impl()), Eq(R"(Struct S {
StructMember{[[ offset 0 ]] field0: __f32}
StructMember{[[ offset 8 ]] field1: __vec_2__f32}
StructMember{[[ offset 16 ]] field2: __mat_2_2__f32}

View File

@ -1654,7 +1654,7 @@ TEST_F(SpvModuleScopeVarParserTest,
EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
S Struct{
Struct S {
[[block]]
StructMember{field0: __u32}
StructMember{field1: __f32}
@ -1685,7 +1685,7 @@ TEST_F(SpvModuleScopeVarParserTest, ColMajorDecoration_Dropped) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
S Struct{
Struct S {
[[block]]
StructMember{field0: __mat_2_3__f32}
}
@ -1714,7 +1714,7 @@ TEST_F(SpvModuleScopeVarParserTest, MatrixStrideDecoration_Dropped) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
S Struct{
Struct S {
[[block]]
StructMember{field0: __mat_2_3__f32}
}
@ -1763,7 +1763,7 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_AllMembers) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
S Struct{
Struct S {
[[block]]
StructMember{field0: __f32}
StructMember{field1: __f32}
@ -1792,7 +1792,7 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_NotAllMembers) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
S Struct{
Struct S {
[[block]]
StructMember{field0: __f32}
StructMember{field1: __f32}
@ -1824,7 +1824,7 @@ TEST_F(
EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
S Struct{
Struct S {
[[block]]
StructMember{field0: __f32}
StructMember{field1: __f32}

View File

@ -29,7 +29,7 @@ TEST_F(SpvParserTest, NamedTypes_AnonStruct) {
%s = OpTypeStruct %uint %uint
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_THAT(p->program().to_str(), HasSubstr("S Struct"));
EXPECT_THAT(p->program().to_str(), HasSubstr("Struct S"));
}
TEST_F(SpvParserTest, NamedTypes_NamedStruct) {
@ -39,7 +39,7 @@ TEST_F(SpvParserTest, NamedTypes_NamedStruct) {
%s = OpTypeStruct %uint %uint
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_THAT(p->program().to_str(), HasSubstr("mystruct Struct"));
EXPECT_THAT(p->program().to_str(), HasSubstr("Struct mystruct"));
}
TEST_F(SpvParserTest, NamedTypes_Dup_EmitBoth) {
@ -49,11 +49,11 @@ TEST_F(SpvParserTest, NamedTypes_Dup_EmitBoth) {
%s2 = OpTypeStruct %uint %uint
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
EXPECT_THAT(p->program().to_str(), HasSubstr(R"(S Struct{
EXPECT_THAT(p->program().to_str(), HasSubstr(R"(Struct S {
StructMember{field0: __u32}
StructMember{field1: __u32}
}
S_1 Struct{
Struct S_1 {
StructMember{field0: __u32}
StructMember{field1: __u32}
})"));

View File

@ -836,7 +836,7 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
return TypedIdentifier{ty, ident.value, ident.source};
}
Expect<ast::AccessControl> ParserImpl::expect_access_type() {
Expect<ast::AccessControl::Access> ParserImpl::expect_access_type() {
auto ident = expect_ident("access_type");
if (ident.errored)
return Failure::kErrored;
@ -1134,9 +1134,10 @@ Maybe<sem::StructType*> ParserImpl::struct_decl(ast::DecorationList& decos) {
if (body.errored)
return Failure::kErrored;
auto sym = builder_.Symbols().Register(name.value);
return create<sem::StructType>(
builder_.Symbols().Register(name.value),
create<ast::Struct>(source, std::move(body.value), std::move(decos)));
sym, create<ast::Struct>(source, sym, std::move(body.value),
std::move(decos)));
}
// struct_body_decl

View File

@ -437,7 +437,7 @@ class ParserImpl {
/// Parses an access type identifier, erroring if the next token does not
/// match a valid access type name.
/// @returns the parsed access control.
Expect<ast::AccessControl> expect_access_type();
Expect<ast::AccessControl::Access> expect_access_type();
/// Parses a builtin identifier, erroring if the next token does not match a
/// valid builtin name.
/// @returns the parsed builtin.

View File

@ -115,7 +115,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) {
ast::DecorationList decos;
decos.push_back(block_deco);
auto* str = create<ast::Struct>(members, decos);
auto* str = create<ast::Struct>(Sym("S"), members, decos);
auto* s = ty.struct_("S", str);
p->register_constructed("S", s);
@ -140,7 +140,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) {
ast::DecorationList decos;
decos.push_back(block_deco);
auto* str = create<ast::Struct>(members, decos);
auto* str = create<ast::Struct>(Sym("S"), members, decos);
auto* s = ty.struct_("S", str);
p->register_constructed("S", s);
@ -165,7 +165,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail) {
ast::DecorationList decos;
decos.push_back(block_deco);
auto* str = create<ast::Struct>(members, decos);
auto* str = create<ast::Struct>(Sym("S"), members, decos);
auto* s = ty.struct_("S", str);
p->register_constructed("S", s);
@ -187,7 +187,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDeco_MultiBlock_Fail) {
ast::DecorationList decos;
decos.push_back(block_deco);
auto* str = create<ast::Struct>(members, decos);
auto* str = create<ast::Struct>(Sym("S"), members, decos);
auto* s = ty.struct_("S", str);
p->register_constructed("S", s);
@ -225,7 +225,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_NonAccessDecoFail) {
ast::DecorationList decos;
decos.push_back(block_deco);
auto* str = create<ast::Struct>(members, decos);
auto* str = create<ast::Struct>(Sym("S"), members, decos);
auto* s = ty.struct_("S", str);
p->register_constructed("S", s);

View File

@ -131,7 +131,8 @@ TEST_P(ArrayDecorationTest, IsValid) {
ast::DecorationList{createDecoration(
Source{{12, 34}}, *this, params.kind)}))};
auto* s = create<ast::Struct>(
members, ast::DecorationList{create<ast::StructBlockDecoration>()});
Sym("mystruct"), members,
ast::DecorationList{create<ast::StructBlockDecoration>()});
auto* s_ty = ty.struct_("mystruct", s);
AST().AddConstructedType(s_ty);
@ -166,7 +167,7 @@ using StructDecorationTest = TestWithParams;
TEST_P(StructDecorationTest, IsValid) {
auto& params = GetParam();
auto* s = create<ast::Struct>(ast::StructMemberList{},
auto* s = create<ast::Struct>(Sym("mystruct"), ast::StructMemberList{},
ast::DecorationList{createDecoration(
Source{{12, 34}}, *this, params.kind)});
auto* s_ty = ty.struct_("mystruct", s);
@ -207,7 +208,8 @@ TEST_P(StructMemberDecorationTest, IsValid) {
Member("a", ty.i32(),
ast::DecorationList{
createDecoration(Source{{12, 34}}, *this, params.kind)})};
auto* s = create<ast::Struct>(members, ast::DecorationList{});
auto* s =
create<ast::Struct>(Sym("mystruct"), members, ast::DecorationList{});
auto* s_ty = ty.struct_("mystruct", s);
AST().AddConstructedType(s_ty);

View File

@ -889,6 +889,7 @@ TEST_F(ResolverTest, Function_ReturnStatements) {
TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
auto* strct = create<ast::Struct>(
Sym("S"),
ast::StructMemberList{Member("first_member", ty.i32()),
Member("second_member", ty.f32())},
ast::DecorationList{});
@ -918,6 +919,7 @@ TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) {
auto* strct = create<ast::Struct>(
Sym("alias"),
ast::StructMemberList{Member("first_member", ty.i32()),
Member("second_member", ty.f32())},
ast::DecorationList{});
@ -999,14 +1001,15 @@ TEST_F(ResolverTest, Expr_Accessor_MultiLevel) {
// }
//
auto* strctB =
create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
ast::DecorationList{});
auto* strctB = create<ast::Struct>(
Sym("B"), ast::StructMemberList{Member("foo", ty.vec4<f32>())},
ast::DecorationList{});
auto* stB = ty.struct_("B", strctB);
sem::Vector vecB(stB, 3);
auto* strctA = create<ast::Struct>(
ast::StructMemberList{Member("mem", &vecB)}, ast::DecorationList{});
auto* strctA =
create<ast::Struct>(Sym("A"), ast::StructMemberList{Member("mem", &vecB)},
ast::DecorationList{});
auto* stA = ty.struct_("A", strctA);
Global("c", stA, ast::StorageClass::kInput);
@ -1027,6 +1030,7 @@ TEST_F(ResolverTest, Expr_Accessor_MultiLevel) {
TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
auto* strct = create<ast::Struct>(
Sym("S"),
ast::StructMemberList{Member("first_member", ty.f32()),
Member("second_member", ty.f32())},
ast::DecorationList{});

View File

@ -315,7 +315,8 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLast_Pass) {
ast::DecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>());
auto* st =
create<ast::Struct>(ast::StructMemberList{Member("vf", ty.f32()),
create<ast::Struct>(Sym("Foo"),
ast::StructMemberList{Member("vf", ty.f32()),
Member("rt", ty.array<f32>())},
decos);
@ -335,6 +336,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLastNoBlock_Fail) {
ast::DecorationList decos;
auto* st = create<ast::Struct>(
Sym("Foo"),
ast::StructMemberList{Member("vf", ty.f32()),
Member(Source{{12, 34}}, "rt", ty.array<f32>())},
decos);
@ -362,7 +364,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) {
auto* rt = Member(Source{{12, 34}}, "rt", ty.array<f32>());
auto* st = create<ast::Struct>(
ast::StructMemberList{rt, Member("vf", ty.f32())}, decos);
Sym("Foo"), ast::StructMemberList{rt, Member("vf", ty.f32())}, decos);
auto* struct_type = ty.struct_("Foo", st);
@ -438,6 +440,7 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) {
ast::DecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>());
auto* st = create<ast::Struct>(
Sym("s"),
ast::StructMemberList{Member(Source{{12, 34}}, "b", alias),
Member("a", ty.u32())},
decos);
@ -467,6 +470,7 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) {
ast::DecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>());
auto* st = create<ast::Struct>(
Sym("s"),
ast::StructMemberList{Member("a", ty.u32()), Member("b", alias)}, decos);
auto* struct_type = ty.struct_("s", st);

View File

@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::AccessControl);
namespace tint {
namespace sem {
AccessControl::AccessControl(ast::AccessControl access, Type* subtype)
AccessControl::AccessControl(ast::AccessControl::Access access, Type* subtype)
: access_(access), subtype_(subtype) {
TINT_ASSERT(subtype_);
TINT_ASSERT(!subtype_->Is<AccessControl>());

View File

@ -29,7 +29,7 @@ class AccessControl : public Castable<AccessControl, Type> {
/// Constructor
/// @param access the access control setting
/// @param subtype the access controlled type
AccessControl(ast::AccessControl access, Type* subtype);
AccessControl(ast::AccessControl::Access access, Type* subtype);
/// Move constructor
AccessControl(AccessControl&&);
~AccessControl() override;
@ -42,7 +42,7 @@ class AccessControl : public Castable<AccessControl, Type> {
bool IsReadWrite() const { return access_ == ast::AccessControl::kReadWrite; }
/// @returns the access control value
ast::AccessControl access_control() const { return access_; }
ast::AccessControl::Access access_control() const { return access_; }
/// @returns the subtype type
Type* type() const { return subtype_; }
@ -60,7 +60,7 @@ class AccessControl : public Castable<AccessControl, Type> {
AccessControl* Clone(CloneContext* ctx) const override;
private:
ast::AccessControl const access_;
ast::AccessControl::Access const access_;
Type* const subtype_;
};

View File

@ -21,6 +21,8 @@
namespace tint {
namespace sem {
/// An external texture type
class ExternalTexture : public Castable<ExternalTexture, Texture> {
public:
/// Constructor
@ -46,4 +48,5 @@ class ExternalTexture : public Castable<ExternalTexture, Texture> {
} // namespace sem
} // namespace tint
#endif // SRC_SEM_EXTERNAL_TEXTURE_TYPE_H_

View File

@ -23,17 +23,19 @@ namespace {
using StructTypeTest = TestHelper;
TEST_F(StructTypeTest, Creation) {
auto name = Sym("S");
auto* impl =
create<ast::Struct>(ast::StructMemberList{}, ast::DecorationList{});
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* ptr = impl;
auto* s = ty.struct_("S", impl);
auto* s = ty.struct_(name, impl);
EXPECT_EQ(s->impl(), ptr);
}
TEST_F(StructTypeTest, Is) {
auto name = Sym("S");
auto* impl =
create<ast::Struct>(ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_("S", impl);
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_(name, impl);
sem::Type* ty = s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
@ -51,16 +53,18 @@ TEST_F(StructTypeTest, Is) {
}
TEST_F(StructTypeTest, TypeName) {
auto name = Sym("my_struct");
auto* impl =
create<ast::Struct>(ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_("my_struct", impl);
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_(name, impl);
EXPECT_EQ(s->type_name(), "__struct_$1");
}
TEST_F(StructTypeTest, FriendlyName) {
auto name = Sym("my_struct");
auto* impl =
create<ast::Struct>(ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_("my_struct", impl);
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_(name, impl);
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
}

View File

@ -63,7 +63,7 @@ Output BindingRemapper::Run(const Program* in, const DataMap& datamap) {
// Replace any access controls.
auto ac_it = remappings->access_controls.find(from);
if (ac_it != remappings->access_controls.end()) {
ast::AccessControl ac = ac_it->second;
ast::AccessControl::Access ac = ac_it->second;
auto* ty = in->Sem().Get(var)->Type();
sem::Type* inner_ty = nullptr;
if (auto* old_ac = ty->As<sem::AccessControl>()) {

View File

@ -32,7 +32,8 @@ class BindingRemapper : public Transform {
using BindingPoints = std::unordered_map<BindingPoint, BindingPoint>;
/// AccessControls is a map of old binding point to new access control
using AccessControls = std::unordered_map<BindingPoint, ast::AccessControl>;
using AccessControls =
std::unordered_map<BindingPoint, ast::AccessControl::Access>;
/// Remappings is consumed by the BindingRemapper transform.
/// Data holds information about shader usage and constant buffer offsets.

View File

@ -81,10 +81,11 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) {
}
// Redeclare the struct.
auto new_struct_name = ctx.Clone(struct_ty->symbol());
auto* new_struct = ctx.dst->create<sem::StructType>(
ctx.Clone(struct_ty->symbol()),
ctx.dst->create<ast::Struct>(
new_struct_members, ctx.Clone(struct_ty->impl()->decorations())));
new_struct_name, ctx.dst->create<ast::Struct>(
new_struct_name, new_struct_members,
ctx.Clone(struct_ty->impl()->decorations())));
ctx.Replace(struct_ty, new_struct);
}
}
@ -174,9 +175,10 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) {
StructMemberComparator);
// Create the new struct type.
auto in_struct_name = ctx.dst->Symbols().New();
auto* in_struct = ctx.dst->create<sem::StructType>(
ctx.dst->Symbols().New(),
ctx.dst->create<ast::Struct>(new_struct_members,
in_struct_name,
ctx.dst->create<ast::Struct>(in_struct_name, new_struct_members,
ast::DecorationList{}));
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, in_struct);
@ -220,9 +222,10 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) {
StructMemberComparator);
// Create the new struct type.
auto out_struct_name = ctx.dst->Symbols().New();
auto* out_struct = ctx.dst->create<sem::StructType>(
ctx.dst->Symbols().New(),
ctx.dst->create<ast::Struct>(new_struct_members,
out_struct_name,
ctx.dst->create<ast::Struct>(out_struct_name, new_struct_members,
ast::DecorationList{}));
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, out_struct);
new_ret_type = out_struct;

View File

@ -126,10 +126,11 @@ void Spirv::HandleEntryPointIOTypes(CloneContext& ctx) const {
}
// Redeclare the struct.
auto new_struct_name = ctx.Clone(struct_ty->symbol());
auto* new_struct = ctx.dst->create<sem::StructType>(
ctx.Clone(struct_ty->symbol()),
ctx.dst->create<ast::Struct>(
new_struct_members, ctx.Clone(struct_ty->impl()->decorations())));
new_struct_name, ctx.dst->create<ast::Struct>(
new_struct_name, new_struct_members,
ctx.Clone(struct_ty->impl()->decorations())));
ctx.Replace(struct_ty, new_struct);
}
}

View File

@ -3145,7 +3145,7 @@ bool Builder::GeneratePointerType(sem::Pointer* ptr, const Operand& result) {
}
bool Builder::GenerateStructType(sem::StructType* struct_type,
ast::AccessControl access_control,
ast::AccessControl::Access access_control,
const Operand& result) {
auto struct_id = result.to_i();
auto* impl = struct_type->impl();

View File

@ -450,7 +450,7 @@ class Builder {
/// @param result the result operand
/// @returns true if the vector was successfully generated
bool GenerateStructType(sem::StructType* struct_type,
ast::AccessControl access_control,
ast::AccessControl::Access access_control,
const Operand& result);
/// Generates a struct member
/// @param struct_id the id of the parent structure

View File

@ -436,7 +436,7 @@ INSTANTIATE_TEST_SUITE_P(WgslGeneratorImplTest,
struct StorageTextureData {
sem::ImageFormat fmt;
sem::TextureDimension dim;
ast::AccessControl access;
ast::AccessControl::Access access;
const char* name;
};
inline std::ostream& operator<<(std::ostream& out, StorageTextureData data) {

View File

@ -138,14 +138,18 @@ tint_unittests_source_set("tint_unittests_core_sem_src") {
tint_unittests_source_set("tint_unittests_core_src") {
sources = [
"../src/ast/access_control_test.cc",
"../src/ast/access_decoration_test.cc",
"../src/ast/alias_test.cc",
"../src/ast/array_accessor_expression_test.cc",
"../src/ast/array_test.cc",
"../src/ast/assignment_statement_test.cc",
"../src/ast/binary_expression_test.cc",
"../src/ast/binding_decoration_test.cc",
"../src/ast/bitcast_expression_test.cc",
"../src/ast/block_statement_test.cc",
"../src/ast/bool_literal_test.cc",
"../src/ast/bool_test.cc",
"../src/ast/break_statement_test.cc",
"../src/ast/builtin_decoration_test.cc",
"../src/ast/call_expression_test.cc",
@ -153,12 +157,15 @@ tint_unittests_source_set("tint_unittests_core_src") {
"../src/ast/case_statement_test.cc",
"../src/ast/constant_id_decoration_test.cc",
"../src/ast/continue_statement_test.cc",
"../src/ast/depth_texture_test.cc",
"../src/ast/discard_statement_test.cc",
"../src/ast/else_statement_test.cc",
"../src/ast/f32_test.cc",
"../src/ast/fallthrough_statement_test.cc",
"../src/ast/float_literal_test.cc",
"../src/ast/function_test.cc",
"../src/ast/group_decoration_test.cc",
"../src/ast/i32_test.cc",
"../src/ast/identifier_expression_test.cc",
"../src/ast/if_statement_test.cc",
"../src/ast/int_literal_test.cc",
@ -166,13 +173,19 @@ tint_unittests_source_set("tint_unittests_core_src") {
"../src/ast/intrinsic_texture_helper_test.h",
"../src/ast/location_decoration_test.cc",
"../src/ast/loop_statement_test.cc",
"../src/ast/matrix_test.cc",
"../src/ast/member_accessor_expression_test.cc",
"../src/ast/module_clone_test.cc",
"../src/ast/module_test.cc",
"../src/ast/multisampled_texture_test.cc",
"../src/ast/pointer_test.cc",
"../src/ast/return_statement_test.cc",
"../src/ast/sampled_texture_test.cc",
"../src/ast/sampler_test.cc",
"../src/ast/scalar_constructor_expression_test.cc",
"../src/ast/sint_literal_test.cc",
"../src/ast/stage_decoration_test.cc",
"../src/ast/storage_texture_test.cc",
"../src/ast/stride_decoration_test.cc",
"../src/ast/struct_member_align_decoration_test.cc",
"../src/ast/struct_member_offset_decoration_test.cc",
@ -181,11 +194,14 @@ tint_unittests_source_set("tint_unittests_core_src") {
"../src/ast/struct_test.cc",
"../src/ast/switch_statement_test.cc",
"../src/ast/test_helper.h",
"../src/ast/texture_test.cc",
"../src/ast/type_constructor_expression_test.cc",
"../src/ast/u32_test.cc",
"../src/ast/uint_literal_test.cc",
"../src/ast/unary_op_expression_test.cc",
"../src/ast/variable_decl_statement_test.cc",
"../src/ast/variable_test.cc",
"../src/ast/vector_test.cc",
"../src/ast/workgroup_decoration_test.cc",
"../src/block_allocator_test.cc",
"../src/castable_test.cc",
@ -208,9 +224,9 @@ tint_unittests_source_set("tint_unittests_core_src") {
"../src/resolver/intrinsic_test.cc",
"../src/resolver/is_host_shareable_test.cc",
"../src/resolver/is_storeable_test.cc",
"../src/resolver/resolver_test.cc",
"../src/resolver/resolver_test_helper.cc",
"../src/resolver/resolver_test_helper.h",
"../src/resolver/resolver_test.cc",
"../src/resolver/storage_class_validation_test.cc",
"../src/resolver/struct_layout_test.cc",
"../src/resolver/struct_pipeline_stage_use_test.cc",
@ -253,11 +269,12 @@ tint_unittests_source_set("tint_unittests_core_src") {
"../src/transform/vertex_pulling_test.cc",
"../src/utils/command.h",
"../src/utils/command_test.cc",
"../src/utils/command.h",
"../src/utils/get_or_create_test.cc",
"../src/utils/hash_test.cc",
"../src/utils/math_test.cc",
"../src/utils/tmpfile.h",
"../src/utils/tmpfile_test.cc",
"../src/utils/tmpfile.h",
"../src/utils/unique_vector_test.cc",
"../src/writer/append_vector_test.cc",
"../src/writer/float_to_string_test.cc",