[tint] Add sem::Array, derives from core::type::Array
This will hold additional resolver-only data.
Change-Id: I24727df206998ec4a0645b1114b15bb0f1c0a68f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/155302
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/type/array.h b/src/tint/lang/core/type/array.h
index 0f97911..ea29674 100644
--- a/src/tint/lang/core/type/array.h
+++ b/src/tint/lang/core/type/array.h
@@ -28,7 +28,7 @@
namespace tint::core::type {
/// Array holds the type information for Array nodes.
-class Array final : public Castable<Array, Type> {
+class Array : public Castable<Array, Type> {
public:
/// An error message string stating that the array count was expected to be a constant
/// expression. Used by multiple writers and transforms.
diff --git a/src/tint/lang/wgsl/resolver/inferred_type_test.cc b/src/tint/lang/wgsl/resolver/inferred_type_test.cc
index 89212fe..ec9e59a 100644
--- a/src/tint/lang/wgsl/resolver/inferred_type_test.cc
+++ b/src/tint/lang/wgsl/resolver/inferred_type_test.cc
@@ -14,6 +14,7 @@
#include "src/tint/lang/wgsl/resolver/resolver.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "gmock/gmock.h"
@@ -124,9 +125,9 @@
TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
auto type = ty.array<u32, 10>();
- auto* expected_type = create<core::type::Array>(create<core::type::U32>(),
- create<core::type::ConstantArrayCount>(10u), 4u,
- 4u * 10u, 4u, 4u);
+ auto* expected_type =
+ create<sem::Array>(create<core::type::U32>(), create<core::type::ConstantArrayCount>(10u),
+ 4u, 4u * 10u, 4u, 4u);
auto* ctor_expr = Call(type);
auto* var = Var("a", core::AddressSpace::kFunction, ctor_expr);
diff --git a/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc b/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc
index e23a9b5..b7b0aa6 100644
--- a/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc
+++ b/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc
@@ -17,6 +17,7 @@
#include "gmock/gmock.h"
#include "src/tint/lang/core/type/atomic.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
namespace tint::resolver {
namespace {
@@ -106,14 +107,14 @@
}
TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
- auto* arr = create<core::type::Array>(
- create<core::type::I32>(), create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<core::type::I32>(),
+ create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
EXPECT_TRUE(r()->IsHostShareable(arr));
}
TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) {
- auto* arr = create<core::type::Array>(create<core::type::I32>(),
- create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<core::type::I32>(),
+ create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
EXPECT_TRUE(r()->IsHostShareable(arr));
}
diff --git a/src/tint/lang/wgsl/resolver/is_storeable_test.cc b/src/tint/lang/wgsl/resolver/is_storeable_test.cc
index b040dce..e549151 100644
--- a/src/tint/lang/wgsl/resolver/is_storeable_test.cc
+++ b/src/tint/lang/wgsl/resolver/is_storeable_test.cc
@@ -17,6 +17,7 @@
#include "gmock/gmock.h"
#include "src/tint/lang/core/type/atomic.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
using namespace tint::core::fluent_types; // NOLINT
@@ -91,14 +92,14 @@
}
TEST_F(ResolverIsStorableTest, ArraySizedOfStorable) {
- auto* arr = create<core::type::Array>(
- create<core::type::I32>(), create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<core::type::I32>(),
+ create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
EXPECT_TRUE(r()->IsStorable(arr));
}
TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) {
- auto* arr = create<core::type::Array>(create<core::type::I32>(),
- create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<core::type::I32>(),
+ create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
EXPECT_TRUE(r()->IsStorable(arr));
}
diff --git a/src/tint/lang/wgsl/resolver/materialize_test.cc b/src/tint/lang/wgsl/resolver/materialize_test.cc
index f4b0ab5..53a6bc1 100644
--- a/src/tint/lang/wgsl/resolver/materialize_test.cc
+++ b/src/tint/lang/wgsl/resolver/materialize_test.cc
@@ -17,6 +17,7 @@
#include "src/tint/lang/core/type/helper_test.h"
#include "src/tint/lang/wgsl/resolver/resolver.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/utils/rtti/switch.h"
#include "gmock/gmock.h"
@@ -117,7 +118,7 @@
}
}
},
- [&](const core::type::Array* a) {
+ [&](const sem::Array* a) {
auto count = a->ConstantCount();
ASSERT_NE(count, 0u);
for (uint32_t i = 0; i < count; i++) {
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 6708a0c..ff8f66b 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -64,6 +64,7 @@
#include "src/tint/lang/wgsl/resolver/incomplete_type.h"
#include "src/tint/lang/wgsl/resolver/uniformity.h"
#include "src/tint/lang/wgsl/resolver/unresolved_identifier.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/break_if_statement.h"
#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
#include "src/tint/lang/wgsl/sem/call.h"
@@ -901,7 +902,7 @@
for (auto* var : transitively_referenced_overrides) {
b.Sem().AddTransitivelyReferencedOverride(sem, var);
}
- if (auto* arr = sem->Type()->UnwrapRef()->As<core::type::Array>()) {
+ if (auto* arr = sem->Type()->UnwrapRef()->As<sem::Array>()) {
auto* refs = b.Sem().TransitivelyReferencedOverrides(arr);
if (refs) {
for (auto* var : *refs) {
@@ -1775,9 +1776,9 @@
return target_ty ? target_ty : f32m(m->columns(), m->rows());
});
},
- [&](const core::type::Array* a) -> const core::type::Type* {
+ [&](const sem::Array* a) -> const core::type::Type* {
const core::type::Type* target_el_ty = nullptr;
- if (auto* target_arr_ty = As<core::type::Array>(target_ty)) {
+ if (auto* target_arr_ty = As<sem::Array>(target_ty)) {
target_el_ty = target_arr_ty->ElemType();
}
if (auto* el_ty = ConcreteType(a->ElemType(), target_el_ty, source)) {
@@ -1944,7 +1945,7 @@
auto* obj_ty = obj_raw_ty->UnwrapRef();
auto* ty = Switch(
obj_ty, //
- [&](const core::type::Array* arr) { return arr->ElemType(); },
+ [&](const sem::Array* arr) { return arr->ElemType(); },
[&](const core::type::Vector* vec) { return vec->type(); },
[&](const core::type::Matrix* mat) {
return b.create<core::type::Vector>(mat->type(), mat->rows());
@@ -2174,7 +2175,7 @@
return ctor_or_conv(wgsl::intrinsic::MatrixCtorConv(m->columns(), m->rows()),
m->type());
},
- [&](const core::type::Array* arr) -> sem::Call* {
+ [&](const sem::Array* arr) -> sem::Call* {
auto* call_target = array_ctors_.GetOrCreate(
ArrayConstructorSig{{arr, args.Length(), args_stage}},
[&]() -> sem::ValueConstructor* {
@@ -4045,12 +4046,12 @@
return true;
}
-core::type::Array* Resolver::Array(const Source& array_source,
- const Source& el_source,
- const Source& count_source,
- const core::type::Type* el_ty,
- const core::type::ArrayCount* el_count,
- uint32_t explicit_stride) {
+sem::Array* Resolver::Array(const Source& array_source,
+ const Source& el_source,
+ const Source& count_source,
+ const core::type::Type* el_ty,
+ const core::type::ArrayCount* el_count,
+ uint32_t explicit_stride) {
uint32_t el_align = el_ty->Align();
uint32_t el_size = el_ty->Size();
uint64_t implicit_stride = el_size ? tint::RoundUp<uint64_t>(el_align, el_size) : 0;
@@ -4069,9 +4070,9 @@
} else if (el_count->Is<core::type::RuntimeArrayCount>()) {
size = stride;
}
- auto* out = b.create<core::type::Array>(el_ty, el_count, el_align, static_cast<uint32_t>(size),
- static_cast<uint32_t>(stride),
- static_cast<uint32_t>(implicit_stride));
+ auto* out =
+ b.create<sem::Array>(el_ty, el_count, el_align, static_cast<uint32_t>(size),
+ static_cast<uint32_t>(stride), static_cast<uint32_t>(implicit_stride));
// Maximum nesting depth of composite types
// https://gpuweb.github.io/gpuweb/wgsl/#limits
@@ -4735,7 +4736,7 @@
return true;
}
- if (auto* arr = ty->As<core::type::Array>()) {
+ if (auto* arr = ty->As<sem::Array>()) {
if (address_space != core::AddressSpace::kStorage) {
if (arr->Count()->Is<core::type::RuntimeArrayCount>()) {
AddError("runtime-sized arrays can only be used in the <storage> address space",
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index 458546e..45e487f 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -484,12 +484,12 @@
/// @param el_ty the Array element type
/// @param el_count the number of elements in the array.
/// @param explicit_stride the explicit byte stride of the array. Zero means implicit stride.
- core::type::Array* Array(const Source& array_source,
- const Source& el_source,
- const Source& count_source,
- const core::type::Type* el_ty,
- const core::type::ArrayCount* el_count,
- uint32_t explicit_stride);
+ sem::Array* Array(const Source& array_source,
+ const Source& el_source,
+ const Source& count_source,
+ const core::type::Type* el_ty,
+ const core::type::ArrayCount* el_count,
+ uint32_t explicit_stride);
/// Builds and returns the semantic information for the alias `alias`.
/// This method does not mark the ast::Alias node, nor attach the generated
@@ -634,8 +634,8 @@
// ArrayConstructorSig represents a unique array constructor signature.
// It is a tuple of the array type, number of arguments provided and earliest evaluation stage.
- using ArrayConstructorSig = tint::UnorderedKeyWrapper<
- std::tuple<const core::type::Array*, size_t, core::EvaluationStage>>;
+ using ArrayConstructorSig =
+ tint::UnorderedKeyWrapper<std::tuple<const sem::Array*, size_t, core::EvaluationStage>>;
// StructConstructorSig represents a unique structure constructor signature.
// It is a tuple of the structure type, number of arguments provided and earliest evaluation
diff --git a/src/tint/lang/wgsl/resolver/resolver_helper_test.h b/src/tint/lang/wgsl/resolver/resolver_helper_test.h
index f7bda4a..f15027c 100644
--- a/src/tint/lang/wgsl/resolver/resolver_helper_test.h
+++ b/src/tint/lang/wgsl/resolver/resolver_helper_test.h
@@ -28,6 +28,7 @@
#include "src/tint/lang/core/type/abstract_int.h"
#include "src/tint/lang/wgsl/program/program_builder.h"
#include "src/tint/lang/wgsl/resolver/resolver.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/statement.h"
#include "src/tint/lang/wgsl/sem/value_expression.h"
#include "src/tint/lang/wgsl/sem/variable.h"
@@ -682,7 +683,7 @@
} else {
count = b.create<core::type::ConstantArrayCount>(N);
}
- return b.create<core::type::Array>(
+ return b.create<sem::Array>(
/* element */ el,
/* count */ count,
/* align */ el->Align(),
diff --git a/src/tint/lang/wgsl/resolver/resolver_test.cc b/src/tint/lang/wgsl/resolver/resolver_test.cc
index 17a039d..3fc4a87 100644
--- a/src/tint/lang/wgsl/resolver/resolver_test.cc
+++ b/src/tint/lang/wgsl/resolver/resolver_test.cc
@@ -39,6 +39,7 @@
#include "src/tint/lang/wgsl/ast/variable_decl_statement.h"
#include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/lang/wgsl/sem/function.h"
#include "src/tint/lang/wgsl/sem/member_accessor_expression.h"
@@ -423,7 +424,7 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref, nullptr);
- auto* ary = ref->StoreType()->As<core::type::Array>();
+ auto* ary = ref->StoreType()->As<sem::Array>();
EXPECT_EQ(ary->Count(), create<core::type::ConstantArrayCount>(10u));
}
@@ -436,7 +437,7 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref, nullptr);
- auto* ary = ref->StoreType()->As<core::type::Array>();
+ auto* ary = ref->StoreType()->As<sem::Array>();
EXPECT_EQ(ary->Count(), create<core::type::ConstantArrayCount>(10u));
}
@@ -451,7 +452,7 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref, nullptr);
- auto* ary = ref->StoreType()->As<core::type::Array>();
+ auto* ary = ref->StoreType()->As<sem::Array>();
EXPECT_EQ(ary->Count(), create<core::type::ConstantArrayCount>(10u));
}
@@ -466,7 +467,7 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref, nullptr);
- auto* ary = ref->StoreType()->As<core::type::Array>();
+ auto* ary = ref->StoreType()->As<sem::Array>();
EXPECT_EQ(ary->Count(), create<core::type::ConstantArrayCount>(10u));
}
@@ -481,7 +482,7 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref, nullptr);
- auto* ary = ref->StoreType()->As<core::type::Array>();
+ auto* ary = ref->StoreType()->As<sem::Array>();
auto* sem_override = Sem().Get(override);
ASSERT_NE(sem_override, nullptr);
EXPECT_EQ(ary->Count(), create<sem::NamedOverrideArrayCount>(sem_override));
@@ -500,12 +501,12 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref_a = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref_a, nullptr);
- auto* ary_a = ref_a->StoreType()->As<core::type::Array>();
+ auto* ary_a = ref_a->StoreType()->As<sem::Array>();
ASSERT_NE(TypeOf(b), nullptr);
auto* ref_b = TypeOf(b)->As<core::type::Reference>();
ASSERT_NE(ref_b, nullptr);
- auto* ary_b = ref_b->StoreType()->As<core::type::Array>();
+ auto* ary_b = ref_b->StoreType()->As<sem::Array>();
auto* sem_override = Sem().Get(override);
ASSERT_NE(sem_override, nullptr);
@@ -526,7 +527,7 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref, nullptr);
- auto* ary = ref->StoreType()->As<core::type::Array>();
+ auto* ary = ref->StoreType()->As<sem::Array>();
auto* sem_override = Sem().Get(override);
ASSERT_NE(sem_override, nullptr);
EXPECT_EQ(ary->Count(), create<sem::UnnamedOverrideArrayCount>(Sem().Get(cnt)));
@@ -547,12 +548,12 @@
ASSERT_NE(TypeOf(a), nullptr);
auto* ref_a = TypeOf(a)->As<core::type::Reference>();
ASSERT_NE(ref_a, nullptr);
- auto* ary_a = ref_a->StoreType()->As<core::type::Array>();
+ auto* ary_a = ref_a->StoreType()->As<sem::Array>();
ASSERT_NE(TypeOf(b), nullptr);
auto* ref_b = TypeOf(b)->As<core::type::Reference>();
ASSERT_NE(ref_b, nullptr);
- auto* ary_b = ref_b->StoreType()->As<core::type::Array>();
+ auto* ary_b = ref_b->StoreType()->As<sem::Array>();
auto* sem_override = Sem().Get(override);
ASSERT_NE(sem_override, nullptr);
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index ba87a8e..762db30 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -21,7 +21,6 @@
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/type/abstract_numeric.h"
-#include "src/tint/lang/core/type/array.h"
#include "src/tint/lang/core/type/atomic.h"
#include "src/tint/lang/core/type/depth_multisampled_texture.h"
#include "src/tint/lang/core/type/depth_texture.h"
@@ -53,6 +52,7 @@
#include "src/tint/lang/wgsl/ast/unary_op_expression.h"
#include "src/tint/lang/wgsl/ast/variable_decl_statement.h"
#include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/break_if_statement.h"
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/lang/wgsl/sem/for_loop_statement.h"
@@ -202,7 +202,7 @@
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
bool Validator::IsPlain(const core::type::Type* type) const {
return type->IsAnyOf<core::type::Scalar, core::type::Atomic, core::type::Vector,
- core::type::Matrix, core::type::Array, core::type::Struct>();
+ core::type::Matrix, sem::Array, core::type::Struct>();
}
// https://gpuweb.github.io/gpuweb/wgsl/#fixed-footprint-types
@@ -212,7 +212,7 @@
[&](const core::type::Vector*) { return true; }, //
[&](const core::type::Matrix*) { return true; }, //
[&](const core::type::Atomic*) { return true; },
- [&](const core::type::Array* arr) {
+ [&](const sem::Array* arr) {
return !arr->Count()->Is<core::type::RuntimeArrayCount>() &&
IsFixedFootprint(arr->ElemType());
},
@@ -236,7 +236,7 @@
type, //
[&](const core::type::Vector* vec) { return IsHostShareable(vec->type()); },
[&](const core::type::Matrix* mat) { return IsHostShareable(mat->type()); },
- [&](const core::type::Array* arr) { return IsHostShareable(arr->ElemType()); },
+ [&](const sem::Array* arr) { return IsHostShareable(arr->ElemType()); },
[&](const core::type::Struct* str) {
for (auto* member : str->Members()) {
if (!IsHostShareable(member->Type())) {
@@ -416,7 +416,7 @@
auto is_uniform_struct_or_array = [address_space](const core::type::Type* ty) {
return address_space == core::AddressSpace::kUniform &&
- ty->IsAnyOf<core::type::Array, core::type::Struct>();
+ ty->IsAnyOf<sem::Array, core::type::Struct>();
};
auto is_uniform_struct = [address_space](const core::type::Type* ty) {
@@ -523,7 +523,7 @@
}
// For uniform buffer array members, validate that array elements are aligned to 16 bytes
- if (auto* arr = store_ty->As<core::type::Array>()) {
+ if (auto* arr = store_ty->As<sem::Array>()) {
// Recurse into the element type.
// TODO(crbug.com/tint/1388): Ideally we'd pass the source for nested element type here, but
// we can't easily get that from the semantic node. We should consider recursing through the
@@ -1889,7 +1889,7 @@
}
bool Validator::ArrayConstructor(const ast::CallExpression* ctor,
- const core::type::Array* array_type) const {
+ const sem::Array* array_type) const {
auto& values = ctor->args;
auto* elem_ty = array_type->ElemType();
for (auto* value : values) {
@@ -2069,7 +2069,7 @@
return true;
}
-bool Validator::Array(const core::type::Array* arr, const Source& el_source) const {
+bool Validator::Array(const sem::Array* arr, const Source& el_source) const {
auto* el_ty = arr->ElemType();
if (!IsPlain(el_ty)) {
@@ -2123,7 +2123,7 @@
auto has_index = false;
Hashset<std::pair<uint32_t, uint32_t>, 8> locationsAndIndexes;
for (auto* member : str->Members()) {
- if (auto* r = member->Type()->As<core::type::Array>()) {
+ if (auto* r = member->Type()->As<sem::Array>()) {
if (r->Count()->Is<core::type::RuntimeArrayCount>()) {
if (member != str->Members().Back()) {
AddError("runtime arrays may only appear as the last member of a struct",
@@ -2607,7 +2607,7 @@
}
bool Validator::IsArrayWithOverrideCount(const core::type::Type* ty) const {
- if (auto* arr = ty->UnwrapRef()->As<core::type::Array>()) {
+ if (auto* arr = ty->UnwrapRef()->As<sem::Array>()) {
if (arr->Count()->IsAnyOf<sem::NamedOverrideArrayCount, sem::UnnamedOverrideArrayCount>()) {
return true;
}
@@ -2715,7 +2715,7 @@
return true;
},
[&](const core::type::Struct*) { return check_sub_atomics(); }, //
- [&](const core::type::Array*) { return check_sub_atomics(); }, //
+ [&](const sem::Array*) { return check_sub_atomics(); }, //
[&](Default) { return true; });
}
diff --git a/src/tint/lang/wgsl/resolver/validator.h b/src/tint/lang/wgsl/resolver/validator.h
index ecce5ba..e5df0f1 100644
--- a/src/tint/lang/wgsl/resolver/validator.h
+++ b/src/tint/lang/wgsl/resolver/validator.h
@@ -173,7 +173,7 @@
/// @param el_source the source of the array element, or the array if the array does not have a
/// locally-declared element AST node.
/// @returns true on success, false otherwise.
- bool Array(const core::type::Array* arr, const Source& el_source) const;
+ bool Array(const sem::Array* arr, const Source& el_source) const;
/// Validates an array stride attribute
/// @param attr the stride attribute to validate
@@ -452,7 +452,7 @@
/// @param ctor the call expresion to validate
/// @param arr_type the type of the array
/// @returns true on success, false otherwise
- bool ArrayConstructor(const ast::CallExpression* ctor, const core::type::Array* arr_type) const;
+ bool ArrayConstructor(const ast::CallExpression* ctor, const sem::Array* arr_type) const;
/// Validates a texture builtin function
/// @param call the builtin call to validate
diff --git a/src/tint/lang/wgsl/resolver/validator_is_storeable_test.cc b/src/tint/lang/wgsl/resolver/validator_is_storeable_test.cc
index 8674a75..0290231 100644
--- a/src/tint/lang/wgsl/resolver/validator_is_storeable_test.cc
+++ b/src/tint/lang/wgsl/resolver/validator_is_storeable_test.cc
@@ -17,6 +17,7 @@
#include "gmock/gmock.h"
#include "src/tint/lang/core/type/atomic.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
namespace tint::resolver {
namespace {
@@ -89,14 +90,14 @@
}
TEST_F(ValidatorIsStorableTest, ArraySizedOfStorable) {
- auto* arr = create<core::type::Array>(
- create<core::type::I32>(), create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<core::type::I32>(),
+ create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
EXPECT_TRUE(v()->IsStorable(arr));
}
TEST_F(ValidatorIsStorableTest, ArrayUnsizedOfStorable) {
- auto* arr = create<core::type::Array>(create<core::type::I32>(),
- create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<core::type::I32>(),
+ create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
EXPECT_TRUE(v()->IsStorable(arr));
}
diff --git a/src/tint/lang/wgsl/resolver/value_constructor_validation_test.cc b/src/tint/lang/wgsl/resolver/value_constructor_validation_test.cc
index 0dcd3a1..c962e18 100644
--- a/src/tint/lang/wgsl/resolver/value_constructor_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/value_constructor_validation_test.cc
@@ -15,6 +15,7 @@
#include "gmock/gmock.h"
#include "src/tint/lang/core/type/reference.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
+#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/value_constructor.h"
#include "src/tint/lang/wgsl/sem/value_conversion.h"
#include "src/tint/utils/text/string_stream.h"
@@ -489,7 +490,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -505,7 +506,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -524,7 +525,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -543,7 +544,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -562,7 +563,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -581,7 +582,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -600,7 +601,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -621,7 +622,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
@@ -645,7 +646,7 @@
auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
- EXPECT_TRUE(call->Type()->Is<core::type::Array>());
+ EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::ValueConstructor>();
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
diff --git a/src/tint/lang/wgsl/sem/BUILD.bazel b/src/tint/lang/wgsl/sem/BUILD.bazel
index a014edf..a7abdd6 100644
--- a/src/tint/lang/wgsl/sem/BUILD.bazel
+++ b/src/tint/lang/wgsl/sem/BUILD.bazel
@@ -27,6 +27,7 @@
name = "sem",
srcs = [
"accessor_expression.cc",
+ "array.cc",
"array_count.cc",
"behavior.cc",
"block_statement.cc",
@@ -60,6 +61,7 @@
],
hdrs = [
"accessor_expression.h",
+ "array.h",
"array_count.h",
"behavior.h",
"block_statement.h",
diff --git a/src/tint/lang/wgsl/sem/BUILD.cmake b/src/tint/lang/wgsl/sem/BUILD.cmake
index 6e545fa..29749a5 100644
--- a/src/tint/lang/wgsl/sem/BUILD.cmake
+++ b/src/tint/lang/wgsl/sem/BUILD.cmake
@@ -28,6 +28,8 @@
tint_add_target(tint_lang_wgsl_sem lib
lang/wgsl/sem/accessor_expression.cc
lang/wgsl/sem/accessor_expression.h
+ lang/wgsl/sem/array.cc
+ lang/wgsl/sem/array.h
lang/wgsl/sem/array_count.cc
lang/wgsl/sem/array_count.h
lang/wgsl/sem/behavior.cc
diff --git a/src/tint/lang/wgsl/sem/BUILD.gn b/src/tint/lang/wgsl/sem/BUILD.gn
index bdce811..f0465ba 100644
--- a/src/tint/lang/wgsl/sem/BUILD.gn
+++ b/src/tint/lang/wgsl/sem/BUILD.gn
@@ -33,6 +33,8 @@
sources = [
"accessor_expression.cc",
"accessor_expression.h",
+ "array.cc",
+ "array.h",
"array_count.cc",
"array_count.h",
"behavior.cc",
diff --git a/src/tint/lang/wgsl/sem/array.cc b/src/tint/lang/wgsl/sem/array.cc
new file mode 100644
index 0000000..3793bb6
--- /dev/null
+++ b/src/tint/lang/wgsl/sem/array.cc
@@ -0,0 +1,31 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/lang/wgsl/sem/array.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::Array);
+
+namespace tint::sem {
+
+Array::Array(core::type::Type const* element,
+ const core::type::ArrayCount* count,
+ uint32_t align,
+ uint32_t size,
+ uint32_t stride,
+ uint32_t implicit_stride)
+ : Base(element, count, align, size, stride, implicit_stride) {}
+
+Array::~Array() = default;
+
+} // namespace tint::sem
diff --git a/src/tint/lang/wgsl/sem/array.h b/src/tint/lang/wgsl/sem/array.h
new file mode 100644
index 0000000..82c635a
--- /dev/null
+++ b/src/tint/lang/wgsl/sem/array.h
@@ -0,0 +1,55 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0(the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_LANG_WGSL_SEM_ARRAY_H_
+#define SRC_TINT_LANG_WGSL_SEM_ARRAY_H_
+
+#include "src/tint/lang/core/type/array.h"
+#include "src/tint/utils/containers/unique_vector.h"
+
+/// Forward declarations
+namespace tint::sem {
+class GlobalVariable;
+}
+
+namespace tint::sem {
+
+/// Array holds the semantic information for Arrays.
+class Array final : public Castable<Array, core::type::Array> {
+ public:
+ /// Constructor
+ /// @param element the array element type
+ /// @param count the number of elements in the array.
+ /// @param align the byte alignment of the array
+ /// @param size the byte size of the array. The size will be 0 if the array element count is
+ /// pipeline overridable.
+ /// @param stride the number of bytes from the start of one element of the
+ /// array to the start of the next element
+ /// @param implicit_stride the number of bytes from the start of one element
+ /// of the array to the start of the next element, if there was no `@stride`
+ /// attribute applied.
+ Array(core::type::Type const* element,
+ const core::type::ArrayCount* count,
+ uint32_t align,
+ uint32_t size,
+ uint32_t stride,
+ uint32_t implicit_stride);
+
+ /// Destructor
+ ~Array() override;
+};
+
+} // namespace tint::sem
+
+#endif // SRC_TINT_LANG_WGSL_SEM_ARRAY_H_
diff --git a/src/tint/lang/wgsl/sem/helper_test.h b/src/tint/lang/wgsl/sem/helper_test.h
index ece8694..fb45117 100644
--- a/src/tint/lang/wgsl/sem/helper_test.h
+++ b/src/tint/lang/wgsl/sem/helper_test.h
@@ -36,8 +36,11 @@
return resolver::Resolve(*this);
}
};
+
+/// An alias to TestHelper templated without a test parameter
using TestHelper = TestHelperBase<testing::Test>;
+/// An alias to TestHelper templated with the parameter type T
template <typename T>
using TestParamHelper = TestHelperBase<testing::TestWithParam<T>>;
diff --git a/src/tint/lang/wgsl/sem/pipeline_stage_set.h b/src/tint/lang/wgsl/sem/pipeline_stage_set.h
index c21796f..417235b 100644
--- a/src/tint/lang/wgsl/sem/pipeline_stage_set.h
+++ b/src/tint/lang/wgsl/sem/pipeline_stage_set.h
@@ -20,6 +20,7 @@
namespace tint::sem {
+/// A set of PipelineStage
using PipelineStageSet = tint::EnumSet<ast::PipelineStage>;
} // namespace tint::sem