ast: Rename ArrayAccessorExpression to IndexAccessorExpression
The object is not always an array. The index can be applied to vectors too. Change-Id: Ifb63d1862090d28cb48d692870e9dd01ddbce5df Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/68841 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
30848b6594
commit
a838bb718b
|
@ -487,7 +487,7 @@ fn f() {
|
||||||
.Functions()[0]
|
.Functions()[0]
|
||||||
->body->statements[2]
|
->body->statements[2]
|
||||||
->As<ast::AssignmentStatement>()
|
->As<ast::AssignmentStatement>()
|
||||||
->lhs->As<ast::ArrayAccessorExpression>()
|
->lhs->As<ast::IndexAccessorExpression>()
|
||||||
->array->As<ast::UnaryOpExpression>()
|
->array->As<ast::UnaryOpExpression>()
|
||||||
->expr->As<ast::UnaryOpExpression>()
|
->expr->As<ast::UnaryOpExpression>()
|
||||||
->expr);
|
->expr);
|
||||||
|
@ -537,7 +537,7 @@ fn f(b: ptr<function, vec2<u32>>) {
|
||||||
.Functions()[0]
|
.Functions()[0]
|
||||||
->body->statements[2]
|
->body->statements[2]
|
||||||
->As<ast::AssignmentStatement>()
|
->As<ast::AssignmentStatement>()
|
||||||
->lhs->As<ast::ArrayAccessorExpression>()
|
->lhs->As<ast::IndexAccessorExpression>()
|
||||||
->array->As<ast::UnaryOpExpression>()
|
->array->As<ast::UnaryOpExpression>()
|
||||||
->expr);
|
->expr);
|
||||||
ASSERT_NE(use_id, 0);
|
ASSERT_NE(use_id, 0);
|
||||||
|
@ -584,7 +584,7 @@ fn f() {
|
||||||
.Functions()[0]
|
.Functions()[0]
|
||||||
->body->statements[1]
|
->body->statements[1]
|
||||||
->As<ast::AssignmentStatement>()
|
->As<ast::AssignmentStatement>()
|
||||||
->lhs->As<ast::ArrayAccessorExpression>()
|
->lhs->As<ast::IndexAccessorExpression>()
|
||||||
->array->As<ast::UnaryOpExpression>()
|
->array->As<ast::UnaryOpExpression>()
|
||||||
->expr->As<ast::UnaryOpExpression>()
|
->expr->As<ast::UnaryOpExpression>()
|
||||||
->expr);
|
->expr);
|
||||||
|
@ -613,15 +613,15 @@ fn f() {
|
||||||
|
|
||||||
NodeIdMap node_id_map(program);
|
NodeIdMap node_id_map(program);
|
||||||
|
|
||||||
auto use_id = node_id_map.GetId(
|
auto use_id =
|
||||||
program.AST()
|
node_id_map.GetId(program.AST()
|
||||||
.Functions()[0]
|
.Functions()[0]
|
||||||
->body->statements[1]
|
->body->statements[1]
|
||||||
->As<ast::VariableDeclStatement>()
|
->As<ast::VariableDeclStatement>()
|
||||||
->variable->constructor->As<ast::ArrayAccessorExpression>()
|
->variable->constructor->As<ast::IndexAccessorExpression>()
|
||||||
->array->As<ast::UnaryOpExpression>()
|
->array->As<ast::UnaryOpExpression>()
|
||||||
->expr->As<ast::UnaryOpExpression>()
|
->expr->As<ast::UnaryOpExpression>()
|
||||||
->expr);
|
->expr);
|
||||||
ASSERT_NE(use_id, 0);
|
ASSERT_NE(use_id, 0);
|
||||||
|
|
||||||
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
|
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
|
||||||
|
@ -649,14 +649,14 @@ fn f() {
|
||||||
|
|
||||||
NodeIdMap node_id_map(program);
|
NodeIdMap node_id_map(program);
|
||||||
|
|
||||||
auto use_id = node_id_map.GetId(
|
auto use_id =
|
||||||
program.AST()
|
node_id_map.GetId(program.AST()
|
||||||
.Functions()[0]
|
.Functions()[0]
|
||||||
->body->statements[3]
|
->body->statements[3]
|
||||||
->As<ast::VariableDeclStatement>()
|
->As<ast::VariableDeclStatement>()
|
||||||
->variable->constructor->As<ast::ArrayAccessorExpression>()
|
->variable->constructor->As<ast::IndexAccessorExpression>()
|
||||||
->array->As<ast::UnaryOpExpression>()
|
->array->As<ast::UnaryOpExpression>()
|
||||||
->expr);
|
->expr);
|
||||||
ASSERT_NE(use_id, 0);
|
ASSERT_NE(use_id, 0);
|
||||||
|
|
||||||
auto replacement_id = node_id_map.GetId(program.AST()
|
auto replacement_id = node_id_map.GetId(program.AST()
|
||||||
|
|
|
@ -179,8 +179,6 @@ libtint_source_set("libtint_core_all_src") {
|
||||||
"ast/alias.h",
|
"ast/alias.h",
|
||||||
"ast/array.cc",
|
"ast/array.cc",
|
||||||
"ast/array.h",
|
"ast/array.h",
|
||||||
"ast/array_accessor_expression.cc",
|
|
||||||
"ast/array_accessor_expression.h",
|
|
||||||
"ast/assignment_statement.cc",
|
"ast/assignment_statement.cc",
|
||||||
"ast/assignment_statement.h",
|
"ast/assignment_statement.h",
|
||||||
"ast/ast_type.cc", # TODO(bclayton) - rename to type.cc
|
"ast/ast_type.cc", # TODO(bclayton) - rename to type.cc
|
||||||
|
@ -248,6 +246,8 @@ libtint_source_set("libtint_core_all_src") {
|
||||||
"ast/identifier_expression.h",
|
"ast/identifier_expression.h",
|
||||||
"ast/if_statement.cc",
|
"ast/if_statement.cc",
|
||||||
"ast/if_statement.h",
|
"ast/if_statement.h",
|
||||||
|
"ast/index_accessor_expression.cc",
|
||||||
|
"ast/index_accessor_expression.h",
|
||||||
"ast/int_literal_expression.cc",
|
"ast/int_literal_expression.cc",
|
||||||
"ast/int_literal_expression.h",
|
"ast/int_literal_expression.h",
|
||||||
"ast/internal_decoration.cc",
|
"ast/internal_decoration.cc",
|
||||||
|
|
|
@ -42,8 +42,8 @@ set(TINT_LIB_SRCS
|
||||||
ast/access.h
|
ast/access.h
|
||||||
ast/alias.cc
|
ast/alias.cc
|
||||||
ast/alias.h
|
ast/alias.h
|
||||||
ast/array_accessor_expression.cc
|
ast/index_accessor_expression.cc
|
||||||
ast/array_accessor_expression.h
|
ast/index_accessor_expression.h
|
||||||
ast/array.cc
|
ast/array.cc
|
||||||
ast/array.h
|
ast/array.h
|
||||||
ast/assignment_statement.cc
|
ast/assignment_statement.cc
|
||||||
|
@ -581,7 +581,6 @@ endif()
|
||||||
if(${TINT_BUILD_TESTS})
|
if(${TINT_BUILD_TESTS})
|
||||||
set(TINT_TEST_SRCS
|
set(TINT_TEST_SRCS
|
||||||
ast/alias_test.cc
|
ast/alias_test.cc
|
||||||
ast/array_accessor_expression_test.cc
|
|
||||||
ast/array_test.cc
|
ast/array_test.cc
|
||||||
ast/assignment_statement_test.cc
|
ast/assignment_statement_test.cc
|
||||||
ast/atomic_test.cc
|
ast/atomic_test.cc
|
||||||
|
@ -611,6 +610,7 @@ if(${TINT_BUILD_TESTS})
|
||||||
ast/i32_test.cc
|
ast/i32_test.cc
|
||||||
ast/identifier_expression_test.cc
|
ast/identifier_expression_test.cc
|
||||||
ast/if_statement_test.cc
|
ast/if_statement_test.cc
|
||||||
|
ast/index_accessor_expression_test.cc
|
||||||
ast/int_literal_expression_test.cc
|
ast/int_literal_expression_test.cc
|
||||||
ast/interpolate_decoration_test.cc
|
ast/interpolate_decoration_test.cc
|
||||||
ast/intrinsic_texture_helper_test.cc
|
ast/intrinsic_texture_helper_test.cc
|
||||||
|
|
|
@ -12,16 +12,16 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/array_accessor_expression.h"
|
#include "src/ast/index_accessor_expression.h"
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::ArrayAccessorExpression);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::IndexAccessorExpression);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
ArrayAccessorExpression::ArrayAccessorExpression(ProgramID pid,
|
IndexAccessorExpression::IndexAccessorExpression(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const Expression* arr,
|
const Expression* arr,
|
||||||
const Expression* idx)
|
const Expression* idx)
|
||||||
|
@ -32,18 +32,18 @@ ArrayAccessorExpression::ArrayAccessorExpression(ProgramID pid,
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, idx, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, idx, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) =
|
IndexAccessorExpression::IndexAccessorExpression(IndexAccessorExpression&&) =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
ArrayAccessorExpression::~ArrayAccessorExpression() = default;
|
IndexAccessorExpression::~IndexAccessorExpression() = default;
|
||||||
|
|
||||||
const ArrayAccessorExpression* ArrayAccessorExpression::Clone(
|
const IndexAccessorExpression* IndexAccessorExpression::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
auto* arr = ctx->Clone(array);
|
auto* arr = ctx->Clone(array);
|
||||||
auto* idx = ctx->Clone(index);
|
auto* idx = ctx->Clone(index);
|
||||||
return ctx->dst->create<ArrayAccessorExpression>(src, arr, idx);
|
return ctx->dst->create<IndexAccessorExpression>(src, arr, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
|
@ -12,8 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_ARRAY_ACCESSOR_EXPRESSION_H_
|
#ifndef SRC_AST_INDEX_ACCESSOR_EXPRESSION_H_
|
||||||
#define SRC_AST_ARRAY_ACCESSOR_EXPRESSION_H_
|
#define SRC_AST_INDEX_ACCESSOR_EXPRESSION_H_
|
||||||
|
|
||||||
#include "src/ast/expression.h"
|
#include "src/ast/expression.h"
|
||||||
|
|
||||||
|
@ -21,27 +21,27 @@ namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// An array accessor expression
|
/// An array accessor expression
|
||||||
class ArrayAccessorExpression
|
class IndexAccessorExpression
|
||||||
: public Castable<ArrayAccessorExpression, Expression> {
|
: public Castable<IndexAccessorExpression, Expression> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param program_id the identifier of the program that owns this node
|
/// @param program_id the identifier of the program that owns this node
|
||||||
/// @param source the array accessor source
|
/// @param source the array accessor source
|
||||||
/// @param arr the array
|
/// @param arr the array
|
||||||
/// @param idx the index expression
|
/// @param idx the index expression
|
||||||
ArrayAccessorExpression(ProgramID program_id,
|
IndexAccessorExpression(ProgramID program_id,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
const Expression* arr,
|
const Expression* arr,
|
||||||
const Expression* idx);
|
const Expression* idx);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
ArrayAccessorExpression(ArrayAccessorExpression&&);
|
IndexAccessorExpression(IndexAccessorExpression&&);
|
||||||
~ArrayAccessorExpression() override;
|
~IndexAccessorExpression() override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const ArrayAccessorExpression* Clone(CloneContext* ctx) const override;
|
const IndexAccessorExpression* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// the array
|
/// the array
|
||||||
const Expression* const array;
|
const Expression* const array;
|
||||||
|
@ -53,4 +53,4 @@ class ArrayAccessorExpression
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_ARRAY_ACCESSOR_EXPRESSION_H_
|
#endif // SRC_AST_INDEX_ACCESSOR_EXPRESSION_H_
|
|
@ -19,70 +19,69 @@ namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using ArrayAccessorExpressionTest = TestHelper;
|
using IndexAccessorExpressionTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Create) {
|
TEST_F(IndexAccessorExpressionTest, Create) {
|
||||||
auto* ary = Expr("ary");
|
auto* ary = Expr("ary");
|
||||||
auto* idx = Expr("idx");
|
auto* idx = Expr("idx");
|
||||||
|
|
||||||
auto* exp = create<ArrayAccessorExpression>(ary, idx);
|
auto* exp = IndexAccessor(ary, idx);
|
||||||
ASSERT_EQ(exp->array, ary);
|
ASSERT_EQ(exp->array, ary);
|
||||||
ASSERT_EQ(exp->index, idx);
|
ASSERT_EQ(exp->index, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, CreateWithSource) {
|
TEST_F(IndexAccessorExpressionTest, CreateWithSource) {
|
||||||
auto* ary = Expr("ary");
|
auto* ary = Expr("ary");
|
||||||
auto* idx = Expr("idx");
|
auto* idx = Expr("idx");
|
||||||
|
|
||||||
auto* exp = create<ArrayAccessorExpression>(Source{Source::Location{20, 2}},
|
auto* exp = IndexAccessor(Source{{20, 2}}, ary, idx);
|
||||||
ary, idx);
|
|
||||||
auto src = exp->source;
|
auto src = exp->source;
|
||||||
EXPECT_EQ(src.range.begin.line, 20u);
|
EXPECT_EQ(src.range.begin.line, 20u);
|
||||||
EXPECT_EQ(src.range.begin.column, 2u);
|
EXPECT_EQ(src.range.begin.column, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, IsArrayAccessor) {
|
TEST_F(IndexAccessorExpressionTest, IsIndexAccessor) {
|
||||||
auto* ary = Expr("ary");
|
auto* ary = Expr("ary");
|
||||||
auto* idx = Expr("idx");
|
auto* idx = Expr("idx");
|
||||||
|
|
||||||
auto* exp = create<ArrayAccessorExpression>(ary, idx);
|
auto* exp = IndexAccessor(ary, idx);
|
||||||
EXPECT_TRUE(exp->Is<ArrayAccessorExpression>());
|
EXPECT_TRUE(exp->Is<IndexAccessorExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Assert_Null_Array) {
|
TEST_F(IndexAccessorExpressionTest, Assert_Null_Array) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<ArrayAccessorExpression>(nullptr, b.Expr("idx"));
|
b.IndexAccessor(nullptr, b.Expr("idx"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Assert_Null_Index) {
|
TEST_F(IndexAccessorExpressionTest, Assert_Null_Index) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<ArrayAccessorExpression>(b.Expr("arr"), nullptr);
|
b.IndexAccessor(b.Expr("arr"), nullptr);
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Assert_DifferentProgramID_Array) {
|
TEST_F(IndexAccessorExpressionTest, Assert_DifferentProgramID_Array) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.create<ArrayAccessorExpression>(b2.Expr("arr"), b1.Expr("idx"));
|
b1.IndexAccessor(b2.Expr("arr"), b1.Expr("idx"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Assert_DifferentProgramID_Index) {
|
TEST_F(IndexAccessorExpressionTest, Assert_DifferentProgramID_Index) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.create<ArrayAccessorExpression>(b1.Expr("arr"), b2.Expr("idx"));
|
b1.IndexAccessor(b1.Expr("arr"), b2.Expr("idx"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
|
@ -17,10 +17,10 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/array_accessor_expression.h"
|
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
#include "src/ast/bitcast_expression.h"
|
#include "src/ast/bitcast_expression.h"
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
|
#include "src/ast/index_accessor_expression.h"
|
||||||
#include "src/ast/literal_expression.h"
|
#include "src/ast/literal_expression.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
#include "src/ast/phony_expression.h"
|
#include "src/ast/phony_expression.h"
|
||||||
|
@ -102,28 +102,28 @@ bool TraverseExpressions(const ast::Expression* root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* array = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* idx = expr->As<IndexAccessorExpression>()) {
|
||||||
push_pair(array->array, array->index);
|
push_pair(idx->array, idx->index);
|
||||||
} else if (auto* bin_op = expr->As<ast::BinaryExpression>()) {
|
} else if (auto* bin_op = expr->As<BinaryExpression>()) {
|
||||||
push_pair(bin_op->lhs, bin_op->rhs);
|
push_pair(bin_op->lhs, bin_op->rhs);
|
||||||
} else if (auto* bitcast = expr->As<ast::BitcastExpression>()) {
|
} else if (auto* bitcast = expr->As<BitcastExpression>()) {
|
||||||
to_visit.push_back(bitcast->expr);
|
to_visit.push_back(bitcast->expr);
|
||||||
} else if (auto* call = expr->As<ast::CallExpression>()) {
|
} else if (auto* call = expr->As<CallExpression>()) {
|
||||||
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include the
|
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include the
|
||||||
// function name in the traversal.
|
// function name in the traversal.
|
||||||
// to_visit.push_back(call->func);
|
// to_visit.push_back(call->func);
|
||||||
push_list(call->args);
|
push_list(call->args);
|
||||||
} else if (auto* type_ctor = expr->As<ast::TypeConstructorExpression>()) {
|
} else if (auto* type_ctor = expr->As<TypeConstructorExpression>()) {
|
||||||
push_list(type_ctor->values);
|
push_list(type_ctor->values);
|
||||||
} else if (auto* member = expr->As<ast::MemberAccessorExpression>()) {
|
} else if (auto* member = expr->As<MemberAccessorExpression>()) {
|
||||||
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include the
|
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include the
|
||||||
// member name in the traversal.
|
// member name in the traversal.
|
||||||
// push_pair(member->structure, member->member);
|
// push_pair(member->structure, member->member);
|
||||||
to_visit.push_back(member->structure);
|
to_visit.push_back(member->structure);
|
||||||
} else if (auto* unary = expr->As<ast::UnaryOpExpression>()) {
|
} else if (auto* unary = expr->As<UnaryOpExpression>()) {
|
||||||
to_visit.push_back(unary->expr);
|
to_visit.push_back(unary->expr);
|
||||||
} else if (expr->IsAnyOf<ast::Literal, ast::IdentifierExpression,
|
} else if (expr->IsAnyOf<Literal, IdentifierExpression,
|
||||||
ast::PhonyExpression>()) {
|
PhonyExpression>()) {
|
||||||
// Leaf expression
|
// Leaf expression
|
||||||
} else {
|
} else {
|
||||||
TINT_ICE(AST, diags) << "unhandled expression type: "
|
TINT_ICE(AST, diags) << "unhandled expression type: "
|
||||||
|
|
|
@ -24,7 +24,7 @@ using ::testing::ElementsAre;
|
||||||
|
|
||||||
using TraverseExpressionsTest = TestHelper;
|
using TraverseExpressionsTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(TraverseExpressionsTest, DescendArrayAccessorExpression) {
|
TEST_F(TraverseExpressionsTest, DescendIndexAccessor) {
|
||||||
std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
|
std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
|
||||||
std::vector<const ast::Expression*> i = {IndexAccessor(e[0], e[1]),
|
std::vector<const ast::Expression*> i = {IndexAccessor(e[0], e[1]),
|
||||||
IndexAccessor(e[2], e[3])};
|
IndexAccessor(e[2], e[3])};
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include "src/ast/alias.h"
|
#include "src/ast/alias.h"
|
||||||
#include "src/ast/array.h"
|
#include "src/ast/array.h"
|
||||||
#include "src/ast/array_accessor_expression.h"
|
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/atomic.h"
|
#include "src/ast/atomic.h"
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
|
@ -42,6 +41,7 @@
|
||||||
#include "src/ast/for_loop_statement.h"
|
#include "src/ast/for_loop_statement.h"
|
||||||
#include "src/ast/i32.h"
|
#include "src/ast/i32.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
|
#include "src/ast/index_accessor_expression.h"
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_decoration.h"
|
||||||
#include "src/ast/invariant_decoration.h"
|
#include "src/ast/invariant_decoration.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
|
@ -1740,21 +1740,21 @@ class ProgramBuilder {
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param arr the array argument for the array accessor expression
|
/// @param arr the array argument for the array accessor expression
|
||||||
/// @param idx the index argument for the array accessor expression
|
/// @param idx the index argument for the array accessor expression
|
||||||
/// @returns a `ast::ArrayAccessorExpression` that indexes `arr` with `idx`
|
/// @returns a `ast::IndexAccessorExpression` that indexes `arr` with `idx`
|
||||||
template <typename ARR, typename IDX>
|
template <typename ARR, typename IDX>
|
||||||
const ast::ArrayAccessorExpression* IndexAccessor(const Source& source,
|
const ast::IndexAccessorExpression* IndexAccessor(const Source& source,
|
||||||
ARR&& arr,
|
ARR&& arr,
|
||||||
IDX&& idx) {
|
IDX&& idx) {
|
||||||
return create<ast::ArrayAccessorExpression>(
|
return create<ast::IndexAccessorExpression>(
|
||||||
source, Expr(std::forward<ARR>(arr)), Expr(std::forward<IDX>(idx)));
|
source, Expr(std::forward<ARR>(arr)), Expr(std::forward<IDX>(idx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param arr the array argument for the array accessor expression
|
/// @param arr the array argument for the array accessor expression
|
||||||
/// @param idx the index argument for the array accessor expression
|
/// @param idx the index argument for the array accessor expression
|
||||||
/// @returns a `ast::ArrayAccessorExpression` that indexes `arr` with `idx`
|
/// @returns a `ast::IndexAccessorExpression` that indexes `arr` with `idx`
|
||||||
template <typename ARR, typename IDX>
|
template <typename ARR, typename IDX>
|
||||||
const ast::ArrayAccessorExpression* IndexAccessor(ARR&& arr, IDX&& idx) {
|
const ast::IndexAccessorExpression* IndexAccessor(ARR&& arr, IDX&& idx) {
|
||||||
return create<ast::ArrayAccessorExpression>(Expr(std::forward<ARR>(arr)),
|
return create<ast::IndexAccessorExpression>(Expr(std::forward<ARR>(arr)),
|
||||||
Expr(std::forward<IDX>(idx)));
|
Expr(std::forward<IDX>(idx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3622,7 +3622,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
// The private variable is an array whose element type is already of
|
// The private variable is an array whose element type is already of
|
||||||
// the same type as the value being stored into it. Form the
|
// the same type as the value being stored into it. Form the
|
||||||
// reference into the first element.
|
// reference into the first element.
|
||||||
lhs.expr = create<ast::ArrayAccessorExpression>(
|
lhs.expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, lhs.expr, parser_impl_.MakeNullValue(ty_.I32()));
|
Source{}, lhs.expr, parser_impl_.MakeNullValue(ty_.I32()));
|
||||||
if (auto* ref = lhs.type->As<Reference>()) {
|
if (auto* ref = lhs.type->As<Reference>()) {
|
||||||
lhs.type = ref->type;
|
lhs.type = ref->type;
|
||||||
|
@ -3672,7 +3672,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
Source{}, builder_.Symbols().Register(name));
|
Source{}, builder_.Symbols().Register(name));
|
||||||
// SampleMask is an array in Vulkan SPIR-V. Always access the first
|
// SampleMask is an array in Vulkan SPIR-V. Always access the first
|
||||||
// element.
|
// element.
|
||||||
id_expr = create<ast::ArrayAccessorExpression>(
|
id_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, id_expr, parser_impl_.MakeNullValue(ty_.I32()));
|
Source{}, id_expr, parser_impl_.MakeNullValue(ty_.I32()));
|
||||||
|
|
||||||
auto* loaded_type = parser_impl_.ConvertType(inst.type_id());
|
auto* loaded_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
|
@ -3972,7 +3972,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == SpvOpVectorExtractDynamic) {
|
if (opcode == SpvOpVectorExtractDynamic) {
|
||||||
return {ast_type, create<ast::ArrayAccessorExpression>(
|
return {ast_type, create<ast::IndexAccessorExpression>(
|
||||||
Source{}, MakeOperand(inst, 0).expr,
|
Source{}, MakeOperand(inst, 0).expr,
|
||||||
MakeOperand(inst, 1).expr)};
|
MakeOperand(inst, 1).expr)};
|
||||||
}
|
}
|
||||||
|
@ -4362,7 +4362,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
Source{}, current_expr.expr, Swizzle(uint32_t(index_const_val)));
|
Source{}, current_expr.expr, Swizzle(uint32_t(index_const_val)));
|
||||||
} else {
|
} else {
|
||||||
// Non-constant index. Use array syntax
|
// Non-constant index. Use array syntax
|
||||||
next_expr = create<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
||||||
}
|
}
|
||||||
// All vector components are the same type.
|
// All vector components are the same type.
|
||||||
|
@ -4372,18 +4372,18 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeMatrix:
|
case SpvOpTypeMatrix:
|
||||||
// Use array syntax.
|
// Use array syntax.
|
||||||
next_expr = create<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
||||||
// All matrix components are the same type.
|
// All matrix components are the same type.
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeArray:
|
case SpvOpTypeArray:
|
||||||
next_expr = create<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeRuntimeArray:
|
case SpvOpTypeRuntimeArray:
|
||||||
next_expr = create<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
Source{}, current_expr.expr, MakeOperand(inst, index).expr);
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
|
@ -4543,7 +4543,7 @@ TypedExpression FunctionEmitter::MakeCompositeValueDecomposition(
|
||||||
<< " is too big. Max handled index is " << kMaxVectorLen - 1;
|
<< " is too big. Max handled index is " << kMaxVectorLen - 1;
|
||||||
}
|
}
|
||||||
// Use array syntax.
|
// Use array syntax.
|
||||||
next_expr = create<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, current_expr.expr, make_index(index_val));
|
Source{}, current_expr.expr, make_index(index_val));
|
||||||
// All matrix components are the same type.
|
// All matrix components are the same type.
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
||||||
|
@ -4553,7 +4553,7 @@ TypedExpression FunctionEmitter::MakeCompositeValueDecomposition(
|
||||||
// The array size could be a spec constant, and so it's not always
|
// The array size could be a spec constant, and so it's not always
|
||||||
// statically checkable. Instead, rely on a runtime index clamp
|
// statically checkable. Instead, rely on a runtime index clamp
|
||||||
// or runtime check to keep this safe.
|
// or runtime check to keep this safe.
|
||||||
next_expr = create<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, current_expr.expr, make_index(index_val));
|
Source{}, current_expr.expr, make_index(index_val));
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
|
@ -5946,7 +5946,7 @@ bool FunctionEmitter::MakeVectorInsertDynamic(
|
||||||
AddStatement(builder_.Decl({}, temp_var));
|
AddStatement(builder_.Decl({}, temp_var));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* lhs = create<ast::ArrayAccessorExpression>(
|
auto* lhs = create<ast::IndexAccessorExpression>(
|
||||||
Source{}, builder_.Expr(var_name), index.expr);
|
Source{}, builder_.Expr(var_name), index.expr);
|
||||||
if (!lhs) {
|
if (!lhs) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -603,7 +603,7 @@ Source ParserImpl::GetSourceForInst(
|
||||||
if (where == inst_source_.end()) {
|
if (where == inst_source_.end()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return Source{where->second};
|
return Source{where->second };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserImpl::ParseInternalModuleExceptFunctions() {
|
bool ParserImpl::ParseInternalModuleExceptFunctions() {
|
||||||
|
|
|
@ -2270,7 +2270,7 @@ Maybe<const ast::Expression*> ParserImpl::postfix_expression(
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<ast::ArrayAccessorExpression>(source, prefix,
|
return create<ast::IndexAccessorExpression>(source, prefix,
|
||||||
param.value);
|
param.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,8 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
||||||
auto* ident = mem->member->As<ast::IdentifierExpression>();
|
auto* ident = mem->member->As<ast::IdentifierExpression>();
|
||||||
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("d"));
|
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("d"));
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::ArrayAccessorExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::IndexAccessorExpression>());
|
||||||
auto* ary = mem->structure->As<ast::ArrayAccessorExpression>();
|
auto* ary = mem->structure->As<ast::IndexAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_NE(ary->index, nullptr);
|
ASSERT_NE(ary->index, nullptr);
|
||||||
ASSERT_TRUE(ary->index->Is<ast::SintLiteral>());
|
ASSERT_TRUE(ary->index->Is<ast::SintLiteral>());
|
||||||
|
|
|
@ -27,8 +27,8 @@ TEST_F(ParserImplTest, SingularExpression_Array_ConstantIndex) {
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
|
|
||||||
ASSERT_TRUE(e->Is<ast::ArrayAccessorExpression>());
|
ASSERT_TRUE(e->Is<ast::IndexAccessorExpression>());
|
||||||
auto* ary = e->As<ast::ArrayAccessorExpression>();
|
auto* ary = e->As<ast::IndexAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_TRUE(ary->array->Is<ast::IdentifierExpression>());
|
ASSERT_TRUE(ary->array->Is<ast::IdentifierExpression>());
|
||||||
auto* ident = ary->array->As<ast::IdentifierExpression>();
|
auto* ident = ary->array->As<ast::IdentifierExpression>();
|
||||||
|
@ -46,8 +46,8 @@ TEST_F(ParserImplTest, SingularExpression_Array_ExpressionIndex) {
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
|
|
||||||
ASSERT_TRUE(e->Is<ast::ArrayAccessorExpression>());
|
ASSERT_TRUE(e->Is<ast::IndexAccessorExpression>());
|
||||||
auto* ary = e->As<ast::ArrayAccessorExpression>();
|
auto* ary = e->As<ast::IndexAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_TRUE(ary->array->Is<ast::IdentifierExpression>());
|
ASSERT_TRUE(ary->array->Is<ast::IdentifierExpression>());
|
||||||
auto* ident = ary->array->As<ast::IdentifierExpression>();
|
auto* ident = ary->array->As<ast::IdentifierExpression>();
|
||||||
|
@ -202,7 +202,7 @@ TEST_F(ParserImplTest, SingularExpression_NonMatch_returnLHS) {
|
||||||
ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
|
ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SingularExpression_Array_NestedArrayAccessor) {
|
TEST_F(ParserImplTest, SingularExpression_Array_NestedIndexAccessor) {
|
||||||
auto p = parser("a[b[c]]");
|
auto p = parser("a[b[c]]");
|
||||||
auto e = p->singular_expression();
|
auto e = p->singular_expression();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
|
@ -210,7 +210,7 @@ TEST_F(ParserImplTest, SingularExpression_Array_NestedArrayAccessor) {
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
|
|
||||||
const auto* outer_accessor = e->As<ast::ArrayAccessorExpression>();
|
const auto* outer_accessor = e->As<ast::IndexAccessorExpression>();
|
||||||
ASSERT_TRUE(outer_accessor);
|
ASSERT_TRUE(outer_accessor);
|
||||||
|
|
||||||
const auto* outer_array =
|
const auto* outer_array =
|
||||||
|
@ -219,7 +219,7 @@ TEST_F(ParserImplTest, SingularExpression_Array_NestedArrayAccessor) {
|
||||||
EXPECT_EQ(outer_array->symbol, p->builder().Symbols().Get("a"));
|
EXPECT_EQ(outer_array->symbol, p->builder().Symbols().Get("a"));
|
||||||
|
|
||||||
const auto* inner_accessor =
|
const auto* inner_accessor =
|
||||||
outer_accessor->index->As<ast::ArrayAccessorExpression>();
|
outer_accessor->index->As<ast::IndexAccessorExpression>();
|
||||||
ASSERT_TRUE(inner_accessor);
|
ASSERT_TRUE(inner_accessor);
|
||||||
|
|
||||||
const auto* inner_array =
|
const auto* inner_array =
|
||||||
|
|
|
@ -28,8 +28,8 @@ TEST_F(ParserImplTest, UnaryExpression_Postix) {
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
|
|
||||||
ASSERT_TRUE(e->Is<ast::ArrayAccessorExpression>());
|
ASSERT_TRUE(e->Is<ast::IndexAccessorExpression>());
|
||||||
auto* ary = e->As<ast::ArrayAccessorExpression>();
|
auto* ary = e->As<ast::IndexAccessorExpression>();
|
||||||
ASSERT_TRUE(ary->array->Is<ast::IdentifierExpression>());
|
ASSERT_TRUE(ary->array->Is<ast::IdentifierExpression>());
|
||||||
auto* ident = ary->array->As<ast::IdentifierExpression>();
|
auto* ident = ary->array->As<ast::IdentifierExpression>();
|
||||||
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
|
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
|
||||||
|
|
|
@ -22,9 +22,9 @@ namespace tint {
|
||||||
namespace resolver {
|
namespace resolver {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using ResolverArrayAccessorTest = ResolverTest;
|
using ResolverIndexAccessorTest = ResolverTest;
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_Dynamic_F32) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_F32) {
|
||||||
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 1.0f));
|
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 1.0f));
|
||||||
WrapInFunction(acc);
|
WrapInFunction(acc);
|
||||||
|
@ -34,7 +34,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_Dynamic_F32) {
|
||||||
"12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
"12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_Dynamic_Ref) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_Ref) {
|
||||||
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
|
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
|
||||||
auto* acc = IndexAccessor("my_var", idx);
|
auto* acc = IndexAccessor("my_var", idx);
|
||||||
|
@ -43,7 +43,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_Dynamic_Ref) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
|
||||||
Global("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* idx = Var("idx", ty.u32(), Expr(3u));
|
auto* idx = Var("idx", ty.u32(), Expr(3u));
|
||||||
auto* idy = Var("idy", ty.u32(), Expr(2u));
|
auto* idy = Var("idy", ty.u32(), Expr(2u));
|
||||||
|
@ -53,7 +53,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_Dynamic) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic) {
|
||||||
GlobalConst("my_const", ty.mat2x3<f32>(), Construct(ty.mat2x3<f32>()));
|
GlobalConst("my_const", ty.mat2x3<f32>(), Construct(ty.mat2x3<f32>()));
|
||||||
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
|
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
|
||||||
auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
|
auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
|
||||||
|
@ -64,7 +64,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_Dynamic) {
|
||||||
"12:34 error: index must be signed or unsigned integer literal");
|
"12:34 error: index must be signed or unsigned integer literal");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_XDimension_Dynamic) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_XDimension_Dynamic) {
|
||||||
GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
|
GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
|
||||||
auto* idx = Var("idx", ty.u32(), Expr(3u));
|
auto* idx = Var("idx", ty.u32(), Expr(3u));
|
||||||
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
|
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
|
||||||
|
@ -75,7 +75,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_XDimension_Dynamic) {
|
||||||
"12:34 error: index must be signed or unsigned integer literal");
|
"12:34 error: index must be signed or unsigned integer literal");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_BothDimension_Dynamic) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_BothDimension_Dynamic) {
|
||||||
GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
|
GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
|
||||||
auto* idx = Var("idy", ty.u32(), Expr(2u));
|
auto* idx = Var("idy", ty.u32(), Expr(2u));
|
||||||
auto* acc =
|
auto* acc =
|
||||||
|
@ -87,7 +87,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_BothDimension_Dynamic) {
|
||||||
"12:34 error: index must be signed or unsigned integer literal");
|
"12:34 error: index must be signed or unsigned integer literal");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix) {
|
TEST_F(ResolverIndexAccessorTest, Matrix) {
|
||||||
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* acc = IndexAccessor("my_var", 2);
|
auto* acc = IndexAccessor("my_var", 2);
|
||||||
|
@ -103,7 +103,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix) {
|
||||||
EXPECT_EQ(ref->StoreType()->As<sem::Vector>()->Width(), 3u);
|
EXPECT_EQ(ref->StoreType()->As<sem::Vector>()->Width(), 3u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Matrix_BothDimensions) {
|
TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
|
||||||
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
|
auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
|
||||||
|
@ -118,7 +118,7 @@ TEST_F(ResolverArrayAccessorTest, Matrix_BothDimensions) {
|
||||||
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Vector_F32) {
|
TEST_F(ResolverIndexAccessorTest, Vector_F32) {
|
||||||
Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 2.0f));
|
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 2.0f));
|
||||||
WrapInFunction(acc);
|
WrapInFunction(acc);
|
||||||
|
@ -128,7 +128,7 @@ TEST_F(ResolverArrayAccessorTest, Vector_F32) {
|
||||||
"12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
"12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Vector_Dynamic_Ref) {
|
TEST_F(ResolverIndexAccessorTest, Vector_Dynamic_Ref) {
|
||||||
Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* idx = Var("idx", ty.i32(), Expr(2));
|
auto* idx = Var("idx", ty.i32(), Expr(2));
|
||||||
auto* acc = IndexAccessor("my_var", idx);
|
auto* acc = IndexAccessor("my_var", idx);
|
||||||
|
@ -137,7 +137,7 @@ TEST_F(ResolverArrayAccessorTest, Vector_Dynamic_Ref) {
|
||||||
EXPECT_TRUE(r()->Resolve());
|
EXPECT_TRUE(r()->Resolve());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Vector_Dynamic) {
|
TEST_F(ResolverIndexAccessorTest, Vector_Dynamic) {
|
||||||
GlobalConst("my_var", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
|
GlobalConst("my_var", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
|
||||||
auto* idx = Var("idx", ty.i32(), Expr(2));
|
auto* idx = Var("idx", ty.i32(), Expr(2));
|
||||||
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
|
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
|
||||||
|
@ -146,7 +146,7 @@ TEST_F(ResolverArrayAccessorTest, Vector_Dynamic) {
|
||||||
EXPECT_TRUE(r()->Resolve());
|
EXPECT_TRUE(r()->Resolve());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Vector) {
|
TEST_F(ResolverIndexAccessorTest, Vector) {
|
||||||
Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* acc = IndexAccessor("my_var", 2);
|
auto* acc = IndexAccessor("my_var", 2);
|
||||||
|
@ -161,7 +161,7 @@ TEST_F(ResolverArrayAccessorTest, Vector) {
|
||||||
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Array) {
|
TEST_F(ResolverIndexAccessorTest, Array) {
|
||||||
auto* idx = Expr(2);
|
auto* idx = Expr(2);
|
||||||
Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
|
Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ TEST_F(ResolverArrayAccessorTest, Array) {
|
||||||
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Alias_Array) {
|
TEST_F(ResolverIndexAccessorTest, Alias_Array) {
|
||||||
auto* aary = Alias("myarrty", ty.array<f32, 3>());
|
auto* aary = Alias("myarrty", ty.array<f32, 3>());
|
||||||
|
|
||||||
Global("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
|
Global("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
|
||||||
|
@ -194,7 +194,7 @@ TEST_F(ResolverArrayAccessorTest, Alias_Array) {
|
||||||
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Array_Constant) {
|
TEST_F(ResolverIndexAccessorTest, Array_Constant) {
|
||||||
GlobalConst("my_var", ty.array<f32, 3>(), array<f32, 3>());
|
GlobalConst("my_var", ty.array<f32, 3>(), array<f32, 3>());
|
||||||
|
|
||||||
auto* acc = IndexAccessor("my_var", 2);
|
auto* acc = IndexAccessor("my_var", 2);
|
||||||
|
@ -206,7 +206,7 @@ TEST_F(ResolverArrayAccessorTest, Array_Constant) {
|
||||||
EXPECT_TRUE(TypeOf(acc)->Is<sem::F32>()) << TypeOf(acc)->type_name();
|
EXPECT_TRUE(TypeOf(acc)->Is<sem::F32>()) << TypeOf(acc)->type_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Array_Dynamic_I32) {
|
TEST_F(ResolverIndexAccessorTest, Array_Dynamic_I32) {
|
||||||
// let a : array<f32, 3> = 0;
|
// let a : array<f32, 3> = 0;
|
||||||
// var idx : i32 = 0;
|
// var idx : i32 = 0;
|
||||||
// var f : f32 = a[idx];
|
// var f : f32 = a[idx];
|
||||||
|
@ -226,7 +226,7 @@ TEST_F(ResolverArrayAccessorTest, Array_Dynamic_I32) {
|
||||||
"12:34 error: index must be signed or unsigned integer literal");
|
"12:34 error: index must be signed or unsigned integer literal");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Array_Literal_F32) {
|
TEST_F(ResolverIndexAccessorTest, Array_Literal_F32) {
|
||||||
// let a : array<f32, 3>;
|
// let a : array<f32, 3>;
|
||||||
// var f : f32 = a[2.0f];
|
// var f : f32 = a[2.0f];
|
||||||
auto* a = Const("a", ty.array<f32, 3>(), array<f32, 3>());
|
auto* a = Const("a", ty.array<f32, 3>(), array<f32, 3>());
|
||||||
|
@ -243,7 +243,7 @@ TEST_F(ResolverArrayAccessorTest, Array_Literal_F32) {
|
||||||
"12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
"12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Array_Literal_I32) {
|
TEST_F(ResolverIndexAccessorTest, Array_Literal_I32) {
|
||||||
// let a : array<f32, 3>;
|
// let a : array<f32, 3>;
|
||||||
// var f : f32 = a[2];
|
// var f : f32 = a[2];
|
||||||
auto* a = Const("a", ty.array<f32, 3>(), array<f32, 3>());
|
auto* a = Const("a", ty.array<f32, 3>(), array<f32, 3>());
|
||||||
|
@ -257,7 +257,7 @@ TEST_F(ResolverArrayAccessorTest, Array_Literal_I32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, EXpr_Deref_FuncGoodParent) {
|
TEST_F(ResolverIndexAccessorTest, EXpr_Deref_FuncGoodParent) {
|
||||||
// fn func(p: ptr<function, vec4<f32>>) -> f32 {
|
// fn func(p: ptr<function, vec4<f32>>) -> f32 {
|
||||||
// let idx: u32 = u32();
|
// let idx: u32 = u32();
|
||||||
// let x: f32 = (*p)[idx];
|
// let x: f32 = (*p)[idx];
|
||||||
|
@ -274,7 +274,7 @@ TEST_F(ResolverArrayAccessorTest, EXpr_Deref_FuncGoodParent) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, EXpr_Deref_FuncBadParent) {
|
TEST_F(ResolverIndexAccessorTest, EXpr_Deref_FuncBadParent) {
|
||||||
// fn func(p: ptr<function, vec4<f32>>) -> f32 {
|
// fn func(p: ptr<function, vec4<f32>>) -> f32 {
|
||||||
// let idx: u32 = u32();
|
// let idx: u32 = u32();
|
||||||
// let x: f32 = *p[idx];
|
// let x: f32 = *p[idx];
|
||||||
|
@ -294,7 +294,7 @@ TEST_F(ResolverArrayAccessorTest, EXpr_Deref_FuncBadParent) {
|
||||||
"12:34 error: cannot index type 'ptr<function, vec4<f32>, read_write>'");
|
"12:34 error: cannot index type 'ptr<function, vec4<f32>, read_write>'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverArrayAccessorTest, Exr_Deref_BadParent) {
|
TEST_F(ResolverIndexAccessorTest, Exr_Deref_BadParent) {
|
||||||
// var param: vec4<f32>
|
// var param: vec4<f32>
|
||||||
// let x: f32 = *(¶m)[0];
|
// let x: f32 = *(¶m)[0];
|
||||||
auto* param = Var("param", ty.vec4<f32>());
|
auto* param = Var("param", ty.vec4<f32>());
|
||||||
|
|
|
@ -166,7 +166,6 @@ TEST_F(ResolverEntryPointValidationTest,
|
||||||
12:34 note: while analysing entry point 'main')");
|
12:34 note: while analysing entry point 'main')");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateBuiltins) {
|
TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateBuiltins) {
|
||||||
// struct Output {
|
// struct Output {
|
||||||
// [[builtin(frag_depth)]] a : f32;
|
// [[builtin(frag_depth)]] a : f32;
|
||||||
|
@ -354,20 +353,20 @@ constexpr Params ParamsFor(bool is_valid) {
|
||||||
using TypeValidationTest = resolver::ResolverTestWithParam<Params>;
|
using TypeValidationTest = resolver::ResolverTestWithParam<Params>;
|
||||||
|
|
||||||
static constexpr Params cases[] = {
|
static constexpr Params cases[] = {
|
||||||
ParamsFor<f32>(true), //
|
ParamsFor<f32>(true), //
|
||||||
ParamsFor<i32>(true), //
|
ParamsFor<i32>(true), //
|
||||||
ParamsFor<u32>(true), //
|
ParamsFor<u32>(true), //
|
||||||
ParamsFor<bool>(false), //
|
ParamsFor<bool>(false), //
|
||||||
ParamsFor<vec2<f32>>(true), //
|
ParamsFor<vec2<f32>>(true), //
|
||||||
ParamsFor<vec3<f32>>(true), //
|
ParamsFor<vec3<f32>>(true), //
|
||||||
ParamsFor<vec4<f32>>(true), //
|
ParamsFor<vec4<f32>>(true), //
|
||||||
ParamsFor<mat2x2<f32>>(false), //
|
ParamsFor<mat2x2<f32>>(false), //
|
||||||
ParamsFor<mat3x3<f32>>(false), //
|
ParamsFor<mat3x3<f32>>(false), //
|
||||||
ParamsFor<mat4x4<f32>>(false), //
|
ParamsFor<mat4x4<f32>>(false), //
|
||||||
ParamsFor<alias<f32>>(true), //
|
ParamsFor<alias<f32>>(true), //
|
||||||
ParamsFor<alias<i32>>(true), //
|
ParamsFor<alias<i32>>(true), //
|
||||||
ParamsFor<alias<u32>>(true), //
|
ParamsFor<alias<u32>>(true), //
|
||||||
ParamsFor<alias<bool>>(false), //
|
ParamsFor<alias<bool>>(false), //
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(TypeValidationTest, BareInputs) {
|
TEST_P(TypeValidationTest, BareInputs) {
|
||||||
|
|
|
@ -80,7 +80,7 @@ TEST_F(ResolverPtrRefValidationTest, AddressOfVectorComponent_MemberAccessor) {
|
||||||
"12:34 error: cannot take the address of a vector component");
|
"12:34 error: cannot take the address of a vector component");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverPtrRefValidationTest, AddressOfVectorComponent_ArrayAccessor) {
|
TEST_F(ResolverPtrRefValidationTest, AddressOfVectorComponent_IndexAccessor) {
|
||||||
// var v : vec4<i32>;
|
// var v : vec4<i32>;
|
||||||
// &v[2]
|
// &v[2]
|
||||||
auto* v = Var("v", ty.vec4<i32>());
|
auto* v = Var("v", ty.vec4<i32>());
|
||||||
|
|
|
@ -2354,8 +2354,8 @@ sem::Expression* Resolver::Expression(const ast::Expression* root) {
|
||||||
|
|
||||||
for (auto* expr : utils::Reverse(sorted)) {
|
for (auto* expr : utils::Reverse(sorted)) {
|
||||||
sem::Expression* sem_expr = nullptr;
|
sem::Expression* sem_expr = nullptr;
|
||||||
if (auto* array = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* array = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
sem_expr = ArrayAccessor(array);
|
sem_expr = IndexAccessor(array);
|
||||||
} else if (auto* bin_op = expr->As<ast::BinaryExpression>()) {
|
} else if (auto* bin_op = expr->As<ast::BinaryExpression>()) {
|
||||||
sem_expr = Binary(bin_op);
|
sem_expr = Binary(bin_op);
|
||||||
} else if (auto* bitcast = expr->As<ast::BitcastExpression>()) {
|
} else if (auto* bitcast = expr->As<ast::BitcastExpression>()) {
|
||||||
|
@ -2394,8 +2394,8 @@ sem::Expression* Resolver::Expression(const ast::Expression* root) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::ArrayAccessor(
|
sem::Expression* Resolver::IndexAccessor(
|
||||||
const ast::ArrayAccessorExpression* expr) {
|
const ast::IndexAccessorExpression* expr) {
|
||||||
auto* idx = expr->index;
|
auto* idx = expr->index;
|
||||||
auto* parent_raw_ty = TypeOf(expr->array);
|
auto* parent_raw_ty = TypeOf(expr->array);
|
||||||
auto* parent_ty = parent_raw_ty->UnwrapRef();
|
auto* parent_ty = parent_raw_ty->UnwrapRef();
|
||||||
|
@ -3455,7 +3455,7 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* array = unary->expr->As<ast::ArrayAccessorExpression>();
|
auto* array = unary->expr->As<ast::IndexAccessorExpression>();
|
||||||
auto* member = unary->expr->As<ast::MemberAccessorExpression>();
|
auto* member = unary->expr->As<ast::MemberAccessorExpression>();
|
||||||
if ((array && TypeOf(array->array)->UnwrapRef()->Is<sem::Vector>()) ||
|
if ((array && TypeOf(array->array)->UnwrapRef()->Is<sem::Vector>()) ||
|
||||||
(member &&
|
(member &&
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace tint {
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace ast {
|
namespace ast {
|
||||||
class ArrayAccessorExpression;
|
class IndexAccessorExpression;
|
||||||
class BinaryExpression;
|
class BinaryExpression;
|
||||||
class BitcastExpression;
|
class BitcastExpression;
|
||||||
class CallExpression;
|
class CallExpression;
|
||||||
|
@ -167,7 +167,7 @@ class Resolver {
|
||||||
|
|
||||||
// Expression resolving methods
|
// Expression resolving methods
|
||||||
// Returns the semantic node pointer on success, nullptr on failure.
|
// Returns the semantic node pointer on success, nullptr on failure.
|
||||||
sem::Expression* ArrayAccessor(const ast::ArrayAccessorExpression*);
|
sem::Expression* IndexAccessor(const ast::IndexAccessorExpression*);
|
||||||
sem::Expression* Binary(const ast::BinaryExpression*);
|
sem::Expression* Binary(const ast::BinaryExpression*);
|
||||||
sem::Expression* Bitcast(const ast::BitcastExpression*);
|
sem::Expression* Bitcast(const ast::BitcastExpression*);
|
||||||
sem::Expression* Call(const ast::CallExpression*);
|
sem::Expression* Call(const ast::CallExpression*);
|
||||||
|
|
|
@ -667,7 +667,7 @@ TEST_F(ResolverTest, Expr_Identifier_FunctionVariable_Const) {
|
||||||
EXPECT_EQ(VarOf(my_var_a)->Declaration(), var);
|
EXPECT_EQ(VarOf(my_var_a)->Declaration(), var);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, ArrayAccessor_Dynamic_Ref_F32) {
|
TEST_F(ResolverTest, IndexAccessor_Dynamic_Ref_F32) {
|
||||||
// var a : array<bool, 10> = 0;
|
// var a : array<bool, 10> = 0;
|
||||||
// var idx : f32 = f32();
|
// var idx : f32 = f32();
|
||||||
// var f : f32 = a[idx];
|
// var f : f32 = a[idx];
|
||||||
|
|
|
@ -64,7 +64,6 @@ GlobalVariable::GlobalVariable(const ast::Variable* declaration,
|
||||||
binding_point_(binding_point),
|
binding_point_(binding_point),
|
||||||
is_pipeline_constant_(false) {}
|
is_pipeline_constant_(false) {}
|
||||||
|
|
||||||
|
|
||||||
GlobalVariable::~GlobalVariable() = default;
|
GlobalVariable::~GlobalVariable() = default;
|
||||||
|
|
||||||
Parameter::Parameter(const ast::Variable* declaration,
|
Parameter::Parameter(const ast::Variable* declaration,
|
||||||
|
|
|
@ -851,7 +851,7 @@ void DecomposeMemoryAccess::Run(CloneContext& ctx, const DataMap&, DataMap&) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* accessor = node->As<ast::ArrayAccessorExpression>()) {
|
if (auto* accessor = node->As<ast::IndexAccessorExpression>()) {
|
||||||
if (auto access = state.TakeAccess(accessor->array)) {
|
if (auto access = state.TakeAccess(accessor->array)) {
|
||||||
// X[Y]
|
// X[Y]
|
||||||
if (auto* arr = access.type->As<sem::Array>()) {
|
if (auto* arr = access.type->As<sem::Array>()) {
|
||||||
|
|
|
@ -144,8 +144,8 @@ void DecomposeStridedMatrix::Run(CloneContext& ctx, const DataMap&, DataMap&) {
|
||||||
// preserve these without calling conversion functions.
|
// preserve these without calling conversion functions.
|
||||||
// Example:
|
// Example:
|
||||||
// ssbo.mat[2] -> ssbo.mat[2]
|
// ssbo.mat[2] -> ssbo.mat[2]
|
||||||
ctx.ReplaceAll([&](const ast::ArrayAccessorExpression* expr)
|
ctx.ReplaceAll([&](const ast::IndexAccessorExpression* expr)
|
||||||
-> const ast::ArrayAccessorExpression* {
|
-> const ast::IndexAccessorExpression* {
|
||||||
if (auto* access =
|
if (auto* access =
|
||||||
ctx.src->Sem().Get<sem::StructMemberAccess>(expr->array)) {
|
ctx.src->Sem().Get<sem::StructMemberAccess>(expr->array)) {
|
||||||
auto it = decomposed.find(access->Member()->Declaration());
|
auto it = decomposed.find(access->Member()->Declaration());
|
||||||
|
|
|
@ -43,7 +43,7 @@ template <typename F>
|
||||||
void CollectSavedArrayIndices(const Program* program,
|
void CollectSavedArrayIndices(const Program* program,
|
||||||
const ast::Expression* expr,
|
const ast::Expression* expr,
|
||||||
F&& cb) {
|
F&& cb) {
|
||||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
CollectSavedArrayIndices(program, a->array, cb);
|
CollectSavedArrayIndices(program, a->array, cb);
|
||||||
|
|
||||||
if (!a->index->Is<ast::Literal>()) {
|
if (!a->index->Is<ast::Literal>()) {
|
||||||
|
|
|
@ -115,7 +115,7 @@ void PadArrayElements::Run(CloneContext& ctx, const DataMap&, DataMap&) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fix up array accessors so `a[1]` becomes `a[1].el`
|
// Fix up array accessors so `a[1]` becomes `a[1].el`
|
||||||
ctx.ReplaceAll([&](const ast::ArrayAccessorExpression* accessor)
|
ctx.ReplaceAll([&](const ast::IndexAccessorExpression* accessor)
|
||||||
-> const ast::Expression* {
|
-> const ast::Expression* {
|
||||||
if (auto* array = tint::As<sem::Array>(
|
if (auto* array = tint::As<sem::Array>(
|
||||||
sem.Get(accessor->array)->Type()->UnwrapRef())) {
|
sem.Get(accessor->array)->Type()->UnwrapRef())) {
|
||||||
|
|
|
@ -1300,7 +1300,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"long2",
|
"long2",
|
||||||
"long3",
|
"long3",
|
||||||
"long4",
|
"long4",
|
||||||
"main", // No functions called main
|
"main", // No functions called main
|
||||||
"matrix",
|
"matrix",
|
||||||
"metal", // The namespace
|
"metal", // The namespace
|
||||||
"packed_bool2",
|
"packed_bool2",
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct Robustness::State {
|
||||||
|
|
||||||
/// Applies the transformation state to `ctx`.
|
/// Applies the transformation state to `ctx`.
|
||||||
void Transform() {
|
void Transform() {
|
||||||
ctx.ReplaceAll([&](const ast::ArrayAccessorExpression* expr) {
|
ctx.ReplaceAll([&](const ast::IndexAccessorExpression* expr) {
|
||||||
return Transform(expr);
|
return Transform(expr);
|
||||||
});
|
});
|
||||||
ctx.ReplaceAll(
|
ctx.ReplaceAll(
|
||||||
|
@ -52,8 +52,8 @@ struct Robustness::State {
|
||||||
/// @param expr the array, vector or matrix index expression
|
/// @param expr the array, vector or matrix index expression
|
||||||
/// @return the clamped replacement expression, or nullptr if `expr` should be
|
/// @return the clamped replacement expression, or nullptr if `expr` should be
|
||||||
/// cloned without changes.
|
/// cloned without changes.
|
||||||
const ast::ArrayAccessorExpression* Transform(
|
const ast::IndexAccessorExpression* Transform(
|
||||||
const ast::ArrayAccessorExpression* expr) {
|
const ast::IndexAccessorExpression* expr) {
|
||||||
auto* ret_type = ctx.src->Sem().Get(expr->array)->Type();
|
auto* ret_type = ctx.src->Sem().Get(expr->array)->Type();
|
||||||
|
|
||||||
auto* ref = ret_type->As<sem::Reference>();
|
auto* ref = ret_type->As<sem::Reference>();
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
class ArrayAccessorExpression;
|
class IndexAccessorExpression;
|
||||||
class CallExpression;
|
class CallExpression;
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -57,8 +57,8 @@ void WrapArraysInStructs::Run(CloneContext& ctx, const DataMap&, DataMap&) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fix up array accessors so `a[1]` becomes `a.arr[1]`
|
// Fix up array accessors so `a[1]` becomes `a.arr[1]`
|
||||||
ctx.ReplaceAll([&](const ast::ArrayAccessorExpression* accessor)
|
ctx.ReplaceAll([&](const ast::IndexAccessorExpression* accessor)
|
||||||
-> const ast::ArrayAccessorExpression* {
|
-> const ast::IndexAccessorExpression* {
|
||||||
if (auto* array = ::tint::As<sem::Array>(
|
if (auto* array = ::tint::As<sem::Array>(
|
||||||
sem.Get(accessor->array)->Type()->UnwrapRef())) {
|
sem.Get(accessor->array)->Type()->UnwrapRef())) {
|
||||||
if (wrapper(array)) {
|
if (wrapper(array)) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct UniqueVector {
|
||||||
ConstIterator end() const { return vector.end(); }
|
ConstIterator end() const { return vector.end(); }
|
||||||
|
|
||||||
/// @returns a const reference to the internal vector
|
/// @returns a const reference to the internal vector
|
||||||
operator const std::vector<T> &() const { return vector; }
|
operator const std::vector<T>&() const { return vector; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<T> vector;
|
std::vector<T> vector;
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <functional>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "src/debug.h"
|
#include "src/debug.h"
|
||||||
|
|
||||||
|
|
|
@ -164,9 +164,9 @@ bool GeneratorImpl::Generate() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitArrayAccessor(
|
bool GeneratorImpl::EmitIndexAccessor(
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr) {
|
const ast::IndexAccessorExpression* expr) {
|
||||||
if (!EmitExpression(out, expr->array)) {
|
if (!EmitExpression(out, expr->array)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1459,8 +1459,8 @@ bool GeneratorImpl::EmitDiscard(const ast::DiscardStatement*) {
|
||||||
|
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
||||||
const ast::Expression* expr) {
|
const ast::Expression* expr) {
|
||||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
return EmitArrayAccessor(out, a);
|
return EmitIndexAccessor(out, a);
|
||||||
}
|
}
|
||||||
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
||||||
return EmitBinary(out, b);
|
return EmitBinary(out, b);
|
||||||
|
|
|
@ -63,8 +63,8 @@ class GeneratorImpl : public TextGenerator {
|
||||||
/// @param out the output of the expression stream
|
/// @param out the output of the expression stream
|
||||||
/// @param expr the expression to emit
|
/// @param expr the expression to emit
|
||||||
/// @returns true if the array accessor was emitted
|
/// @returns true if the array accessor was emitted
|
||||||
bool EmitArrayAccessor(std::ostream& out,
|
bool EmitIndexAccessor(std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr);
|
const ast::IndexAccessorExpression* expr);
|
||||||
/// Handles an assignment statement
|
/// Handles an assignment statement
|
||||||
/// @param stmt the statement to emit
|
/// @param stmt the statement to emit
|
||||||
/// @returns true if the statement was emitted successfully
|
/// @returns true if the statement was emitted successfully
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
||||||
|
|
||||||
using GlslGeneratorImplTest_Expression = TestHelper;
|
using GlslGeneratorImplTest_Expression = TestHelper;
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Expression, ArrayAccessor) {
|
TEST_F(GlslGeneratorImplTest_Expression, IndexAccessor) {
|
||||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||||
auto* expr = IndexAccessor("ary", 5);
|
auto* expr = IndexAccessor("ary", 5);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
|
|
@ -362,7 +362,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_MemberAccessor,
|
TEST_F(GlslGeneratorImplTest_MemberAccessor,
|
||||||
EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray) {
|
EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray) {
|
||||||
// struct Data {
|
// struct Data {
|
||||||
// a : [[stride(4)]] array<i32, 5>;
|
// a : [[stride(4)]] array<i32, 5>;
|
||||||
// };
|
// };
|
||||||
|
@ -406,7 +406,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_MemberAccessor,
|
TEST_F(GlslGeneratorImplTest_MemberAccessor,
|
||||||
EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
|
EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
|
||||||
// struct Data {
|
// struct Data {
|
||||||
// a : [[stride(4)]] array<i32, 5>;
|
// a : [[stride(4)]] array<i32, 5>;
|
||||||
// };
|
// };
|
||||||
|
|
|
@ -291,7 +291,7 @@ bool GeneratorImpl::EmitDynamicVectorAssignment(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* ast_access_expr = stmt->lhs->As<ast::ArrayAccessorExpression>();
|
auto* ast_access_expr = stmt->lhs->As<ast::IndexAccessorExpression>();
|
||||||
|
|
||||||
auto out = line();
|
auto out = line();
|
||||||
out << name << "(";
|
out << name << "(";
|
||||||
|
@ -311,9 +311,9 @@ bool GeneratorImpl::EmitDynamicVectorAssignment(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitArrayAccessor(
|
bool GeneratorImpl::EmitIndexAccessor(
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr) {
|
const ast::IndexAccessorExpression* expr) {
|
||||||
if (!EmitExpression(out, expr->array)) {
|
if (!EmitExpression(out, expr->array)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ bool GeneratorImpl::EmitBitcast(std::ostream& out,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitAssign(const ast::AssignmentStatement* stmt) {
|
bool GeneratorImpl::EmitAssign(const ast::AssignmentStatement* stmt) {
|
||||||
if (auto* idx = stmt->lhs->As<ast::ArrayAccessorExpression>()) {
|
if (auto* idx = stmt->lhs->As<ast::IndexAccessorExpression>()) {
|
||||||
if (auto* vec = TypeOf(idx->array)->UnwrapRef()->As<sem::Vector>()) {
|
if (auto* vec = TypeOf(idx->array)->UnwrapRef()->As<sem::Vector>()) {
|
||||||
auto* rhs_sem = builder_.Sem().Get(idx->index);
|
auto* rhs_sem = builder_.Sem().Get(idx->index);
|
||||||
if (!rhs_sem->ConstantValue().IsValid()) {
|
if (!rhs_sem->ConstantValue().IsValid()) {
|
||||||
|
@ -2191,8 +2191,8 @@ bool GeneratorImpl::EmitDiscard(const ast::DiscardStatement*) {
|
||||||
|
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
||||||
const ast::Expression* expr) {
|
const ast::Expression* expr) {
|
||||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
return EmitArrayAccessor(out, a);
|
return EmitIndexAccessor(out, a);
|
||||||
}
|
}
|
||||||
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
||||||
return EmitBinary(out, b);
|
return EmitBinary(out, b);
|
||||||
|
|
|
@ -79,8 +79,8 @@ class GeneratorImpl : public TextGenerator {
|
||||||
/// @param out the output of the expression stream
|
/// @param out the output of the expression stream
|
||||||
/// @param expr the expression to emit
|
/// @param expr the expression to emit
|
||||||
/// @returns true if the array accessor was emitted
|
/// @returns true if the array accessor was emitted
|
||||||
bool EmitArrayAccessor(std::ostream& out,
|
bool EmitIndexAccessor(std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr);
|
const ast::IndexAccessorExpression* expr);
|
||||||
/// Handles an assignment statement
|
/// Handles an assignment statement
|
||||||
/// @param stmt the statement to emit
|
/// @param stmt the statement to emit
|
||||||
/// @returns true if the statement was emitted successfully
|
/// @returns true if the statement was emitted successfully
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
||||||
|
|
||||||
using HlslGeneratorImplTest_Expression = TestHelper;
|
using HlslGeneratorImplTest_Expression = TestHelper;
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Expression, ArrayAccessor) {
|
TEST_F(HlslGeneratorImplTest_Expression, IndexAccessor) {
|
||||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||||
auto* expr = IndexAccessor("ary", 5);
|
auto* expr = IndexAccessor("ary", 5);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
|
|
@ -391,7 +391,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray) {
|
EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray) {
|
||||||
// struct Data {
|
// struct Data {
|
||||||
// a : [[stride(4)]] array<i32, 5>;
|
// a : [[stride(4)]] array<i32, 5>;
|
||||||
// };
|
// };
|
||||||
|
@ -423,7 +423,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
|
EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
|
||||||
// struct Data {
|
// struct Data {
|
||||||
// a : [[stride(4)]] array<i32, 5>;
|
// a : [[stride(4)]] array<i32, 5>;
|
||||||
// };
|
// };
|
||||||
|
|
|
@ -238,12 +238,12 @@ bool GeneratorImpl::EmitTypeDecl(const sem::Type* ty) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitArrayAccessor(
|
bool GeneratorImpl::EmitIndexAccessor(
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr) {
|
const ast::IndexAccessorExpression* expr) {
|
||||||
bool paren_lhs =
|
bool paren_lhs =
|
||||||
!expr->array
|
!expr->array
|
||||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
->IsAnyOf<ast::IndexAccessorExpression, ast::CallExpression,
|
||||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||||
ast::TypeConstructorExpression>();
|
ast::TypeConstructorExpression>();
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
|
||||||
auto texture_expr = [&]() {
|
auto texture_expr = [&]() {
|
||||||
bool paren_lhs =
|
bool paren_lhs =
|
||||||
!texture
|
!texture
|
||||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
->IsAnyOf<ast::IndexAccessorExpression, ast::CallExpression,
|
||||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||||
ast::TypeConstructorExpression>();
|
ast::TypeConstructorExpression>();
|
||||||
if (paren_lhs) {
|
if (paren_lhs) {
|
||||||
|
@ -1418,8 +1418,8 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::Literal* lit) {
|
||||||
|
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
||||||
const ast::Expression* expr) {
|
const ast::Expression* expr) {
|
||||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
return EmitArrayAccessor(out, a);
|
return EmitIndexAccessor(out, a);
|
||||||
}
|
}
|
||||||
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
||||||
return EmitBinary(out, b);
|
return EmitBinary(out, b);
|
||||||
|
@ -1905,7 +1905,7 @@ bool GeneratorImpl::EmitMemberAccessor(
|
||||||
auto write_lhs = [&] {
|
auto write_lhs = [&] {
|
||||||
bool paren_lhs =
|
bool paren_lhs =
|
||||||
!expr->structure
|
!expr->structure
|
||||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
->IsAnyOf<ast::IndexAccessorExpression, ast::CallExpression,
|
||||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||||
ast::TypeConstructorExpression>();
|
ast::TypeConstructorExpression>();
|
||||||
if (paren_lhs) {
|
if (paren_lhs) {
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/array_accessor_expression.h"
|
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
#include "src/ast/bitcast_expression.h"
|
#include "src/ast/bitcast_expression.h"
|
||||||
|
@ -28,6 +27,7 @@
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/expression.h"
|
#include "src/ast/expression.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
|
#include "src/ast/index_accessor_expression.h"
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_decoration.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
|
@ -99,8 +99,8 @@ class GeneratorImpl : public TextGenerator {
|
||||||
/// @param out the output of the expression stream
|
/// @param out the output of the expression stream
|
||||||
/// @param expr the expression to emit
|
/// @param expr the expression to emit
|
||||||
/// @returns true if the array accessor was emitted
|
/// @returns true if the array accessor was emitted
|
||||||
bool EmitArrayAccessor(std::ostream& out,
|
bool EmitIndexAccessor(std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr);
|
const ast::IndexAccessorExpression* expr);
|
||||||
/// Handles an assignment statement
|
/// Handles an assignment statement
|
||||||
/// @param stmt the statement to emit
|
/// @param stmt the statement to emit
|
||||||
/// @returns true if the statement was emitted successfully
|
/// @returns true if the statement was emitted successfully
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
||||||
|
|
||||||
using MslGeneratorImplTest = TestHelper;
|
using MslGeneratorImplTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, ArrayAccessor) {
|
TEST_F(MslGeneratorImplTest, IndexAccessor) {
|
||||||
auto* ary = Var("ary", ty.array<i32, 10>());
|
auto* ary = Var("ary", ty.array<i32, 10>());
|
||||||
auto* expr = IndexAccessor("ary", 5);
|
auto* expr = IndexAccessor("ary", 5);
|
||||||
WrapInFunction(ary, expr);
|
WrapInFunction(ary, expr);
|
||||||
|
@ -33,7 +33,7 @@ TEST_F(MslGeneratorImplTest, ArrayAccessor) {
|
||||||
EXPECT_EQ(out.str(), "ary[5]");
|
EXPECT_EQ(out.str(), "ary[5]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, ArrayAccessor_OfDref) {
|
TEST_F(MslGeneratorImplTest, IndexAccessor_OfDref) {
|
||||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* p = Const("p", nullptr, AddressOf("ary"));
|
auto* p = Const("p", nullptr, AddressOf("ary"));
|
||||||
|
|
|
@ -565,7 +565,7 @@ bool Builder::GenerateExecutionModes(const ast::Function* func, uint32_t id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Builder::GenerateExpression(const ast::Expression* expr) {
|
uint32_t Builder::GenerateExpression(const ast::Expression* expr) {
|
||||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
return GenerateAccessorExpression(a);
|
return GenerateAccessorExpression(a);
|
||||||
}
|
}
|
||||||
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
||||||
|
@ -900,7 +900,7 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* var) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Builder::GenerateArrayAccessor(const ast::ArrayAccessorExpression* expr,
|
bool Builder::GenerateIndexAccessor(const ast::IndexAccessorExpression* expr,
|
||||||
AccessorInfo* info) {
|
AccessorInfo* info) {
|
||||||
auto idx_id = GenerateExpression(expr->index);
|
auto idx_id = GenerateExpression(expr->index);
|
||||||
if (idx_id == 0) {
|
if (idx_id == 0) {
|
||||||
|
@ -1089,7 +1089,7 @@ bool Builder::GenerateMemberAccessor(const ast::MemberAccessorExpression* expr,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Builder::GenerateAccessorExpression(const ast::Expression* expr) {
|
uint32_t Builder::GenerateAccessorExpression(const ast::Expression* expr) {
|
||||||
if (!expr->IsAnyOf<ast::ArrayAccessorExpression,
|
if (!expr->IsAnyOf<ast::IndexAccessorExpression,
|
||||||
ast::MemberAccessorExpression>()) {
|
ast::MemberAccessorExpression>()) {
|
||||||
TINT_ICE(Writer, builder_.Diagnostics()) << "expression is not an accessor";
|
TINT_ICE(Writer, builder_.Diagnostics()) << "expression is not an accessor";
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1101,7 +1101,7 @@ uint32_t Builder::GenerateAccessorExpression(const ast::Expression* expr) {
|
||||||
std::vector<const ast::Expression*> accessors;
|
std::vector<const ast::Expression*> accessors;
|
||||||
const ast::Expression* source = expr;
|
const ast::Expression* source = expr;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (auto* array = source->As<ast::ArrayAccessorExpression>()) {
|
if (auto* array = source->As<ast::IndexAccessorExpression>()) {
|
||||||
accessors.insert(accessors.begin(), source);
|
accessors.insert(accessors.begin(), source);
|
||||||
source = array->array;
|
source = array->array;
|
||||||
} else if (auto* member = source->As<ast::MemberAccessorExpression>()) {
|
} else if (auto* member = source->As<ast::MemberAccessorExpression>()) {
|
||||||
|
@ -1120,8 +1120,8 @@ uint32_t Builder::GenerateAccessorExpression(const ast::Expression* expr) {
|
||||||
info.source_type = TypeOf(source);
|
info.source_type = TypeOf(source);
|
||||||
|
|
||||||
for (auto* accessor : accessors) {
|
for (auto* accessor : accessors) {
|
||||||
if (auto* array = accessor->As<ast::ArrayAccessorExpression>()) {
|
if (auto* array = accessor->As<ast::IndexAccessorExpression>()) {
|
||||||
if (!GenerateArrayAccessor(array, &info)) {
|
if (!GenerateIndexAccessor(array, &info)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (auto* member = accessor->As<ast::MemberAccessorExpression>()) {
|
} else if (auto* member = accessor->As<ast::MemberAccessorExpression>()) {
|
||||||
|
|
|
@ -311,7 +311,7 @@ class Builder {
|
||||||
/// @param expr the accessor to generate
|
/// @param expr the accessor to generate
|
||||||
/// @param info the current accessor information
|
/// @param info the current accessor information
|
||||||
/// @returns true if the accessor was generated successfully
|
/// @returns true if the accessor was generated successfully
|
||||||
bool GenerateArrayAccessor(const ast::ArrayAccessorExpression* expr,
|
bool GenerateIndexAccessor(const ast::IndexAccessorExpression* expr,
|
||||||
AccessorInfo* info);
|
AccessorInfo* info);
|
||||||
/// Generates a member accessor
|
/// Generates a member accessor
|
||||||
/// @param expr the accessor to generate
|
/// @param expr the accessor to generate
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace {
|
||||||
|
|
||||||
using BuilderTest = TestHelper;
|
using BuilderTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_VectorRef_Literal) {
|
TEST_F(BuilderTest, IndexAccessor_VectorRef_Literal) {
|
||||||
// var ary : vec3<f32>;
|
// var ary : vec3<f32>;
|
||||||
// ary[1] -> ref<f32>
|
// ary[1] -> ref<f32>
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ TEST_F(BuilderTest, ArrayAccessor_VectorRef_Literal) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_VectorRef_Dynamic) {
|
TEST_F(BuilderTest, IndexAccessor_VectorRef_Dynamic) {
|
||||||
// var ary : vec3<f32>;
|
// var ary : vec3<f32>;
|
||||||
// var idx : i32;
|
// var idx : i32;
|
||||||
// ary[idx] -> ref<f32>
|
// ary[idx] -> ref<f32>
|
||||||
|
@ -98,7 +98,7 @@ TEST_F(BuilderTest, ArrayAccessor_VectorRef_Dynamic) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_VectorRef_Dynamic2) {
|
TEST_F(BuilderTest, IndexAccessor_VectorRef_Dynamic2) {
|
||||||
// var ary : vec3<f32>;
|
// var ary : vec3<f32>;
|
||||||
// ary[1 + 2] -> ref<f32>
|
// ary[1 + 2] -> ref<f32>
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ TEST_F(BuilderTest, ArrayAccessor_VectorRef_Dynamic2) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_ArrayRef_MultiLevel) {
|
TEST_F(BuilderTest, IndexAccessor_ArrayRef_MultiLevel) {
|
||||||
auto* ary4 = ty.array(ty.vec3<f32>(), 4);
|
auto* ary4 = ty.array(ty.vec3<f32>(), 4);
|
||||||
|
|
||||||
// var ary : array<vec3<f32>, 4>
|
// var ary : array<vec3<f32>, 4>
|
||||||
|
@ -172,7 +172,7 @@ TEST_F(BuilderTest, ArrayAccessor_ArrayRef_MultiLevel) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_ArrayRef_ArrayWithSwizzle) {
|
TEST_F(BuilderTest, IndexAccessor_ArrayRef_ArrayWithSwizzle) {
|
||||||
auto* ary4 = ty.array(ty.vec3<f32>(), 4);
|
auto* ary4 = ty.array(ty.vec3<f32>(), 4);
|
||||||
|
|
||||||
// var a : array<vec3<f32>, 4>;
|
// var a : array<vec3<f32>, 4>;
|
||||||
|
@ -682,7 +682,7 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Mixed_ArrayAndMember) {
|
TEST_F(BuilderTest, IndexAccessor_Mixed_ArrayAndMember) {
|
||||||
// type C = struct {
|
// type C = struct {
|
||||||
// baz : vec3<f32>
|
// baz : vec3<f32>
|
||||||
// }
|
// }
|
||||||
|
@ -749,7 +749,7 @@ TEST_F(BuilderTest, ArrayAccessor_Mixed_ArrayAndMember) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Of_Vec) {
|
TEST_F(BuilderTest, IndexAccessor_Of_Vec) {
|
||||||
// let pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
|
// let pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
|
||||||
// vec2<f32>(0.0, 0.5),
|
// vec2<f32>(0.0, 0.5),
|
||||||
// vec2<f32>(-0.5, -0.5),
|
// vec2<f32>(-0.5, -0.5),
|
||||||
|
@ -792,7 +792,7 @@ TEST_F(BuilderTest, ArrayAccessor_Of_Vec) {
|
||||||
Validate(b);
|
Validate(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Of_Array_Of_f32) {
|
TEST_F(BuilderTest, IndexAccessor_Of_Array_Of_f32) {
|
||||||
// let pos : array<array<f32, 2>, 3> = array<vec2<f32, 2>, 3>(
|
// let pos : array<array<f32, 2>, 3> = array<vec2<f32, 2>, 3>(
|
||||||
// array<f32, 2>(0.0, 0.5),
|
// array<f32, 2>(0.0, 0.5),
|
||||||
// array<f32, 2>(-0.5, -0.5),
|
// array<f32, 2>(-0.5, -0.5),
|
||||||
|
@ -837,7 +837,7 @@ TEST_F(BuilderTest, ArrayAccessor_Of_Array_Of_f32) {
|
||||||
Validate(b);
|
Validate(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Vec_Literal) {
|
TEST_F(BuilderTest, IndexAccessor_Vec_Literal) {
|
||||||
// let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
|
// let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
|
||||||
// pos[1]
|
// pos[1]
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ TEST_F(BuilderTest, ArrayAccessor_Vec_Literal) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Vec_Dynamic) {
|
TEST_F(BuilderTest, IndexAccessor_Vec_Dynamic) {
|
||||||
// let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
|
// let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
|
||||||
// idx : i32
|
// idx : i32
|
||||||
// pos[idx]
|
// pos[idx]
|
||||||
|
@ -902,7 +902,7 @@ TEST_F(BuilderTest, ArrayAccessor_Vec_Dynamic) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Array_Literal) {
|
TEST_F(BuilderTest, IndexAccessor_Array_Literal) {
|
||||||
// let a : array<f32, 3>;
|
// let a : array<f32, 3>;
|
||||||
// a[2]
|
// a[2]
|
||||||
|
|
||||||
|
@ -936,7 +936,7 @@ TEST_F(BuilderTest, ArrayAccessor_Array_Literal) {
|
||||||
Validate(b);
|
Validate(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Array_Dynamic) {
|
TEST_F(BuilderTest, IndexAccessor_Array_Dynamic) {
|
||||||
// var a : array<f32, 3>;
|
// var a : array<f32, 3>;
|
||||||
// idx : i32
|
// idx : i32
|
||||||
// a[idx]
|
// a[idx]
|
||||||
|
@ -984,7 +984,7 @@ TEST_F(BuilderTest, ArrayAccessor_Array_Dynamic) {
|
||||||
Validate(b);
|
Validate(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, ArrayAccessor_Matrix_Dynamic) {
|
TEST_F(BuilderTest, IndexAccessor_Matrix_Dynamic) {
|
||||||
// var a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
|
// var a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
|
||||||
// idx : i32
|
// idx : i32
|
||||||
// a[idx]
|
// a[idx]
|
||||||
|
|
|
@ -141,7 +141,7 @@ class TextGenerator {
|
||||||
~LineWriter();
|
~LineWriter();
|
||||||
|
|
||||||
/// @returns the ostringstream
|
/// @returns the ostringstream
|
||||||
operator std::ostream &() { return os; }
|
operator std::ostream&() { return os; }
|
||||||
|
|
||||||
/// @param rhs the value to write to the line
|
/// @param rhs the value to write to the line
|
||||||
/// @returns the ostream so calls can be chained
|
/// @returns the ostream so calls can be chained
|
||||||
|
|
|
@ -116,8 +116,8 @@ bool GeneratorImpl::EmitTypeDecl(const ast::TypeDecl* ty) {
|
||||||
|
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
bool GeneratorImpl::EmitExpression(std::ostream& out,
|
||||||
const ast::Expression* expr) {
|
const ast::Expression* expr) {
|
||||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
|
||||||
return EmitArrayAccessor(out, a);
|
return EmitIndexAccessor(out, a);
|
||||||
}
|
}
|
||||||
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
||||||
return EmitBinary(out, b);
|
return EmitBinary(out, b);
|
||||||
|
@ -152,12 +152,12 @@ bool GeneratorImpl::EmitExpression(std::ostream& out,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitArrayAccessor(
|
bool GeneratorImpl::EmitIndexAccessor(
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr) {
|
const ast::IndexAccessorExpression* expr) {
|
||||||
bool paren_lhs =
|
bool paren_lhs =
|
||||||
!expr->array
|
!expr->array
|
||||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
->IsAnyOf<ast::IndexAccessorExpression, ast::CallExpression,
|
||||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||||
ast::TypeConstructorExpression>();
|
ast::TypeConstructorExpression>();
|
||||||
if (paren_lhs) {
|
if (paren_lhs) {
|
||||||
|
@ -184,7 +184,7 @@ bool GeneratorImpl::EmitMemberAccessor(
|
||||||
const ast::MemberAccessorExpression* expr) {
|
const ast::MemberAccessorExpression* expr) {
|
||||||
bool paren_lhs =
|
bool paren_lhs =
|
||||||
!expr->structure
|
!expr->structure
|
||||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
->IsAnyOf<ast::IndexAccessorExpression, ast::CallExpression,
|
||||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||||
ast::TypeConstructorExpression>();
|
ast::TypeConstructorExpression>();
|
||||||
if (paren_lhs) {
|
if (paren_lhs) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/array_accessor_expression.h"
|
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
#include "src/ast/bitcast_expression.h"
|
#include "src/ast/bitcast_expression.h"
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
#include "src/ast/for_loop_statement.h"
|
#include "src/ast/for_loop_statement.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
|
#include "src/ast/index_accessor_expression.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
#include "src/ast/return_statement.h"
|
#include "src/ast/return_statement.h"
|
||||||
|
@ -62,8 +62,8 @@ class GeneratorImpl : public TextGenerator {
|
||||||
/// @param out the output of the expression stream
|
/// @param out the output of the expression stream
|
||||||
/// @param expr the expression to emit
|
/// @param expr the expression to emit
|
||||||
/// @returns true if the array accessor was emitted
|
/// @returns true if the array accessor was emitted
|
||||||
bool EmitArrayAccessor(std::ostream& out,
|
bool EmitIndexAccessor(std::ostream& out,
|
||||||
const ast::ArrayAccessorExpression* expr);
|
const ast::IndexAccessorExpression* expr);
|
||||||
/// Handles an assignment statement
|
/// Handles an assignment statement
|
||||||
/// @param stmt the statement to emit
|
/// @param stmt the statement to emit
|
||||||
/// @returns true if the statement was emitted successfully
|
/// @returns true if the statement was emitted successfully
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
||||||
|
|
||||||
using WgslGeneratorImplTest = TestHelper;
|
using WgslGeneratorImplTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, ArrayAccessor) {
|
TEST_F(WgslGeneratorImplTest, IndexAccessor) {
|
||||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||||
auto* expr = IndexAccessor("ary", 5);
|
auto* expr = IndexAccessor("ary", 5);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -33,7 +33,7 @@ TEST_F(WgslGeneratorImplTest, ArrayAccessor) {
|
||||||
EXPECT_EQ(out.str(), "ary[5]");
|
EXPECT_EQ(out.str(), "ary[5]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, ArrayAccessor_OfDref) {
|
TEST_F(WgslGeneratorImplTest, IndexAccessor_OfDref) {
|
||||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* p = Const("p", nullptr, AddressOf("ary"));
|
auto* p = Const("p", nullptr, AddressOf("ary"));
|
||||||
|
|
|
@ -146,7 +146,6 @@ tint_unittests_source_set("tint_unittests_core_sem_src") {
|
||||||
tint_unittests_source_set("tint_unittests_core_src") {
|
tint_unittests_source_set("tint_unittests_core_src") {
|
||||||
sources = [
|
sources = [
|
||||||
"../src/ast/alias_test.cc",
|
"../src/ast/alias_test.cc",
|
||||||
"../src/ast/array_accessor_expression_test.cc",
|
|
||||||
"../src/ast/array_test.cc",
|
"../src/ast/array_test.cc",
|
||||||
"../src/ast/assignment_statement_test.cc",
|
"../src/ast/assignment_statement_test.cc",
|
||||||
"../src/ast/atomic_test.cc",
|
"../src/ast/atomic_test.cc",
|
||||||
|
@ -174,6 +173,7 @@ tint_unittests_source_set("tint_unittests_core_src") {
|
||||||
"../src/ast/function_test.cc",
|
"../src/ast/function_test.cc",
|
||||||
"../src/ast/group_decoration_test.cc",
|
"../src/ast/group_decoration_test.cc",
|
||||||
"../src/ast/i32_test.cc",
|
"../src/ast/i32_test.cc",
|
||||||
|
"../src/ast/index_accessor_expression_test.cc",
|
||||||
"../src/ast/identifier_expression_test.cc",
|
"../src/ast/identifier_expression_test.cc",
|
||||||
"../src/ast/if_statement_test.cc",
|
"../src/ast/if_statement_test.cc",
|
||||||
"../src/ast/int_literal_expression_test.cc",
|
"../src/ast/int_literal_expression_test.cc",
|
||||||
|
|
Loading…
Reference in New Issue