[wgsl-reader] Allow array decorations to have multiple blocks.
This CL updates the WGSL parser to allow array decorations to accept multiple blocks. The stride decoration on arrays was turned into a proper decoration object instead of just storing the stride directly. Bug: tint:240 Change-Id: I6cdc7400d8847e3e043b846ea5c9f86cb795cf86 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/29780 Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
71d69e5ed3
commit
eb5d3e147d
5
BUILD.gn
5
BUILD.gn
|
@ -219,6 +219,8 @@ source_set("libtint_core_src") {
|
||||||
sources = [
|
sources = [
|
||||||
"src/ast/array_accessor_expression.cc",
|
"src/ast/array_accessor_expression.cc",
|
||||||
"src/ast/array_accessor_expression.h",
|
"src/ast/array_accessor_expression.h",
|
||||||
|
"src/ast/array_decoration.cc",
|
||||||
|
"src/ast/array_decoration.h",
|
||||||
"src/ast/assignment_statement.cc",
|
"src/ast/assignment_statement.cc",
|
||||||
"src/ast/assignment_statement.h",
|
"src/ast/assignment_statement.h",
|
||||||
"src/ast/binary_expression.cc",
|
"src/ast/binary_expression.cc",
|
||||||
|
@ -303,6 +305,8 @@ source_set("libtint_core_src") {
|
||||||
"src/ast/statement.h",
|
"src/ast/statement.h",
|
||||||
"src/ast/storage_class.cc",
|
"src/ast/storage_class.cc",
|
||||||
"src/ast/storage_class.h",
|
"src/ast/storage_class.h",
|
||||||
|
"src/ast/stride_decoration.cc",
|
||||||
|
"src/ast/stride_decoration.h",
|
||||||
"src/ast/struct.cc",
|
"src/ast/struct.cc",
|
||||||
"src/ast/struct.h",
|
"src/ast/struct.h",
|
||||||
"src/ast/struct_decoration.cc",
|
"src/ast/struct_decoration.cc",
|
||||||
|
@ -727,6 +731,7 @@ source_set("tint_unittests_core_src") {
|
||||||
"src/ast/set_decoration_test.cc",
|
"src/ast/set_decoration_test.cc",
|
||||||
"src/ast/sint_literal_test.cc",
|
"src/ast/sint_literal_test.cc",
|
||||||
"src/ast/stage_decoration_test.cc",
|
"src/ast/stage_decoration_test.cc",
|
||||||
|
"src/ast/stride_decoration_test.cc",
|
||||||
"src/ast/struct_member_offset_decoration_test.cc",
|
"src/ast/struct_member_offset_decoration_test.cc",
|
||||||
"src/ast/struct_member_test.cc",
|
"src/ast/struct_member_test.cc",
|
||||||
"src/ast/struct_test.cc",
|
"src/ast/struct_test.cc",
|
||||||
|
|
|
@ -40,6 +40,8 @@ set(TINT_LIB_SRCS
|
||||||
../include/tint/tint.h
|
../include/tint/tint.h
|
||||||
ast/array_accessor_expression.cc
|
ast/array_accessor_expression.cc
|
||||||
ast/array_accessor_expression.h
|
ast/array_accessor_expression.h
|
||||||
|
ast/array_decoration.cc
|
||||||
|
ast/array_decoration.h
|
||||||
ast/assignment_statement.cc
|
ast/assignment_statement.cc
|
||||||
ast/assignment_statement.h
|
ast/assignment_statement.h
|
||||||
ast/binary_expression.cc
|
ast/binary_expression.cc
|
||||||
|
@ -124,10 +126,12 @@ set(TINT_LIB_SRCS
|
||||||
ast/statement.h
|
ast/statement.h
|
||||||
ast/storage_class.cc
|
ast/storage_class.cc
|
||||||
ast/storage_class.h
|
ast/storage_class.h
|
||||||
ast/struct_decoration.cc
|
ast/stride_decoration.cc
|
||||||
ast/struct_decoration.h
|
ast/stride_decoration.h
|
||||||
ast/struct.cc
|
ast/struct.cc
|
||||||
ast/struct.h
|
ast/struct.h
|
||||||
|
ast/struct_decoration.cc
|
||||||
|
ast/struct_decoration.h
|
||||||
ast/struct_member.cc
|
ast/struct_member.cc
|
||||||
ast/struct_member.h
|
ast/struct_member.h
|
||||||
ast/struct_member_decoration.cc
|
ast/struct_member_decoration.cc
|
||||||
|
@ -337,6 +341,7 @@ set(TINT_TEST_SRCS
|
||||||
ast/set_decoration_test.cc
|
ast/set_decoration_test.cc
|
||||||
ast/sint_literal_test.cc
|
ast/sint_literal_test.cc
|
||||||
ast/stage_decoration_test.cc
|
ast/stage_decoration_test.cc
|
||||||
|
ast/stride_decoration_test.cc
|
||||||
ast/struct_member_test.cc
|
ast/struct_member_test.cc
|
||||||
ast/struct_member_offset_decoration_test.cc
|
ast/struct_member_offset_decoration_test.cc
|
||||||
ast/struct_test.cc
|
ast/struct_test.cc
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// 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_decoration.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace ast {
|
||||||
|
|
||||||
|
ArrayDecoration::ArrayDecoration() = default;
|
||||||
|
|
||||||
|
ArrayDecoration::~ArrayDecoration() = default;
|
||||||
|
|
||||||
|
bool ArrayDecoration::IsStride() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrideDecoration* ArrayDecoration::AsStride() {
|
||||||
|
assert(IsStride());
|
||||||
|
return static_cast<StrideDecoration*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ast
|
||||||
|
} // namespace tint
|
|
@ -0,0 +1,51 @@
|
||||||
|
// 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_DECORATION_H_
|
||||||
|
#define SRC_AST_ARRAY_DECORATION_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace ast {
|
||||||
|
|
||||||
|
class StrideDecoration;
|
||||||
|
|
||||||
|
/// A decoration attached to an array
|
||||||
|
class ArrayDecoration {
|
||||||
|
public:
|
||||||
|
virtual ~ArrayDecoration();
|
||||||
|
|
||||||
|
/// @returns true if this is a stride decoration
|
||||||
|
virtual bool IsStride() const;
|
||||||
|
|
||||||
|
/// @returns the decoration as a stride decoration
|
||||||
|
StrideDecoration* AsStride();
|
||||||
|
|
||||||
|
/// @returns the decoration as a string
|
||||||
|
virtual std::string to_str() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ArrayDecoration();
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A list of unique array decorations
|
||||||
|
using ArrayDecorationList = std::vector<std::unique_ptr<ArrayDecoration>>;
|
||||||
|
|
||||||
|
} // namespace ast
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_AST_ARRAY_DECORATION_H_
|
|
@ -0,0 +1,33 @@
|
||||||
|
// 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/stride_decoration.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace ast {
|
||||||
|
|
||||||
|
StrideDecoration::StrideDecoration(uint32_t stride) : stride_(stride) {}
|
||||||
|
|
||||||
|
bool StrideDecoration::IsStride() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrideDecoration::~StrideDecoration() = default;
|
||||||
|
|
||||||
|
std::string StrideDecoration::to_str() const {
|
||||||
|
return "stride " + std::to_string(stride_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ast
|
||||||
|
} // namespace tint
|
|
@ -0,0 +1,51 @@
|
||||||
|
// 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_STRIDE_DECORATION_H_
|
||||||
|
#define SRC_AST_STRIDE_DECORATION_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/ast/array_decoration.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace ast {
|
||||||
|
|
||||||
|
/// A stride decoration
|
||||||
|
class StrideDecoration : public ArrayDecoration {
|
||||||
|
public:
|
||||||
|
/// constructor
|
||||||
|
/// @param stride the stride value
|
||||||
|
explicit StrideDecoration(uint32_t stride);
|
||||||
|
~StrideDecoration() override;
|
||||||
|
|
||||||
|
/// @returns true if this is a stride decoration
|
||||||
|
bool IsStride() const override;
|
||||||
|
|
||||||
|
/// @returns the stride value
|
||||||
|
uint32_t stride() const { return stride_; }
|
||||||
|
|
||||||
|
/// @returns the decoration as a string
|
||||||
|
std::string to_str() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t stride_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ast
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_AST_STRIDE_DECORATION_H_
|
|
@ -0,0 +1,37 @@
|
||||||
|
// 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/stride_decoration.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace ast {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using StrideDecorationTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(StrideDecorationTest, Creation) {
|
||||||
|
StrideDecoration d{2};
|
||||||
|
EXPECT_EQ(2u, d.stride());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StrideDecorationTest, Is) {
|
||||||
|
StrideDecoration d{2};
|
||||||
|
EXPECT_TRUE(d.IsStride());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace ast
|
||||||
|
} // namespace tint
|
|
@ -16,6 +16,7 @@
|
||||||
#define SRC_AST_STRUCT_DECORATION_H_
|
#define SRC_AST_STRUCT_DECORATION_H_
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/type/array_type.h"
|
#include "src/ast/type/array_type.h"
|
||||||
|
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace type {
|
namespace type {
|
||||||
|
@ -31,6 +33,24 @@ bool ArrayType::IsArray() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ArrayType::array_stride() const {
|
||||||
|
for (const auto& deco : decos_) {
|
||||||
|
if (deco->IsStride()) {
|
||||||
|
return deco->AsStride()->stride();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArrayType::has_array_stride() const {
|
||||||
|
for (const auto& deco : decos_) {
|
||||||
|
if (deco->IsStride()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ArrayType::type_name() const {
|
std::string ArrayType::type_name() const {
|
||||||
assert(subtype_);
|
assert(subtype_);
|
||||||
|
|
||||||
|
@ -38,7 +58,7 @@ std::string ArrayType::type_name() const {
|
||||||
if (!IsRuntimeArray())
|
if (!IsRuntimeArray())
|
||||||
type_name += "_" + std::to_string(size_);
|
type_name += "_" + std::to_string(size_);
|
||||||
if (has_array_stride())
|
if (has_array_stride())
|
||||||
type_name += "_stride_" + std::to_string(array_stride_);
|
type_name += "_stride_" + std::to_string(array_stride());
|
||||||
|
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/ast/array_decoration.h"
|
||||||
#include "src/ast/type/type.h"
|
#include "src/ast/type/type.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -45,13 +46,18 @@ class ArrayType : public Type {
|
||||||
/// i.e. the size is determined at runtime
|
/// i.e. the size is determined at runtime
|
||||||
bool IsRuntimeArray() const { return size_ == 0; }
|
bool IsRuntimeArray() const { return size_ == 0; }
|
||||||
|
|
||||||
/// Sets the array stride
|
/// Sets the array decorations
|
||||||
/// @param stride the stride to set
|
/// @param decos the decorations to set
|
||||||
void set_array_stride(uint32_t stride) { array_stride_ = stride; }
|
void set_decorations(ast::ArrayDecorationList decos) {
|
||||||
|
decos_ = std::move(decos);
|
||||||
|
}
|
||||||
|
/// @returns the array decorations
|
||||||
|
const ArrayDecorationList& decorations() const { return decos_; }
|
||||||
|
|
||||||
/// @returns the array stride or 0 if none set.
|
/// @returns the array stride or 0 if none set.
|
||||||
uint32_t array_stride() const { return array_stride_; }
|
uint32_t array_stride() const;
|
||||||
/// @returns true if the array has a stride set
|
/// @returns true if the array has a stride set
|
||||||
bool has_array_stride() const { return array_stride_ != 0; }
|
bool has_array_stride() const;
|
||||||
|
|
||||||
/// @returns the array type
|
/// @returns the array type
|
||||||
Type* type() const { return subtype_; }
|
Type* type() const { return subtype_; }
|
||||||
|
@ -64,7 +70,7 @@ class ArrayType : public Type {
|
||||||
private:
|
private:
|
||||||
Type* subtype_ = nullptr;
|
Type* subtype_ = nullptr;
|
||||||
uint32_t size_ = 0;
|
uint32_t size_ = 0;
|
||||||
uint32_t array_stride_ = 0;
|
ast::ArrayDecorationList decos_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace type
|
} // namespace type
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "src/ast/type/array_type.h"
|
#include "src/ast/type/array_type.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/type/i32_type.h"
|
#include "src/ast/type/i32_type.h"
|
||||||
#include "src/ast/type/u32_type.h"
|
#include "src/ast/type/u32_type.h"
|
||||||
|
|
||||||
|
@ -75,8 +76,11 @@ TEST_F(ArrayTypeTest, TypeName_RuntimeArray) {
|
||||||
|
|
||||||
TEST_F(ArrayTypeTest, TypeName_WithStride) {
|
TEST_F(ArrayTypeTest, TypeName_WithStride) {
|
||||||
I32Type i32;
|
I32Type i32;
|
||||||
|
ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<StrideDecoration>(16));
|
||||||
|
|
||||||
ArrayType arr{&i32, 3};
|
ArrayType arr{&i32, 3};
|
||||||
arr.set_array_stride(16);
|
arr.set_decorations(std::move(decos));
|
||||||
EXPECT_EQ(arr.type_name(), "__array__i32_3_stride_16");
|
EXPECT_EQ(arr.type_name(), "__array__i32_3_stride_16");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_decoration.h"
|
#include "src/ast/struct_decoration.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
|
@ -772,7 +773,9 @@ bool ParserImpl::ApplyArrayDecorations(
|
||||||
return Fail() << "invalid array type ID " << type_id
|
return Fail() << "invalid array type ID " << type_id
|
||||||
<< ": multiple ArrayStride decorations";
|
<< ": multiple ArrayStride decorations";
|
||||||
}
|
}
|
||||||
ast_type->set_array_stride(stride);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(stride));
|
||||||
|
ast_type->set_decorations(std::move(decos));
|
||||||
} else {
|
} else {
|
||||||
return Fail() << "invalid array type ID " << type_id
|
return Fail() << "invalid array type ID " << type_id
|
||||||
<< ": unknown decoration "
|
<< ": unknown decoration "
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
#include "src/ast/switch_statement.h"
|
#include "src/ast/switch_statement.h"
|
||||||
#include "src/ast/type/alias_type.h"
|
#include "src/ast/type/alias_type.h"
|
||||||
|
@ -1105,9 +1106,9 @@ ast::type::AliasType* ParserImpl::type_alias() {
|
||||||
// | VEC3 LESS_THAN type_decl GREATER_THAN
|
// | VEC3 LESS_THAN type_decl GREATER_THAN
|
||||||
// | VEC4 LESS_THAN type_decl GREATER_THAN
|
// | VEC4 LESS_THAN type_decl GREATER_THAN
|
||||||
// | PTR LESS_THAN storage_class, type_decl GREATER_THAN
|
// | PTR LESS_THAN storage_class, type_decl GREATER_THAN
|
||||||
// | array_decoration_list? ARRAY LESS_THAN type_decl COMMA
|
// | array_decoration_list* ARRAY LESS_THAN type_decl COMMA
|
||||||
// INT_LITERAL GREATER_THAN
|
// INT_LITERAL GREATER_THAN
|
||||||
// | array_decoration_list? ARRAY LESS_THAN type_decl
|
// | array_decoration_list* ARRAY LESS_THAN type_decl
|
||||||
// GREATER_THAN
|
// GREATER_THAN
|
||||||
// | MAT2x2 LESS_THAN type_decl GREATER_THAN
|
// | MAT2x2 LESS_THAN type_decl GREATER_THAN
|
||||||
// | MAT2x3 LESS_THAN type_decl GREATER_THAN
|
// | MAT2x3 LESS_THAN type_decl GREATER_THAN
|
||||||
|
@ -1153,19 +1154,28 @@ ast::type::Type* ParserImpl::type_decl() {
|
||||||
return type_decl_pointer(t);
|
return type_decl_pointer(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto deco = array_decoration_list();
|
ast::ArrayDecorationList decos;
|
||||||
|
for (;;) {
|
||||||
|
size_t s = decos.size();
|
||||||
|
if (!array_decoration_list(decos)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (decos.size() == s) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (has_error()) {
|
if (has_error()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (deco != 0) {
|
if (!decos.empty()) {
|
||||||
t = peek();
|
t = peek();
|
||||||
}
|
}
|
||||||
if (deco != 0 && !t.IsArray()) {
|
if (!decos.empty() && !t.IsArray()) {
|
||||||
set_error(t, "found array decoration but no array");
|
set_error(t, "found array decoration but no array");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (t.IsArray()) {
|
if (t.IsArray()) {
|
||||||
return type_decl_array(t, deco);
|
return type_decl_array(t, std::move(decos));
|
||||||
}
|
}
|
||||||
if (t.IsMat2x2() || t.IsMat2x3() || t.IsMat2x4() || t.IsMat3x2() ||
|
if (t.IsMat2x2() || t.IsMat2x3() || t.IsMat2x4() || t.IsMat3x2() ||
|
||||||
t.IsMat3x3() || t.IsMat3x4() || t.IsMat4x2() || t.IsMat4x3() ||
|
t.IsMat3x3() || t.IsMat3x4() || t.IsMat4x2() || t.IsMat4x3() ||
|
||||||
|
@ -1258,7 +1268,8 @@ ast::type::Type* ParserImpl::type_decl_vector(Token t) {
|
||||||
std::make_unique<ast::type::VectorType>(subtype, count));
|
std::make_unique<ast::type::VectorType>(subtype, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::type::Type* ParserImpl::type_decl_array(Token t, uint32_t stride) {
|
ast::type::Type* ParserImpl::type_decl_array(Token t,
|
||||||
|
ast::ArrayDecorationList decos) {
|
||||||
next(); // Consume the peek
|
next(); // Consume the peek
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
|
@ -1296,9 +1307,7 @@ ast::type::Type* ParserImpl::type_decl_array(Token t, uint32_t stride) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ty = std::make_unique<ast::type::ArrayType>(subtype, size);
|
auto ty = std::make_unique<ast::type::ArrayType>(subtype, size);
|
||||||
if (stride != 0) {
|
ty->set_decorations(std::move(decos));
|
||||||
ty->set_array_stride(stride);
|
|
||||||
}
|
|
||||||
return ctx_.type_mgr().Get(std::move(ty));
|
return ctx_.type_mgr().Get(std::move(ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,48 +1318,62 @@ ast::type::Type* ParserImpl::type_decl_array(Token t, uint32_t stride) {
|
||||||
//
|
//
|
||||||
// As there is currently only one decoration I'm combining these for now.
|
// As there is currently only one decoration I'm combining these for now.
|
||||||
// we can split apart later if needed.
|
// we can split apart later if needed.
|
||||||
uint32_t ParserImpl::array_decoration_list() {
|
bool ParserImpl::array_decoration_list(ast::ArrayDecorationList& decos) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsAttrLeft()) {
|
if (!t.IsAttrLeft()) {
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
t = peek(1);
|
t = peek(1);
|
||||||
if (!t.IsStride()) {
|
if (!t.IsStride()) {
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
next(); // consume the peek of [[
|
next(); // consume the peek of [[
|
||||||
next(); // consume the peek of stride
|
|
||||||
|
for (;;) {
|
||||||
|
t = next();
|
||||||
|
if (!t.IsStride()) {
|
||||||
|
set_error(t, "unknown array decoration");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsParenLeft()) {
|
if (!t.IsParenLeft()) {
|
||||||
set_error(t, "missing ( for stride attribute");
|
set_error(t, "missing ( for stride attribute");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsSintLiteral()) {
|
if (!t.IsSintLiteral()) {
|
||||||
set_error(t, "missing value for stride decoration");
|
set_error(t, "missing value for stride decoration");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
if (t.to_i32() < 0) {
|
if (t.to_i32() < 0) {
|
||||||
set_error(t, "invalid stride value: " + t.to_str());
|
set_error(t, "invalid stride value: " + t.to_str());
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t stride = static_cast<uint32_t>(t.to_i32());
|
uint32_t stride = static_cast<uint32_t>(t.to_i32());
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(stride));
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsParenRight()) {
|
if (!t.IsParenRight()) {
|
||||||
set_error(t, "missing ) for stride attribute");
|
set_error(t, "missing ) for stride attribute");
|
||||||
return 0;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = peek();
|
||||||
|
if (!t.IsComma()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next(); // Consume the peek
|
||||||
}
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsAttrRight()) {
|
if (!t.IsAttrRight()) {
|
||||||
set_error(t, "missing ]] for array decoration");
|
set_error(t, "missing ]] for array decoration");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
return stride;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::type::Type* ParserImpl::type_decl_matrix(Token t) {
|
ast::type::Type* ParserImpl::type_decl_matrix(Token t) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "src/ast/array_decoration.h"
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
|
@ -172,8 +173,8 @@ class ParserImpl {
|
||||||
std::unique_ptr<ast::StructMember> struct_member();
|
std::unique_ptr<ast::StructMember> struct_member();
|
||||||
/// Parses a `struct_member_decoration_decl` grammar element, appending newly
|
/// Parses a `struct_member_decoration_decl` grammar element, appending newly
|
||||||
/// parsed decorations to the end of |decos|.
|
/// parsed decorations to the end of |decos|.
|
||||||
/// @params decos the decoration list
|
/// @param decos the decoration list
|
||||||
/// @returns the list of decorations
|
/// @returns true if parsing was successful.
|
||||||
bool struct_member_decoration_decl(ast::StructMemberDecorationList& decos);
|
bool struct_member_decoration_decl(ast::StructMemberDecorationList& decos);
|
||||||
/// Parses a `struct_member_decoration` grammar element
|
/// Parses a `struct_member_decoration` grammar element
|
||||||
/// @returns the decoration or nullptr if none found
|
/// @returns the decoration or nullptr if none found
|
||||||
|
@ -395,8 +396,8 @@ class ParserImpl {
|
||||||
private:
|
private:
|
||||||
ast::type::Type* type_decl_pointer(Token t);
|
ast::type::Type* type_decl_pointer(Token t);
|
||||||
ast::type::Type* type_decl_vector(Token t);
|
ast::type::Type* type_decl_vector(Token t);
|
||||||
ast::type::Type* type_decl_array(Token t, uint32_t stride);
|
ast::type::Type* type_decl_array(Token t, ast::ArrayDecorationList decos);
|
||||||
uint32_t array_decoration_list();
|
bool array_decoration_list(ast::ArrayDecorationList& decos);
|
||||||
ast::type::Type* type_decl_matrix(Token t);
|
ast::type::Type* type_decl_matrix(Token t);
|
||||||
|
|
||||||
std::unique_ptr<ast::ConstructorExpression> const_expr_internal(
|
std::unique_ptr<ast::ConstructorExpression> const_expr_internal(
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/type/alias_type.h"
|
#include "src/ast/type/alias_type.h"
|
||||||
#include "src/ast/type/array_type.h"
|
#include "src/ast/type/array_type.h"
|
||||||
#include "src/ast/type/bool_type.h"
|
#include "src/ast/type/bool_type.h"
|
||||||
|
@ -423,6 +424,44 @@ TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Stride) {
|
||||||
EXPECT_EQ(a->array_stride(), 16u);
|
EXPECT_EQ(a->array_stride(), 16u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_OneBlock) {
|
||||||
|
auto* p = parser("[[stride(16), stride(32)]] array<f32>");
|
||||||
|
auto* t = p->type_decl();
|
||||||
|
ASSERT_NE(t, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
ASSERT_TRUE(t->IsArray());
|
||||||
|
|
||||||
|
auto* a = t->AsArray();
|
||||||
|
ASSERT_TRUE(a->IsRuntimeArray());
|
||||||
|
ASSERT_TRUE(a->type()->IsF32());
|
||||||
|
|
||||||
|
auto& decos = a->decorations();
|
||||||
|
ASSERT_EQ(decos.size(), 2u);
|
||||||
|
EXPECT_TRUE(decos[0]->IsStride());
|
||||||
|
EXPECT_EQ(decos[0]->AsStride()->stride(), 16u);
|
||||||
|
EXPECT_TRUE(decos[1]->IsStride());
|
||||||
|
EXPECT_EQ(decos[1]->AsStride()->stride(), 32u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_MultipleBlocks) {
|
||||||
|
auto* p = parser("[[stride(16)]] [[stride(32)]] array<f32>");
|
||||||
|
auto* t = p->type_decl();
|
||||||
|
ASSERT_NE(t, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
ASSERT_TRUE(t->IsArray());
|
||||||
|
|
||||||
|
auto* a = t->AsArray();
|
||||||
|
ASSERT_TRUE(a->IsRuntimeArray());
|
||||||
|
ASSERT_TRUE(a->type()->IsF32());
|
||||||
|
|
||||||
|
auto& decos = a->decorations();
|
||||||
|
ASSERT_EQ(decos.size(), 2u);
|
||||||
|
EXPECT_TRUE(decos[0]->IsStride());
|
||||||
|
EXPECT_EQ(decos[0]->AsStride()->stride(), 16u);
|
||||||
|
EXPECT_TRUE(decos[1]->IsStride());
|
||||||
|
EXPECT_EQ(decos[1]->AsStride()->stride(), 32u);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Array_Decoration_MissingArray) {
|
TEST_F(ParserImplTest, TypeDecl_Array_Decoration_MissingArray) {
|
||||||
auto* p = parser("[[stride(16)]] f32");
|
auto* p = parser("[[stride(16)]] f32");
|
||||||
auto* t = p->type_decl();
|
auto* t = p->type_decl();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "src/ast/decorated_variable.h"
|
#include "src/ast/decorated_variable.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_decoration.h"
|
#include "src/ast/struct_decoration.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
|
@ -215,7 +216,10 @@ void VertexPullingTransform::AddVertexStorageBuffers() {
|
||||||
// TODO(idanr): Make this readonly https://github.com/gpuweb/gpuweb/issues/935
|
// TODO(idanr): Make this readonly https://github.com/gpuweb/gpuweb/issues/935
|
||||||
// The array inside the struct definition
|
// The array inside the struct definition
|
||||||
auto internal_array = std::make_unique<ast::type::ArrayType>(GetU32Type());
|
auto internal_array = std::make_unique<ast::type::ArrayType>(GetU32Type());
|
||||||
internal_array->set_array_stride(4u);
|
ast::ArrayDecorationList ary_decos;
|
||||||
|
ary_decos.push_back(std::make_unique<ast::StrideDecoration>(4u));
|
||||||
|
internal_array->set_decorations(std::move(ary_decos));
|
||||||
|
|
||||||
auto* internal_array_type = ctx_->type_mgr().Get(std::move(internal_array));
|
auto* internal_array_type = ctx_->type_mgr().Get(std::move(internal_array));
|
||||||
|
|
||||||
// Creating the struct type
|
// Creating the struct type
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
|
@ -525,7 +526,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::ArrayType ary(&i32, 5);
|
ast::type::ArrayType ary(&i32, 5);
|
||||||
ary.set_array_stride(4);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(4));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
ast::StructMemberList members;
|
ast::StructMemberList members;
|
||||||
ast::StructMemberDecorationList a_deco;
|
ast::StructMemberDecorationList a_deco;
|
||||||
|
@ -573,7 +576,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::ArrayType ary(&i32, 5);
|
ast::type::ArrayType ary(&i32, 5);
|
||||||
ary.set_array_stride(4);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(4));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
ast::StructMemberList members;
|
ast::StructMemberList members;
|
||||||
ast::StructMemberDecorationList a_deco;
|
ast::StructMemberDecorationList a_deco;
|
||||||
|
@ -684,7 +689,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::ArrayType ary(&i32, 5);
|
ast::type::ArrayType ary(&i32, 5);
|
||||||
ary.set_array_stride(4);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(4));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
ast::StructMemberList members;
|
ast::StructMemberList members;
|
||||||
ast::StructMemberDecorationList a_deco;
|
ast::StructMemberDecorationList a_deco;
|
||||||
|
@ -937,7 +944,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
data.set_name("Data");
|
data.set_name("Data");
|
||||||
|
|
||||||
ast::type::ArrayType ary(&data, 4);
|
ast::type::ArrayType ary(&data, 4);
|
||||||
ary.set_array_stride(32);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
||||||
members.push_back(
|
members.push_back(
|
||||||
|
@ -1010,7 +1019,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
data.set_name("Data");
|
data.set_name("Data");
|
||||||
|
|
||||||
ast::type::ArrayType ary(&data, 4);
|
ast::type::ArrayType ary(&data, 4);
|
||||||
ary.set_array_stride(32);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
||||||
members.push_back(
|
members.push_back(
|
||||||
|
@ -1086,7 +1097,9 @@ TEST_F(
|
||||||
data.set_name("Data");
|
data.set_name("Data");
|
||||||
|
|
||||||
ast::type::ArrayType ary(&data, 4);
|
ast::type::ArrayType ary(&data, 4);
|
||||||
ary.set_array_stride(32);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
||||||
members.push_back(
|
members.push_back(
|
||||||
|
@ -1161,7 +1174,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
data.set_name("Data");
|
data.set_name("Data");
|
||||||
|
|
||||||
ast::type::ArrayType ary(&data, 4);
|
ast::type::ArrayType ary(&data, 4);
|
||||||
ary.set_array_stride(32);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
||||||
members.push_back(
|
members.push_back(
|
||||||
|
@ -1237,7 +1252,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
data.set_name("Data");
|
data.set_name("Data");
|
||||||
|
|
||||||
ast::type::ArrayType ary(&data, 4);
|
ast::type::ArrayType ary(&data, 4);
|
||||||
ary.set_array_stride(32);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
||||||
members.push_back(
|
members.push_back(
|
||||||
|
@ -1329,7 +1346,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
data.set_name("Data");
|
data.set_name("Data");
|
||||||
|
|
||||||
ast::type::ArrayType ary(&data, 4);
|
ast::type::ArrayType ary(&data, 4);
|
||||||
ary.set_array_stride(32);
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32));
|
||||||
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
|
||||||
members.push_back(
|
members.push_back(
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
|
@ -128,8 +129,12 @@ TEST_F(BuilderTest_Type, GenerateArray) {
|
||||||
|
|
||||||
TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
|
TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
|
|
||||||
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(16u));
|
||||||
|
|
||||||
ast::type::ArrayType ary(&i32, 4);
|
ast::type::ArrayType ary(&i32, 4);
|
||||||
ary.set_array_stride(16u);
|
ary.set_decorations(std::move(decos));
|
||||||
|
|
||||||
ast::Module mod;
|
ast::Module mod;
|
||||||
Builder b(&mod);
|
Builder b(&mod);
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
#include "src/ast/statement.h"
|
#include "src/ast/statement.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
|
@ -395,8 +396,10 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
||||||
} else if (type->IsArray()) {
|
} else if (type->IsArray()) {
|
||||||
auto* ary = type->AsArray();
|
auto* ary = type->AsArray();
|
||||||
|
|
||||||
if (ary->has_array_stride()) {
|
for (const auto& deco : ary->decorations()) {
|
||||||
out_ << "[[stride(" << ary->array_stride() << ")]] ";
|
if (deco->IsStride()) {
|
||||||
|
out_ << "[[stride(" << deco->AsStride()->stride() << ")]] ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out_ << "array<";
|
out_ << "array<";
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "src/ast/stride_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_decoration.h"
|
#include "src/ast/struct_decoration.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
|
@ -60,16 +61,33 @@ TEST_F(WgslGeneratorImplTest, EmitType_Array) {
|
||||||
EXPECT_EQ(g.result(), "array<bool, 4>");
|
EXPECT_EQ(g.result(), "array<bool, 4>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitType_Array_WithStride) {
|
TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) {
|
||||||
ast::type::BoolType b;
|
ast::type::BoolType b;
|
||||||
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(16u));
|
||||||
|
|
||||||
ast::type::ArrayType a(&b, 4);
|
ast::type::ArrayType a(&b, 4);
|
||||||
a.set_array_stride(16);
|
a.set_decorations(std::move(decos));
|
||||||
|
|
||||||
GeneratorImpl g;
|
GeneratorImpl g;
|
||||||
ASSERT_TRUE(g.EmitType(&a)) << g.error();
|
ASSERT_TRUE(g.EmitType(&a)) << g.error();
|
||||||
EXPECT_EQ(g.result(), "[[stride(16)]] array<bool, 4>");
|
EXPECT_EQ(g.result(), "[[stride(16)]] array<bool, 4>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WgslGeneratorImplTest, EmitType_Array_MultipleDecorations) {
|
||||||
|
ast::type::BoolType b;
|
||||||
|
ast::ArrayDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(16u));
|
||||||
|
decos.push_back(std::make_unique<ast::StrideDecoration>(32u));
|
||||||
|
|
||||||
|
ast::type::ArrayType a(&b, 4);
|
||||||
|
a.set_decorations(std::move(decos));
|
||||||
|
|
||||||
|
GeneratorImpl g;
|
||||||
|
ASSERT_TRUE(g.EmitType(&a)) << g.error();
|
||||||
|
EXPECT_EQ(g.result(), "[[stride(16)]] [[stride(32)]] array<bool, 4>");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) {
|
TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) {
|
||||||
ast::type::BoolType b;
|
ast::type::BoolType b;
|
||||||
ast::type::ArrayType a(&b);
|
ast::type::ArrayType a(&b);
|
||||||
|
|
Loading…
Reference in New Issue