ast: Merge DecoratedVariable into Variable
Remove all Variable setters (with exception to set_storage_class() which is called by the TypeDeterminer) Bug: tint:390 Change-Id: I172667e21e2b02e85dcea6703aa1e608ec718250 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35015 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
ccc67252ff
commit
a80511e021
3
BUILD.gn
3
BUILD.gn
|
@ -259,8 +259,6 @@ source_set("libtint_core_src") {
|
||||||
"src/ast/constructor_expression.h",
|
"src/ast/constructor_expression.h",
|
||||||
"src/ast/continue_statement.cc",
|
"src/ast/continue_statement.cc",
|
||||||
"src/ast/continue_statement.h",
|
"src/ast/continue_statement.h",
|
||||||
"src/ast/decorated_variable.cc",
|
|
||||||
"src/ast/decorated_variable.h",
|
|
||||||
"src/ast/decoration.cc",
|
"src/ast/decoration.cc",
|
||||||
"src/ast/decoration.h",
|
"src/ast/decoration.h",
|
||||||
"src/ast/discard_statement.cc",
|
"src/ast/discard_statement.cc",
|
||||||
|
@ -765,7 +763,6 @@ source_set("tint_unittests_core_src") {
|
||||||
"src/ast/clone_context_test.cc",
|
"src/ast/clone_context_test.cc",
|
||||||
"src/ast/constant_id_decoration_test.cc",
|
"src/ast/constant_id_decoration_test.cc",
|
||||||
"src/ast/continue_statement_test.cc",
|
"src/ast/continue_statement_test.cc",
|
||||||
"src/ast/decorated_variable_test.cc",
|
|
||||||
"src/ast/decoration_test.cc",
|
"src/ast/decoration_test.cc",
|
||||||
"src/ast/discard_statement_test.cc",
|
"src/ast/discard_statement_test.cc",
|
||||||
"src/ast/else_statement_test.cc",
|
"src/ast/else_statement_test.cc",
|
||||||
|
|
|
@ -80,8 +80,6 @@ set(TINT_LIB_SRCS
|
||||||
ast/constructor_expression.h
|
ast/constructor_expression.h
|
||||||
ast/continue_statement.cc
|
ast/continue_statement.cc
|
||||||
ast/continue_statement.h
|
ast/continue_statement.h
|
||||||
ast/decorated_variable.cc
|
|
||||||
ast/decorated_variable.h
|
|
||||||
ast/decoration.cc
|
ast/decoration.cc
|
||||||
ast/decoration.h
|
ast/decoration.h
|
||||||
ast/discard_statement.cc
|
ast/discard_statement.cc
|
||||||
|
@ -403,7 +401,6 @@ if(${TINT_BUILD_TESTS})
|
||||||
ast/continue_statement_test.cc
|
ast/continue_statement_test.cc
|
||||||
ast/discard_statement_test.cc
|
ast/discard_statement_test.cc
|
||||||
ast/decoration_test.cc
|
ast/decoration_test.cc
|
||||||
ast/decorated_variable_test.cc
|
|
||||||
ast/else_statement_test.cc
|
ast/else_statement_test.cc
|
||||||
ast/expression_test.cc
|
ast/expression_test.cc
|
||||||
ast/fallthrough_statement_test.cc
|
ast/fallthrough_statement_test.cc
|
||||||
|
|
|
@ -32,7 +32,16 @@ Builder::~Builder() = default;
|
||||||
Variable* Builder::Var(const std::string& name,
|
Variable* Builder::Var(const std::string& name,
|
||||||
StorageClass storage,
|
StorageClass storage,
|
||||||
type::Type* type) {
|
type::Type* type) {
|
||||||
auto* var = create<Variable>(Source{}, name, storage, type);
|
return Var(name, storage, type, nullptr, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable* Builder::Var(const std::string& name,
|
||||||
|
StorageClass storage,
|
||||||
|
type::Type* type,
|
||||||
|
Expression* constructor,
|
||||||
|
VariableDecorationList decorations) {
|
||||||
|
auto* var = create<Variable>(Source{}, name, storage, type, false,
|
||||||
|
constructor, decorations);
|
||||||
OnVariableBuilt(var);
|
OnVariableBuilt(var);
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
@ -40,8 +49,16 @@ Variable* Builder::Var(const std::string& name,
|
||||||
Variable* Builder::Const(const std::string& name,
|
Variable* Builder::Const(const std::string& name,
|
||||||
StorageClass storage,
|
StorageClass storage,
|
||||||
type::Type* type) {
|
type::Type* type) {
|
||||||
auto* var = create<Variable>(Source{}, name, storage, type);
|
return Const(name, storage, type, nullptr, {});
|
||||||
var->set_is_const(true);
|
}
|
||||||
|
|
||||||
|
Variable* Builder::Const(const std::string& name,
|
||||||
|
StorageClass storage,
|
||||||
|
type::Type* type,
|
||||||
|
Expression* constructor,
|
||||||
|
VariableDecorationList decorations) {
|
||||||
|
auto* var = create<Variable>(Source{}, name, storage, type, true, constructor,
|
||||||
|
decorations);
|
||||||
OnVariableBuilt(var);
|
OnVariableBuilt(var);
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,7 +428,8 @@ class Builder {
|
||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
/// @param storage the variable storage class
|
/// @param storage the variable storage class
|
||||||
/// @param type the variable type
|
/// @param type the variable type
|
||||||
/// @returns a `Variable` with the given name, storage and type
|
/// @returns a `Variable` with the given name, storage and type. The variable
|
||||||
|
/// will be built with a nullptr constructor and no decorations.
|
||||||
Variable* Var(const std::string& name,
|
Variable* Var(const std::string& name,
|
||||||
StorageClass storage,
|
StorageClass storage,
|
||||||
type::Type* type);
|
type::Type* type);
|
||||||
|
@ -436,11 +437,36 @@ class Builder {
|
||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
/// @param storage the variable storage class
|
/// @param storage the variable storage class
|
||||||
/// @param type the variable type
|
/// @param type the variable type
|
||||||
/// @returns a constant `Variable` with the given name, storage and type
|
/// @param constructor constructor expression
|
||||||
|
/// @param decorations variable decorations
|
||||||
|
/// @returns a `Variable` with the given name, storage and type
|
||||||
|
Variable* Var(const std::string& name,
|
||||||
|
StorageClass storage,
|
||||||
|
type::Type* type,
|
||||||
|
Expression* constructor,
|
||||||
|
VariableDecorationList decorations);
|
||||||
|
|
||||||
|
/// @param name the variable name
|
||||||
|
/// @param storage the variable storage class
|
||||||
|
/// @param type the variable type
|
||||||
|
/// @returns a constant `Variable` with the given name, storage and type. The
|
||||||
|
/// variable will be built with a nullptr constructor and no decorations.
|
||||||
Variable* Const(const std::string& name,
|
Variable* Const(const std::string& name,
|
||||||
StorageClass storage,
|
StorageClass storage,
|
||||||
type::Type* type);
|
type::Type* type);
|
||||||
|
|
||||||
|
/// @param name the variable name
|
||||||
|
/// @param storage the variable storage class
|
||||||
|
/// @param type the variable type
|
||||||
|
/// @param constructor optional constructor expression
|
||||||
|
/// @param decorations optional variable decorations
|
||||||
|
/// @returns a constant `Variable` with the given name, storage and type
|
||||||
|
Variable* Const(const std::string& name,
|
||||||
|
StorageClass storage,
|
||||||
|
type::Type* type,
|
||||||
|
Expression* constructor,
|
||||||
|
VariableDecorationList decorations);
|
||||||
|
|
||||||
/// @param func the function name
|
/// @param func the function name
|
||||||
/// @param args the function call arguments
|
/// @param args the function call arguments
|
||||||
/// @returns a `CallExpression` to the function `func`, with the
|
/// @returns a `CallExpression` to the function `func`, with the
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
// Copyright 2020 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "src/ast/builtin_decoration.h"
|
|
||||||
#include "src/ast/clone_context.h"
|
|
||||||
#include "src/ast/constant_id_decoration.h"
|
|
||||||
#include "src/ast/location_decoration.h"
|
|
||||||
#include "src/ast/module.h"
|
|
||||||
|
|
||||||
TINT_INSTANTIATE_CLASS_ID(tint::ast::DecoratedVariable);
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace ast {
|
|
||||||
|
|
||||||
DecoratedVariable::DecoratedVariable() = default;
|
|
||||||
|
|
||||||
DecoratedVariable::DecoratedVariable(Variable* var)
|
|
||||||
: Base(var->source(), var->name(), var->storage_class(), var->type()) {}
|
|
||||||
|
|
||||||
DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default;
|
|
||||||
|
|
||||||
DecoratedVariable::~DecoratedVariable() = default;
|
|
||||||
|
|
||||||
bool DecoratedVariable::HasLocationDecoration() const {
|
|
||||||
for (auto* deco : decorations_) {
|
|
||||||
if (deco->Is<LocationDecoration>()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DecoratedVariable::HasBuiltinDecoration() const {
|
|
||||||
for (auto* deco : decorations_) {
|
|
||||||
if (deco->Is<BuiltinDecoration>()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DecoratedVariable::HasConstantIdDecoration() const {
|
|
||||||
for (auto* deco : decorations_) {
|
|
||||||
if (deco->Is<ConstantIdDecoration>()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t DecoratedVariable::constant_id() const {
|
|
||||||
assert(HasConstantIdDecoration());
|
|
||||||
for (auto* deco : decorations_) {
|
|
||||||
if (auto* cid = deco->As<ConstantIdDecoration>()) {
|
|
||||||
return cid->value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DecoratedVariable* DecoratedVariable::Clone(CloneContext* ctx) const {
|
|
||||||
auto* cloned = ctx->mod->create<DecoratedVariable>();
|
|
||||||
cloned->set_source(ctx->Clone(source()));
|
|
||||||
cloned->set_name(name());
|
|
||||||
cloned->set_storage_class(storage_class());
|
|
||||||
cloned->set_type(ctx->Clone(type()));
|
|
||||||
cloned->set_constructor(ctx->Clone(constructor()));
|
|
||||||
cloned->set_is_const(is_const());
|
|
||||||
cloned->set_decorations(ctx->Clone(decorations()));
|
|
||||||
return cloned;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DecoratedVariable::IsValid() const {
|
|
||||||
return Variable::IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecoratedVariable::to_str(std::ostream& out, size_t indent) const {
|
|
||||||
make_indent(out, indent);
|
|
||||||
out << "DecoratedVariable";
|
|
||||||
if (is_const()) {
|
|
||||||
out << "Const";
|
|
||||||
}
|
|
||||||
out << "{" << std::endl;
|
|
||||||
|
|
||||||
make_indent(out, indent + 2);
|
|
||||||
out << "Decorations{" << std::endl;
|
|
||||||
for (auto* deco : decorations_) {
|
|
||||||
deco->to_str(out, indent + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
make_indent(out, indent + 2);
|
|
||||||
out << "}" << std::endl;
|
|
||||||
|
|
||||||
info_to_str(out, indent + 2);
|
|
||||||
constructor_to_str(out, indent + 2);
|
|
||||||
make_indent(out, indent);
|
|
||||||
out << "}" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ast
|
|
||||||
} // namespace tint
|
|
|
@ -1,84 +0,0 @@
|
||||||
// Copyright 2020 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef SRC_AST_DECORATED_VARIABLE_H_
|
|
||||||
#define SRC_AST_DECORATED_VARIABLE_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "src/ast/variable.h"
|
|
||||||
#include "src/ast/variable_decoration.h"
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace ast {
|
|
||||||
|
|
||||||
/// A Decorated Variable statement.
|
|
||||||
class DecoratedVariable : public Castable<DecoratedVariable, Variable> {
|
|
||||||
public:
|
|
||||||
/// Create a new empty decorated variable statement
|
|
||||||
/// Note, used by the `Clone` method.
|
|
||||||
DecoratedVariable();
|
|
||||||
/// Create a decorated variable from an existing variable
|
|
||||||
/// @param var the variable to initialize from
|
|
||||||
explicit DecoratedVariable(Variable* var);
|
|
||||||
/// Move constructor
|
|
||||||
DecoratedVariable(DecoratedVariable&&);
|
|
||||||
|
|
||||||
~DecoratedVariable() override;
|
|
||||||
|
|
||||||
/// Sets a decoration to the variable
|
|
||||||
/// @param decos the decorations to set
|
|
||||||
void set_decorations(VariableDecorationList decos) {
|
|
||||||
decorations_ = std::move(decos);
|
|
||||||
}
|
|
||||||
/// @returns the decorations attached to this variable
|
|
||||||
const VariableDecorationList& decorations() const { return decorations_; }
|
|
||||||
|
|
||||||
/// @returns true if the decorations include a LocationDecoration
|
|
||||||
bool HasLocationDecoration() const;
|
|
||||||
/// @returns true if the deocrations include a BuiltinDecoration
|
|
||||||
bool HasBuiltinDecoration() const;
|
|
||||||
/// @returns true if the decorations include a ConstantIdDecoration
|
|
||||||
bool HasConstantIdDecoration() const;
|
|
||||||
|
|
||||||
/// @returns the constant_id value for the variable. Assumes that
|
|
||||||
/// HasConstantIdDecoration() has been called first.
|
|
||||||
uint32_t constant_id() const;
|
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
|
||||||
/// `ctx`.
|
|
||||||
/// @note Semantic information such as resolved expression type and intrinsic
|
|
||||||
/// information is not cloned.
|
|
||||||
/// @param ctx the clone context
|
|
||||||
/// @return the newly cloned node
|
|
||||||
DecoratedVariable* Clone(CloneContext* ctx) const override;
|
|
||||||
|
|
||||||
/// @returns true if the name and path are both present
|
|
||||||
bool IsValid() const override;
|
|
||||||
|
|
||||||
/// @param out the stream to write to
|
|
||||||
/// @param indent number of spaces to indent the node when writing
|
|
||||||
void to_str(std::ostream& out, size_t indent) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
DecoratedVariable(const DecoratedVariable&) = delete;
|
|
||||||
|
|
||||||
VariableDecorationList decorations_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ast
|
|
||||||
} // namespace tint
|
|
||||||
|
|
||||||
#endif // SRC_AST_DECORATED_VARIABLE_H_
|
|
|
@ -1,146 +0,0 @@
|
||||||
// Copyright 2020 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
|
|
||||||
#include "src/ast/binding_decoration.h"
|
|
||||||
#include "src/ast/builtin_decoration.h"
|
|
||||||
#include "src/ast/constant_id_decoration.h"
|
|
||||||
#include "src/ast/identifier_expression.h"
|
|
||||||
#include "src/ast/location_decoration.h"
|
|
||||||
#include "src/ast/set_decoration.h"
|
|
||||||
#include "src/ast/test_helper.h"
|
|
||||||
#include "src/ast/type/f32_type.h"
|
|
||||||
#include "src/ast/type/i32_type.h"
|
|
||||||
#include "src/ast/variable.h"
|
|
||||||
#include "src/ast/variable_decoration.h"
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace ast {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using DecoratedVariableTest = TestHelper;
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, Creation) {
|
|
||||||
type::I32 t;
|
|
||||||
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
|
|
||||||
EXPECT_EQ(dv.name(), "my_var");
|
|
||||||
EXPECT_EQ(dv.storage_class(), StorageClass::kFunction);
|
|
||||||
EXPECT_EQ(dv.type(), &t);
|
|
||||||
EXPECT_EQ(dv.source().range.begin.line, 0u);
|
|
||||||
EXPECT_EQ(dv.source().range.begin.column, 0u);
|
|
||||||
EXPECT_EQ(dv.source().range.end.line, 0u);
|
|
||||||
EXPECT_EQ(dv.source().range.end.column, 0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, CreationWithSource) {
|
|
||||||
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
|
|
||||||
type::F32 t;
|
|
||||||
auto* var = create<Variable>(s, "i", StorageClass::kPrivate, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
|
|
||||||
EXPECT_EQ(dv.name(), "i");
|
|
||||||
EXPECT_EQ(dv.storage_class(), StorageClass::kPrivate);
|
|
||||||
EXPECT_EQ(dv.type(), &t);
|
|
||||||
EXPECT_EQ(dv.source().range.begin.line, 27u);
|
|
||||||
EXPECT_EQ(dv.source().range.begin.column, 4u);
|
|
||||||
EXPECT_EQ(dv.source().range.end.line, 27u);
|
|
||||||
EXPECT_EQ(dv.source().range.end.column, 5u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, NoDecorations) {
|
|
||||||
type::I32 t;
|
|
||||||
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
EXPECT_FALSE(dv.HasLocationDecoration());
|
|
||||||
EXPECT_FALSE(dv.HasBuiltinDecoration());
|
|
||||||
EXPECT_FALSE(dv.HasConstantIdDecoration());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, WithDecorations) {
|
|
||||||
type::F32 t;
|
|
||||||
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
|
|
||||||
VariableDecorationList decos;
|
|
||||||
decos.push_back(create<LocationDecoration>(1, Source{}));
|
|
||||||
decos.push_back(create<BuiltinDecoration>(Builtin::kPosition, Source{}));
|
|
||||||
decos.push_back(create<ConstantIdDecoration>(1200, Source{}));
|
|
||||||
|
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(dv.HasLocationDecoration());
|
|
||||||
EXPECT_TRUE(dv.HasBuiltinDecoration());
|
|
||||||
EXPECT_TRUE(dv.HasConstantIdDecoration());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, ConstantId) {
|
|
||||||
type::F32 t;
|
|
||||||
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
|
|
||||||
VariableDecorationList decos;
|
|
||||||
decos.push_back(create<ConstantIdDecoration>(1200, Source{}));
|
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_EQ(dv.constant_id(), 1200u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, IsValid) {
|
|
||||||
type::I32 t;
|
|
||||||
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kNone, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
EXPECT_TRUE(dv.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, IsDecorated) {
|
|
||||||
type::I32 t;
|
|
||||||
DecoratedVariable dv(
|
|
||||||
create<Variable>(Source{}, "my_var", StorageClass::kNone, &t));
|
|
||||||
EXPECT_TRUE(dv.Is<DecoratedVariable>());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DecoratedVariableTest, to_str) {
|
|
||||||
type::F32 t;
|
|
||||||
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t);
|
|
||||||
DecoratedVariable dv(var);
|
|
||||||
dv.set_constructor(create<IdentifierExpression>("expr"));
|
|
||||||
|
|
||||||
VariableDecorationList decos;
|
|
||||||
decos.push_back(create<BindingDecoration>(2, Source{}));
|
|
||||||
decos.push_back(create<SetDecoration>(1, Source{}));
|
|
||||||
|
|
||||||
dv.set_decorations(decos);
|
|
||||||
std::ostringstream out;
|
|
||||||
dv.to_str(out, 2);
|
|
||||||
EXPECT_EQ(out.str(), R"( DecoratedVariable{
|
|
||||||
Decorations{
|
|
||||||
BindingDecoration{2}
|
|
||||||
SetDecoration{1}
|
|
||||||
}
|
|
||||||
my_var
|
|
||||||
function
|
|
||||||
__f32
|
|
||||||
{
|
|
||||||
Identifier[not set]{expr}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
} // namespace ast
|
|
||||||
} // namespace tint
|
|
|
@ -17,12 +17,12 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "src/ast/clone_context.h"
|
#include "src/ast/clone_context.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
#include "src/ast/type/multisampled_texture_type.h"
|
#include "src/ast/type/multisampled_texture_type.h"
|
||||||
#include "src/ast/type/sampled_texture_type.h"
|
#include "src/ast/type/sampled_texture_type.h"
|
||||||
#include "src/ast/type/texture_type.h"
|
#include "src/ast/type/texture_type.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_decoration.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_CLASS_ID(tint::ast::Function);
|
TINT_INSTANTIATE_CLASS_ID(tint::ast::Function);
|
||||||
|
@ -88,12 +88,10 @@ Function::referenced_location_variables() const {
|
||||||
std::vector<std::pair<Variable*, LocationDecoration*>> ret;
|
std::vector<std::pair<Variable*, LocationDecoration*>> ret;
|
||||||
|
|
||||||
for (auto* var : referenced_module_variables()) {
|
for (auto* var : referenced_module_variables()) {
|
||||||
if (auto* decos = var->As<DecoratedVariable>()) {
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decos->decorations()) {
|
if (auto* location = deco->As<LocationDecoration>()) {
|
||||||
if (auto* location = deco->As<LocationDecoration>()) {
|
ret.push_back({var, location});
|
||||||
ret.push_back({var, location});
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,22 +107,20 @@ Function::referenced_uniform_variables() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = var->As<DecoratedVariable>()) {
|
BindingDecoration* binding = nullptr;
|
||||||
BindingDecoration* binding = nullptr;
|
SetDecoration* set = nullptr;
|
||||||
SetDecoration* set = nullptr;
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* b = deco->As<BindingDecoration>()) {
|
||||||
if (auto* b = deco->As<BindingDecoration>()) {
|
binding = b;
|
||||||
binding = b;
|
} else if (auto* s = deco->As<SetDecoration>()) {
|
||||||
} else if (auto* s = deco->As<SetDecoration>()) {
|
set = s;
|
||||||
set = s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (binding == nullptr || set == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, set}});
|
|
||||||
}
|
}
|
||||||
|
if (binding == nullptr || set == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back({var, BindingInfo{binding, set}});
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -138,22 +134,20 @@ Function::referenced_storagebuffer_variables() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = var->As<DecoratedVariable>()) {
|
BindingDecoration* binding = nullptr;
|
||||||
BindingDecoration* binding = nullptr;
|
SetDecoration* set = nullptr;
|
||||||
SetDecoration* set = nullptr;
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* b = deco->As<BindingDecoration>()) {
|
||||||
if (auto* b = deco->As<BindingDecoration>()) {
|
binding = b;
|
||||||
binding = b;
|
} else if (auto* s = deco->As<SetDecoration>()) {
|
||||||
} else if (auto* s = deco->As<SetDecoration>()) {
|
set = s;
|
||||||
set = s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (binding == nullptr || set == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, set}});
|
|
||||||
}
|
}
|
||||||
|
if (binding == nullptr || set == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back({var, BindingInfo{binding, set}});
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -163,12 +157,10 @@ Function::referenced_builtin_variables() const {
|
||||||
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
|
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
|
||||||
|
|
||||||
for (auto* var : referenced_module_variables()) {
|
for (auto* var : referenced_module_variables()) {
|
||||||
if (auto* decorated = var->As<DecoratedVariable>()) {
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* builtin = deco->As<BuiltinDecoration>()) {
|
||||||
if (auto* builtin = deco->As<BuiltinDecoration>()) {
|
ret.push_back({var, builtin});
|
||||||
ret.push_back({var, builtin});
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,12 +192,10 @@ Function::local_referenced_builtin_variables() const {
|
||||||
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
|
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
|
||||||
|
|
||||||
for (auto* var : local_referenced_module_variables()) {
|
for (auto* var : local_referenced_module_variables()) {
|
||||||
if (auto* decorated = var->As<DecoratedVariable>()) {
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* builtin = deco->As<BuiltinDecoration>()) {
|
||||||
if (auto* builtin = deco->As<BuiltinDecoration>()) {
|
ret.push_back({var, builtin});
|
||||||
ret.push_back({var, builtin});
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,23 +304,21 @@ Function::ReferencedSamplerVariablesImpl(type::SamplerKind kind) const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = var->As<DecoratedVariable>()) {
|
BindingDecoration* binding = nullptr;
|
||||||
BindingDecoration* binding = nullptr;
|
SetDecoration* set = nullptr;
|
||||||
SetDecoration* set = nullptr;
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* b = deco->As<BindingDecoration>()) {
|
||||||
if (auto* b = deco->As<BindingDecoration>()) {
|
binding = b;
|
||||||
binding = b;
|
|
||||||
}
|
|
||||||
if (auto* s = deco->As<SetDecoration>()) {
|
|
||||||
set = s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (binding == nullptr || set == nullptr) {
|
if (auto* s = deco->As<SetDecoration>()) {
|
||||||
continue;
|
set = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, set}});
|
|
||||||
}
|
}
|
||||||
|
if (binding == nullptr || set == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back({var, BindingInfo{binding, set}});
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -353,22 +341,20 @@ Function::ReferencedSampledTextureVariablesImpl(bool multisampled) const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = var->As<DecoratedVariable>()) {
|
BindingDecoration* binding = nullptr;
|
||||||
BindingDecoration* binding = nullptr;
|
SetDecoration* set = nullptr;
|
||||||
SetDecoration* set = nullptr;
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* b = deco->As<BindingDecoration>()) {
|
||||||
if (auto* b = deco->As<BindingDecoration>()) {
|
binding = b;
|
||||||
binding = b;
|
} else if (auto* s = deco->As<SetDecoration>()) {
|
||||||
} else if (auto* s = deco->As<SetDecoration>()) {
|
set = s;
|
||||||
set = s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (binding == nullptr || set == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, set}});
|
|
||||||
}
|
}
|
||||||
|
if (binding == nullptr || set == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back({var, BindingInfo{binding, set}});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
|
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
|
@ -37,8 +36,9 @@ TEST_F(FunctionTest, Creation) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
auto* var = params[0];
|
auto* var = params[0];
|
||||||
|
|
||||||
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
||||||
|
@ -54,8 +54,9 @@ TEST_F(FunctionTest, Creation_WithSource) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
Function f(Source{Source::Location{20, 2}}, "func", params, &void_type,
|
Function f(Source{Source::Location{20, 2}}, "func", params, &void_type,
|
||||||
create<BlockStatement>(), FunctionDecorationList{});
|
create<BlockStatement>(), FunctionDecorationList{});
|
||||||
|
@ -68,7 +69,8 @@ TEST_F(FunctionTest, AddDuplicateReferencedVariables) {
|
||||||
type::Void void_type;
|
type::Void void_type;
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
Variable v(Source{}, "var", StorageClass::kInput, &i32);
|
Variable v(Source{}, "var", StorageClass::kInput, &i32, false, nullptr,
|
||||||
|
ast::VariableDecorationList{});
|
||||||
Function f(Source{}, "func", VariableList{}, &void_type,
|
Function f(Source{}, "func", VariableList{}, &void_type,
|
||||||
create<BlockStatement>(), FunctionDecorationList{});
|
create<BlockStatement>(), FunctionDecorationList{});
|
||||||
|
|
||||||
|
@ -79,7 +81,8 @@ TEST_F(FunctionTest, AddDuplicateReferencedVariables) {
|
||||||
f.add_referenced_module_variable(&v);
|
f.add_referenced_module_variable(&v);
|
||||||
ASSERT_EQ(f.referenced_module_variables().size(), 1u);
|
ASSERT_EQ(f.referenced_module_variables().size(), 1u);
|
||||||
|
|
||||||
Variable v2(Source{}, "var2", StorageClass::kOutput, &i32);
|
Variable v2(Source{}, "var2", StorageClass::kOutput, &i32, false, nullptr,
|
||||||
|
ast::VariableDecorationList{});
|
||||||
f.add_referenced_module_variable(&v2);
|
f.add_referenced_module_variable(&v2);
|
||||||
ASSERT_EQ(f.referenced_module_variables().size(), 2u);
|
ASSERT_EQ(f.referenced_module_variables().size(), 2u);
|
||||||
EXPECT_EQ(f.referenced_module_variables()[1], &v2);
|
EXPECT_EQ(f.referenced_module_variables()[1], &v2);
|
||||||
|
@ -89,38 +92,44 @@ TEST_F(FunctionTest, GetReferenceLocations) {
|
||||||
type::Void void_type;
|
type::Void void_type;
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
DecoratedVariable loc1(
|
auto* loc1 = create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32,
|
||||||
create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32));
|
false, nullptr,
|
||||||
loc1.set_decorations({create<LocationDecoration>(0, Source{})});
|
ast::VariableDecorationList{
|
||||||
|
create<LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
DecoratedVariable loc2(
|
auto* loc2 = create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32,
|
||||||
create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32));
|
false, nullptr,
|
||||||
loc2.set_decorations({create<LocationDecoration>(1, Source{})});
|
ast::VariableDecorationList{
|
||||||
|
create<LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
DecoratedVariable builtin1(
|
auto* builtin1 = create<Variable>(
|
||||||
create<Variable>(Source{}, "builtin1", StorageClass::kInput, &i32));
|
Source{}, "builtin1", StorageClass::kInput, &i32, false, nullptr,
|
||||||
builtin1.set_decorations(
|
ast::VariableDecorationList{
|
||||||
{create<BuiltinDecoration>(Builtin::kPosition, Source{})});
|
create<BuiltinDecoration>(Builtin::kPosition, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
DecoratedVariable builtin2(
|
auto* builtin2 = create<Variable>(
|
||||||
create<Variable>(Source{}, "builtin2", StorageClass::kInput, &i32));
|
Source{}, "builtin2", StorageClass::kInput, &i32, false, nullptr,
|
||||||
builtin2.set_decorations(
|
ast::VariableDecorationList{
|
||||||
{create<BuiltinDecoration>(Builtin::kFragDepth, Source{})});
|
create<BuiltinDecoration>(Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
Function f(Source{}, "func", VariableList{}, &void_type,
|
Function f(Source{}, "func", VariableList{}, &void_type,
|
||||||
create<BlockStatement>(), FunctionDecorationList{});
|
create<BlockStatement>(), FunctionDecorationList{});
|
||||||
|
|
||||||
f.add_referenced_module_variable(&loc1);
|
f.add_referenced_module_variable(loc1);
|
||||||
f.add_referenced_module_variable(&builtin1);
|
f.add_referenced_module_variable(builtin1);
|
||||||
f.add_referenced_module_variable(&loc2);
|
f.add_referenced_module_variable(loc2);
|
||||||
f.add_referenced_module_variable(&builtin2);
|
f.add_referenced_module_variable(builtin2);
|
||||||
ASSERT_EQ(f.referenced_module_variables().size(), 4u);
|
ASSERT_EQ(f.referenced_module_variables().size(), 4u);
|
||||||
|
|
||||||
auto ref_locs = f.referenced_location_variables();
|
auto ref_locs = f.referenced_location_variables();
|
||||||
ASSERT_EQ(ref_locs.size(), 2u);
|
ASSERT_EQ(ref_locs.size(), 2u);
|
||||||
EXPECT_EQ(ref_locs[0].first, &loc1);
|
EXPECT_EQ(ref_locs[0].first, loc1);
|
||||||
EXPECT_EQ(ref_locs[0].second->value(), 0u);
|
EXPECT_EQ(ref_locs[0].second->value(), 0u);
|
||||||
EXPECT_EQ(ref_locs[1].first, &loc2);
|
EXPECT_EQ(ref_locs[1].first, loc2);
|
||||||
EXPECT_EQ(ref_locs[1].second->value(), 1u);
|
EXPECT_EQ(ref_locs[1].second->value(), 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,38 +137,44 @@ TEST_F(FunctionTest, GetReferenceBuiltins) {
|
||||||
type::Void void_type;
|
type::Void void_type;
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
DecoratedVariable loc1(
|
auto* loc1 = create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32,
|
||||||
create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32));
|
false, nullptr,
|
||||||
loc1.set_decorations({create<LocationDecoration>(0, Source{})});
|
ast::VariableDecorationList{
|
||||||
|
create<LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
DecoratedVariable loc2(
|
auto* loc2 = create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32,
|
||||||
create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32));
|
false, nullptr,
|
||||||
loc2.set_decorations({create<LocationDecoration>(1, Source{})});
|
ast::VariableDecorationList{
|
||||||
|
create<LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
DecoratedVariable builtin1(
|
auto* builtin1 = create<Variable>(
|
||||||
create<Variable>(Source{}, "builtin1", StorageClass::kInput, &i32));
|
Source{}, "builtin1", StorageClass::kInput, &i32, false, nullptr,
|
||||||
builtin1.set_decorations(
|
ast::VariableDecorationList{
|
||||||
{create<BuiltinDecoration>(Builtin::kPosition, Source{})});
|
create<BuiltinDecoration>(Builtin::kPosition, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
DecoratedVariable builtin2(
|
auto* builtin2 = create<Variable>(
|
||||||
create<Variable>(Source{}, "builtin2", StorageClass::kInput, &i32));
|
Source{}, "builtin2", StorageClass::kInput, &i32, false, nullptr,
|
||||||
builtin2.set_decorations(
|
ast::VariableDecorationList{
|
||||||
{create<BuiltinDecoration>(Builtin::kFragDepth, Source{})});
|
create<BuiltinDecoration>(Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
Function f(Source{}, "func", VariableList{}, &void_type,
|
Function f(Source{}, "func", VariableList{}, &void_type,
|
||||||
create<BlockStatement>(), FunctionDecorationList{});
|
create<BlockStatement>(), FunctionDecorationList{});
|
||||||
|
|
||||||
f.add_referenced_module_variable(&loc1);
|
f.add_referenced_module_variable(loc1);
|
||||||
f.add_referenced_module_variable(&builtin1);
|
f.add_referenced_module_variable(builtin1);
|
||||||
f.add_referenced_module_variable(&loc2);
|
f.add_referenced_module_variable(loc2);
|
||||||
f.add_referenced_module_variable(&builtin2);
|
f.add_referenced_module_variable(builtin2);
|
||||||
ASSERT_EQ(f.referenced_module_variables().size(), 4u);
|
ASSERT_EQ(f.referenced_module_variables().size(), 4u);
|
||||||
|
|
||||||
auto ref_locs = f.referenced_builtin_variables();
|
auto ref_locs = f.referenced_builtin_variables();
|
||||||
ASSERT_EQ(ref_locs.size(), 2u);
|
ASSERT_EQ(ref_locs.size(), 2u);
|
||||||
EXPECT_EQ(ref_locs[0].first, &builtin1);
|
EXPECT_EQ(ref_locs[0].first, builtin1);
|
||||||
EXPECT_EQ(ref_locs[0].second->value(), Builtin::kPosition);
|
EXPECT_EQ(ref_locs[0].second->value(), Builtin::kPosition);
|
||||||
EXPECT_EQ(ref_locs[1].first, &builtin2);
|
EXPECT_EQ(ref_locs[1].first, builtin2);
|
||||||
EXPECT_EQ(ref_locs[1].second->value(), Builtin::kFragDepth);
|
EXPECT_EQ(ref_locs[1].second->value(), Builtin::kFragDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +197,9 @@ TEST_F(FunctionTest, IsValid) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
auto* body = create<BlockStatement>();
|
auto* body = create<BlockStatement>();
|
||||||
body->append(create<DiscardStatement>());
|
body->append(create<DiscardStatement>());
|
||||||
|
@ -198,8 +214,9 @@ TEST_F(FunctionTest, IsValid_EmptyName) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
Function f(Source{}, "", params, &void_type, create<BlockStatement>(),
|
Function f(Source{}, "", params, &void_type, create<BlockStatement>(),
|
||||||
FunctionDecorationList{});
|
FunctionDecorationList{});
|
||||||
|
@ -210,8 +227,9 @@ TEST_F(FunctionTest, IsValid_MissingReturnType) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
Function f(Source{}, "func", params, nullptr, create<BlockStatement>(),
|
Function f(Source{}, "func", params, nullptr, create<BlockStatement>(),
|
||||||
FunctionDecorationList{});
|
FunctionDecorationList{});
|
||||||
|
@ -223,8 +241,9 @@ TEST_F(FunctionTest, IsValid_NullParam) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
params.push_back(nullptr);
|
params.push_back(nullptr);
|
||||||
|
|
||||||
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
||||||
|
@ -236,8 +255,9 @@ TEST_F(FunctionTest, IsValid_InvalidParam) {
|
||||||
type::Void void_type;
|
type::Void void_type;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, nullptr));
|
nullptr, false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
||||||
FunctionDecorationList{});
|
FunctionDecorationList{});
|
||||||
|
@ -249,8 +269,9 @@ TEST_F(FunctionTest, IsValid_NullBodyStatement) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
auto* body = create<BlockStatement>();
|
auto* body = create<BlockStatement>();
|
||||||
body->append(create<DiscardStatement>());
|
body->append(create<DiscardStatement>());
|
||||||
|
@ -267,8 +288,9 @@ TEST_F(FunctionTest, IsValid_InvalidBodyStatement) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
auto* body = create<BlockStatement>();
|
auto* body = create<BlockStatement>();
|
||||||
body->append(create<DiscardStatement>());
|
body->append(create<DiscardStatement>());
|
||||||
|
@ -325,8 +347,9 @@ TEST_F(FunctionTest, ToStr_WithParams) {
|
||||||
type::I32 i32;
|
type::I32 i32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
auto* body = create<BlockStatement>();
|
auto* body = create<BlockStatement>();
|
||||||
body->append(create<DiscardStatement>());
|
body->append(create<DiscardStatement>());
|
||||||
|
@ -364,10 +387,12 @@ TEST_F(FunctionTest, TypeName_WithParams) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
|
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(
|
params.push_back(create<Variable>(Source{}, "var1", StorageClass::kNone, &i32,
|
||||||
create<Variable>(Source{}, "var1", StorageClass::kNone, &i32));
|
false, nullptr,
|
||||||
params.push_back(
|
ast::VariableDecorationList{}));
|
||||||
create<Variable>(Source{}, "var2", StorageClass::kNone, &f32));
|
params.push_back(create<Variable>(Source{}, "var2", StorageClass::kNone, &f32,
|
||||||
|
false, nullptr,
|
||||||
|
ast::VariableDecorationList{}));
|
||||||
|
|
||||||
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
|
||||||
FunctionDecorationList{});
|
FunctionDecorationList{});
|
||||||
|
|
|
@ -67,7 +67,8 @@ TEST_F(ModuleTest, IsValid_Empty) {
|
||||||
|
|
||||||
TEST_F(ModuleTest, IsValid_GlobalVariable) {
|
TEST_F(ModuleTest, IsValid_GlobalVariable) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, &f32);
|
auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, &f32,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
Module m;
|
Module m;
|
||||||
m.AddGlobalVariable(var);
|
m.AddGlobalVariable(var);
|
||||||
|
@ -81,7 +82,8 @@ TEST_F(ModuleTest, IsValid_Null_GlobalVariable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
|
TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
|
||||||
auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, nullptr);
|
auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, nullptr,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
Module m;
|
Module m;
|
||||||
m.AddGlobalVariable(var);
|
m.AddGlobalVariable(var);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "src/ast/clone_context.h"
|
#include "src/ast/clone_context.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
|
TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
|
||||||
|
@ -25,24 +25,66 @@ TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
Variable::Variable() = default;
|
|
||||||
|
|
||||||
Variable::Variable(const Source& source,
|
Variable::Variable(const Source& source,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
StorageClass sc,
|
StorageClass sc,
|
||||||
type::Type* type)
|
type::Type* type,
|
||||||
: Base(source), name_(name), storage_class_(sc), type_(type) {}
|
bool is_const,
|
||||||
|
Expression* constructor,
|
||||||
|
VariableDecorationList decorations)
|
||||||
|
: Base(source),
|
||||||
|
name_(name),
|
||||||
|
storage_class_(sc),
|
||||||
|
type_(type),
|
||||||
|
is_const_(is_const),
|
||||||
|
constructor_(constructor),
|
||||||
|
decorations_(std::move(decorations)) {}
|
||||||
|
|
||||||
Variable::Variable(Variable&&) = default;
|
Variable::Variable(Variable&&) = default;
|
||||||
|
|
||||||
Variable::~Variable() = default;
|
Variable::~Variable() = default;
|
||||||
|
|
||||||
|
bool Variable::HasLocationDecoration() const {
|
||||||
|
for (auto* deco : decorations_) {
|
||||||
|
if (deco->Is<LocationDecoration>()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Variable::HasBuiltinDecoration() const {
|
||||||
|
for (auto* deco : decorations_) {
|
||||||
|
if (deco->Is<BuiltinDecoration>()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Variable::HasConstantIdDecoration() const {
|
||||||
|
for (auto* deco : decorations_) {
|
||||||
|
if (deco->Is<ConstantIdDecoration>()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Variable::constant_id() const {
|
||||||
|
assert(HasConstantIdDecoration());
|
||||||
|
for (auto* deco : decorations_) {
|
||||||
|
if (auto* cid = deco->As<ConstantIdDecoration>()) {
|
||||||
|
return cid->value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Variable* Variable::Clone(CloneContext* ctx) const {
|
Variable* Variable::Clone(CloneContext* ctx) const {
|
||||||
auto* cloned = ctx->mod->create<Variable>(
|
return ctx->mod->create<Variable>(
|
||||||
ctx->Clone(source()), name(), storage_class(), ctx->Clone(type()));
|
ctx->Clone(source()), name(), storage_class(), ctx->Clone(type()),
|
||||||
cloned->set_constructor(ctx->Clone(constructor()));
|
is_const_, ctx->Clone(constructor()), ctx->Clone(decorations_));
|
||||||
cloned->set_is_const(is_const());
|
|
||||||
return cloned;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variable::IsValid() const {
|
bool Variable::IsValid() const {
|
||||||
|
@ -87,6 +129,17 @@ void Variable::to_str(std::ostream& out, size_t indent) const {
|
||||||
out << "Const";
|
out << "Const";
|
||||||
}
|
}
|
||||||
out << "{" << std::endl;
|
out << "{" << std::endl;
|
||||||
|
|
||||||
|
if (!decorations_.empty()) {
|
||||||
|
make_indent(out, indent + 2);
|
||||||
|
out << "Decorations{" << std::endl;
|
||||||
|
for (auto* deco : decorations_) {
|
||||||
|
deco->to_str(out, indent + 4);
|
||||||
|
}
|
||||||
|
make_indent(out, indent + 2);
|
||||||
|
out << "}" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
info_to_str(out, indent + 2);
|
info_to_str(out, indent + 2);
|
||||||
constructor_to_str(out, indent + 2);
|
constructor_to_str(out, indent + 2);
|
||||||
make_indent(out, indent);
|
make_indent(out, indent);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "src/ast/node.h"
|
#include "src/ast/node.h"
|
||||||
#include "src/ast/storage_class.h"
|
#include "src/ast/storage_class.h"
|
||||||
#include "src/ast/type/type.h"
|
#include "src/ast/type/type.h"
|
||||||
|
#include "src/ast/variable_decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
@ -83,25 +84,24 @@ class Variable : public Castable<Variable, Node> {
|
||||||
/// @param name the variables name
|
/// @param name the variables name
|
||||||
/// @param sc the variable storage class
|
/// @param sc the variable storage class
|
||||||
/// @param type the value type
|
/// @param type the value type
|
||||||
|
/// @param is_const true if the variable is const
|
||||||
|
/// @param constructor the constructor expression
|
||||||
|
/// @param decorations the variable decorations
|
||||||
Variable(const Source& source,
|
Variable(const Source& source,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
StorageClass sc,
|
StorageClass sc,
|
||||||
type::Type* type);
|
type::Type* type,
|
||||||
|
bool is_const,
|
||||||
|
Expression* constructor,
|
||||||
|
VariableDecorationList decorations);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Variable(Variable&&);
|
Variable(Variable&&);
|
||||||
|
|
||||||
~Variable() override;
|
~Variable() override;
|
||||||
|
|
||||||
/// Sets the variable name
|
|
||||||
/// @param name the name to set
|
|
||||||
void set_name(const std::string& name) { name_ = name; }
|
|
||||||
/// @returns the variable name
|
/// @returns the variable name
|
||||||
const std::string& name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
|
|
||||||
/// Sets the value type if a const or formal parameter, or the
|
|
||||||
/// store type if a var.
|
|
||||||
/// @param type the type
|
|
||||||
void set_type(type::Type* type) { type_ = type; }
|
|
||||||
/// @returns the variable's type.
|
/// @returns the variable's type.
|
||||||
type::Type* type() const { return type_; }
|
type::Type* type() const { return type_; }
|
||||||
|
|
||||||
|
@ -111,20 +111,28 @@ class Variable : public Castable<Variable, Node> {
|
||||||
/// @returns the storage class
|
/// @returns the storage class
|
||||||
StorageClass storage_class() const { return storage_class_; }
|
StorageClass storage_class() const { return storage_class_; }
|
||||||
|
|
||||||
/// Sets the constructor
|
|
||||||
/// @param expr the constructor expression
|
|
||||||
void set_constructor(Expression* expr) { constructor_ = expr; }
|
|
||||||
/// @returns the constructor expression or nullptr if none set
|
/// @returns the constructor expression or nullptr if none set
|
||||||
Expression* constructor() const { return constructor_; }
|
Expression* constructor() const { return constructor_; }
|
||||||
/// @returns true if the variable has an constructor
|
/// @returns true if the variable has an constructor
|
||||||
bool has_constructor() const { return constructor_ != nullptr; }
|
bool has_constructor() const { return constructor_ != nullptr; }
|
||||||
|
|
||||||
/// Sets if the variable is constant
|
|
||||||
/// @param val the value to be set
|
|
||||||
void set_is_const(bool val) { is_const_ = val; }
|
|
||||||
/// @returns true if this is a constant, false otherwise
|
/// @returns true if this is a constant, false otherwise
|
||||||
bool is_const() const { return is_const_; }
|
bool is_const() const { return is_const_; }
|
||||||
|
|
||||||
|
/// @returns the decorations attached to this variable
|
||||||
|
const VariableDecorationList& decorations() const { return decorations_; }
|
||||||
|
|
||||||
|
/// @returns true if the decorations include a LocationDecoration
|
||||||
|
bool HasLocationDecoration() const;
|
||||||
|
/// @returns true if the deocrations include a BuiltinDecoration
|
||||||
|
bool HasBuiltinDecoration() const;
|
||||||
|
/// @returns true if the decorations include a ConstantIdDecoration
|
||||||
|
bool HasConstantIdDecoration() const;
|
||||||
|
|
||||||
|
/// @returns the constant_id value for the variable. Assumes that
|
||||||
|
/// HasConstantIdDecoration() has been called first.
|
||||||
|
uint32_t constant_id() const;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @note Semantic information such as resolved expression type and intrinsic
|
/// @note Semantic information such as resolved expression type and intrinsic
|
||||||
|
@ -142,10 +150,6 @@ class Variable : public Castable<Variable, Node> {
|
||||||
void to_str(std::ostream& out, size_t indent) const override;
|
void to_str(std::ostream& out, size_t indent) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Constructor
|
|
||||||
/// Used by the DecoratedVariable constructor.
|
|
||||||
Variable();
|
|
||||||
|
|
||||||
/// Output information for this variable.
|
/// Output information for this variable.
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
/// @param indent number of spaces to indent the node when writing
|
/// @param indent number of spaces to indent the node when writing
|
||||||
|
@ -158,12 +162,13 @@ class Variable : public Castable<Variable, Node> {
|
||||||
private:
|
private:
|
||||||
Variable(const Variable&) = delete;
|
Variable(const Variable&) = delete;
|
||||||
|
|
||||||
bool is_const_ = false;
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
StorageClass storage_class_ = StorageClass::kNone;
|
StorageClass storage_class_ = StorageClass::kNone;
|
||||||
// The value type if a const or formal paramter, and the store type if a var
|
// The value type if a const or formal paramter, and the store type if a var
|
||||||
type::Type* type_ = nullptr;
|
type::Type* type_ = nullptr;
|
||||||
|
bool is_const_ = false;
|
||||||
Expression* constructor_ = nullptr;
|
Expression* constructor_ = nullptr;
|
||||||
|
VariableDecorationList decorations_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A list of variables
|
/// A list of variables
|
||||||
|
|
|
@ -26,7 +26,8 @@ using VariableDeclStatementTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, Creation) {
|
TEST_F(VariableDeclStatementTest, Creation) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32);
|
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
VariableDeclStatement stmt(var);
|
VariableDeclStatement stmt(var);
|
||||||
EXPECT_EQ(stmt.variable(), var);
|
EXPECT_EQ(stmt.variable(), var);
|
||||||
|
@ -34,7 +35,8 @@ TEST_F(VariableDeclStatementTest, Creation) {
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, Creation_WithSource) {
|
TEST_F(VariableDeclStatementTest, Creation_WithSource) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32);
|
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var);
|
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var);
|
||||||
auto src = stmt.source();
|
auto src = stmt.source();
|
||||||
|
@ -44,7 +46,8 @@ TEST_F(VariableDeclStatementTest, Creation_WithSource) {
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, IsVariableDecl) {
|
TEST_F(VariableDeclStatementTest, IsVariableDecl) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32);
|
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
VariableDeclStatement s(var);
|
VariableDeclStatement s(var);
|
||||||
EXPECT_TRUE(s.Is<VariableDeclStatement>());
|
EXPECT_TRUE(s.Is<VariableDeclStatement>());
|
||||||
|
@ -52,14 +55,16 @@ TEST_F(VariableDeclStatementTest, IsVariableDecl) {
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, IsValid) {
|
TEST_F(VariableDeclStatementTest, IsValid) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32);
|
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
VariableDeclStatement stmt(var);
|
VariableDeclStatement stmt(var);
|
||||||
EXPECT_TRUE(stmt.IsValid());
|
EXPECT_TRUE(stmt.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
|
TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "", StorageClass::kNone, &f32);
|
auto* var = create<Variable>(Source{}, "", StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
VariableDeclStatement stmt(var);
|
VariableDeclStatement stmt(var);
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
EXPECT_FALSE(stmt.IsValid());
|
||||||
}
|
}
|
||||||
|
@ -71,7 +76,8 @@ TEST_F(VariableDeclStatementTest, IsValid_NullVariable) {
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, ToStr) {
|
TEST_F(VariableDeclStatementTest, ToStr) {
|
||||||
type::F32 f32;
|
type::F32 f32;
|
||||||
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32);
|
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var);
|
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var);
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "src/ast/variable.h"
|
#include "src/ast/variable.h"
|
||||||
|
|
||||||
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
|
@ -27,7 +28,8 @@ using VariableTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(VariableTest, Creation) {
|
TEST_F(VariableTest, Creation) {
|
||||||
type::I32 t;
|
type::I32 t;
|
||||||
Variable v(Source{}, "my_var", StorageClass::kFunction, &t);
|
Variable v(Source{}, "my_var", StorageClass::kFunction, &t, false, nullptr,
|
||||||
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_EQ(v.name(), "my_var");
|
EXPECT_EQ(v.name(), "my_var");
|
||||||
EXPECT_EQ(v.storage_class(), StorageClass::kFunction);
|
EXPECT_EQ(v.storage_class(), StorageClass::kFunction);
|
||||||
|
@ -41,7 +43,8 @@ TEST_F(VariableTest, Creation) {
|
||||||
TEST_F(VariableTest, CreationWithSource) {
|
TEST_F(VariableTest, CreationWithSource) {
|
||||||
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
|
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
|
||||||
type::F32 t;
|
type::F32 t;
|
||||||
Variable v(s, "i", StorageClass::kPrivate, &t);
|
Variable v(s, "i", StorageClass::kPrivate, &t, false, nullptr,
|
||||||
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_EQ(v.name(), "i");
|
EXPECT_EQ(v.name(), "i");
|
||||||
EXPECT_EQ(v.storage_class(), StorageClass::kPrivate);
|
EXPECT_EQ(v.storage_class(), StorageClass::kPrivate);
|
||||||
|
@ -55,7 +58,8 @@ TEST_F(VariableTest, CreationWithSource) {
|
||||||
TEST_F(VariableTest, CreationEmpty) {
|
TEST_F(VariableTest, CreationEmpty) {
|
||||||
type::I32 t;
|
type::I32 t;
|
||||||
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}};
|
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}};
|
||||||
Variable v(s, "a_var", StorageClass::kWorkgroup, &t);
|
Variable v(s, "a_var", StorageClass::kWorkgroup, &t, false, nullptr,
|
||||||
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_EQ(v.name(), "a_var");
|
EXPECT_EQ(v.name(), "a_var");
|
||||||
EXPECT_EQ(v.storage_class(), StorageClass::kWorkgroup);
|
EXPECT_EQ(v.storage_class(), StorageClass::kWorkgroup);
|
||||||
|
@ -68,43 +72,58 @@ TEST_F(VariableTest, CreationEmpty) {
|
||||||
|
|
||||||
TEST_F(VariableTest, IsValid) {
|
TEST_F(VariableTest, IsValid) {
|
||||||
type::I32 t;
|
type::I32 t;
|
||||||
Variable v{Source{}, "my_var", StorageClass::kNone, &t};
|
Variable v{Source{}, "my_var", StorageClass::kNone, &t,
|
||||||
|
false, nullptr, ast::VariableDecorationList{}};
|
||||||
EXPECT_TRUE(v.IsValid());
|
EXPECT_TRUE(v.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, IsValid_WithConstructor) {
|
TEST_F(VariableTest, IsValid_WithConstructor) {
|
||||||
type::I32 t;
|
type::I32 t;
|
||||||
Variable v{Source{}, "my_var", StorageClass::kNone, &t};
|
Variable v{Source{},
|
||||||
v.set_constructor(create<IdentifierExpression>("ident"));
|
"my_var",
|
||||||
|
StorageClass::kNone,
|
||||||
|
&t,
|
||||||
|
false,
|
||||||
|
create<IdentifierExpression>("ident"),
|
||||||
|
ast::VariableDecorationList{}};
|
||||||
EXPECT_TRUE(v.IsValid());
|
EXPECT_TRUE(v.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, IsValid_MissinName) {
|
TEST_F(VariableTest, IsValid_MissinName) {
|
||||||
type::I32 t;
|
type::I32 t;
|
||||||
Variable v{Source{}, "", StorageClass::kNone, &t};
|
Variable v{Source{}, "", StorageClass::kNone, &t,
|
||||||
|
false, nullptr, ast::VariableDecorationList{}};
|
||||||
EXPECT_FALSE(v.IsValid());
|
EXPECT_FALSE(v.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, IsValid_MissingType) {
|
TEST_F(VariableTest, IsValid_MissingType) {
|
||||||
Variable v{Source{}, "x", StorageClass::kNone, nullptr};
|
Variable v{Source{}, "x", StorageClass::kNone, nullptr,
|
||||||
|
false, nullptr, ast::VariableDecorationList{}};
|
||||||
EXPECT_FALSE(v.IsValid());
|
EXPECT_FALSE(v.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, IsValid_MissingBoth) {
|
TEST_F(VariableTest, IsValid_MissingBoth) {
|
||||||
Variable v{Source{}, "", StorageClass::kNone, nullptr};
|
Variable v{Source{}, "", StorageClass::kNone, nullptr,
|
||||||
|
false, nullptr, ast::VariableDecorationList{}};
|
||||||
EXPECT_FALSE(v.IsValid());
|
EXPECT_FALSE(v.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, IsValid_InvalidConstructor) {
|
TEST_F(VariableTest, IsValid_InvalidConstructor) {
|
||||||
type::I32 t;
|
type::I32 t;
|
||||||
Variable v{Source{}, "my_var", StorageClass::kNone, &t};
|
Variable v{Source{},
|
||||||
v.set_constructor(create<IdentifierExpression>(""));
|
"my_var",
|
||||||
|
StorageClass::kNone,
|
||||||
|
&t,
|
||||||
|
false,
|
||||||
|
create<IdentifierExpression>(""),
|
||||||
|
ast::VariableDecorationList{}};
|
||||||
EXPECT_FALSE(v.IsValid());
|
EXPECT_FALSE(v.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, to_str) {
|
TEST_F(VariableTest, to_str) {
|
||||||
type::F32 t;
|
type::F32 t;
|
||||||
Variable v{Source{}, "my_var", StorageClass::kFunction, &t};
|
Variable v{Source{}, "my_var", StorageClass::kFunction, &t,
|
||||||
|
false, nullptr, ast::VariableDecorationList{}};
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
v.to_str(out, 2);
|
v.to_str(out, 2);
|
||||||
EXPECT_EQ(out.str(), R"( Variable{
|
EXPECT_EQ(out.str(), R"( Variable{
|
||||||
|
@ -115,6 +134,58 @@ TEST_F(VariableTest, to_str) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(VariableTest, WithDecorations) {
|
||||||
|
type::F32 t;
|
||||||
|
auto* var = create<Variable>(
|
||||||
|
Source{}, "my_var", StorageClass::kFunction, &t, false, nullptr,
|
||||||
|
VariableDecorationList{
|
||||||
|
create<LocationDecoration>(1, Source{}),
|
||||||
|
create<BuiltinDecoration>(Builtin::kPosition, Source{}),
|
||||||
|
create<ConstantIdDecoration>(1200, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_TRUE(var->HasLocationDecoration());
|
||||||
|
EXPECT_TRUE(var->HasBuiltinDecoration());
|
||||||
|
EXPECT_TRUE(var->HasConstantIdDecoration());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(VariableTest, ConstantId) {
|
||||||
|
type::F32 t;
|
||||||
|
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t,
|
||||||
|
false, nullptr,
|
||||||
|
VariableDecorationList{
|
||||||
|
create<ConstantIdDecoration>(1200, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_EQ(var->constant_id(), 1200u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(VariableTest, Decorated_to_str) {
|
||||||
|
type::F32 t;
|
||||||
|
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t,
|
||||||
|
false, create<IdentifierExpression>("expr"),
|
||||||
|
VariableDecorationList{
|
||||||
|
create<BindingDecoration>(2, Source{}),
|
||||||
|
create<SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
var->to_str(out, 2);
|
||||||
|
EXPECT_EQ(out.str(), R"( Variable{
|
||||||
|
Decorations{
|
||||||
|
BindingDecoration{2}
|
||||||
|
SetDecoration{1}
|
||||||
|
}
|
||||||
|
my_var
|
||||||
|
function
|
||||||
|
__f32
|
||||||
|
{
|
||||||
|
Identifier[not set]{expr}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "src/ast/bool_literal.h"
|
#include "src/ast/bool_literal.h"
|
||||||
#include "src/ast/constructor_expression.h"
|
#include "src/ast/constructor_expression.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/null_literal.h"
|
#include "src/ast/null_literal.h"
|
||||||
|
@ -39,6 +38,7 @@
|
||||||
#include "src/ast/type/u32_type.h"
|
#include "src/ast/type/u32_type.h"
|
||||||
#include "src/ast/type/vector_type.h"
|
#include "src/ast/type/vector_type.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace inspector {
|
namespace inspector {
|
||||||
|
@ -91,12 +91,7 @@ std::string Inspector::GetRemappedNameForEntryPoint(
|
||||||
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
|
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
|
||||||
std::map<uint32_t, Scalar> result;
|
std::map<uint32_t, Scalar> result;
|
||||||
for (auto* var : module_.global_variables()) {
|
for (auto* var : module_.global_variables()) {
|
||||||
auto* decorated = var->As<ast::DecoratedVariable>();
|
if (!var->HasConstantIdDecoration()) {
|
||||||
if (decorated == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!decorated->HasConstantIdDecoration()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +99,7 @@ std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
|
||||||
// WGSL, so the validator should catch it. Thus here the inspector just
|
// WGSL, so the validator should catch it. Thus here the inspector just
|
||||||
// assumes all definitians of the constant id are the same, so only needs
|
// assumes all definitians of the constant id are the same, so only needs
|
||||||
// to find the first reference to constant id.
|
// to find the first reference to constant id.
|
||||||
uint32_t constant_id = decorated->constant_id();
|
uint32_t constant_id = var->constant_id();
|
||||||
if (result.find(constant_id) != result.end()) {
|
if (result.find(constant_id) != result.end()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
@ -56,6 +55,7 @@
|
||||||
#include "src/ast/type/vector_type.h"
|
#include "src/ast/type/vector_type.h"
|
||||||
#include "src/ast/type/void_type.h"
|
#include "src/ast/type/void_type.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/ast/variable_decoration.h"
|
#include "src/ast/variable_decoration.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_decoration.h"
|
||||||
|
@ -114,10 +114,22 @@ class InspectorHelper {
|
||||||
for (auto inout : inout_vars) {
|
for (auto inout : inout_vars) {
|
||||||
std::string in, out;
|
std::string in, out;
|
||||||
std::tie(in, out) = inout;
|
std::tie(in, out) = inout;
|
||||||
auto* in_var = create<ast::Variable>(
|
auto* in_var =
|
||||||
Source{}, in, ast::StorageClass::kInput, u32_type());
|
create<ast::Variable>(Source{}, // source
|
||||||
auto* out_var = create<ast::Variable>(
|
in, // name
|
||||||
Source{}, out, ast::StorageClass::kOutput, u32_type());
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
u32_type(), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* out_var =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
out, // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
u32_type(), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
mod()->AddGlobalVariable(in_var);
|
mod()->AddGlobalVariable(in_var);
|
||||||
mod()->AddGlobalVariable(out_var);
|
mod()->AddGlobalVariable(out_var);
|
||||||
}
|
}
|
||||||
|
@ -187,17 +199,23 @@ class InspectorHelper {
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
ast::type::Type* type,
|
ast::type::Type* type,
|
||||||
T* val) {
|
T* val) {
|
||||||
auto* dvar = create<ast::DecoratedVariable>(
|
ast::Expression* constructor = nullptr;
|
||||||
create<ast::Variable>(Source{}, name, ast::StorageClass::kNone, type));
|
|
||||||
dvar->set_is_const(true);
|
|
||||||
ast::VariableDecorationList decos;
|
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(id, Source{}));
|
|
||||||
dvar->set_decorations(decos);
|
|
||||||
if (val) {
|
if (val) {
|
||||||
dvar->set_constructor(
|
constructor =
|
||||||
create<ast::ScalarConstructorExpression>(MakeLiteral(type, val)));
|
create<ast::ScalarConstructorExpression>(MakeLiteral(type, val));
|
||||||
}
|
}
|
||||||
mod()->AddGlobalVariable(dvar);
|
auto* var = create<ast::Variable>(
|
||||||
|
Source{}, // source
|
||||||
|
name, // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
type, // type
|
||||||
|
true, // is_const
|
||||||
|
constructor, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(id, Source{}),
|
||||||
|
});
|
||||||
|
mod()->AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param type AST type of the literal, must resolve to BoolLiteral
|
/// @param type AST type of the literal, must resolve to BoolLiteral
|
||||||
|
@ -348,13 +366,18 @@ class InspectorHelper {
|
||||||
ast::StorageClass storage_class,
|
ast::StorageClass storage_class,
|
||||||
uint32_t set,
|
uint32_t set,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
auto* var = create<ast::DecoratedVariable>(
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, name, storage_class, type));
|
Source{}, // source
|
||||||
ast::VariableDecorationList decorations;
|
name, // name
|
||||||
|
storage_class, // storage_class
|
||||||
decorations.push_back(create<ast::BindingDecoration>(binding, Source{}));
|
type, // type
|
||||||
decorations.push_back(create<ast::SetDecoration>(set, Source{}));
|
false, // is_const
|
||||||
var->set_decorations(decorations);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(binding, Source{}),
|
||||||
|
create<ast::SetDecoration>(set, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
mod()->AddGlobalVariable(var);
|
mod()->AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
|
@ -399,9 +422,14 @@ class InspectorHelper {
|
||||||
ast::type::Type* member_type;
|
ast::type::Type* member_type;
|
||||||
std::tie(member_idx, member_type) = member;
|
std::tie(member_idx, member_type) = member;
|
||||||
std::string member_name = StructMemberName(member_idx, member_type);
|
std::string member_name = StructMemberName(member_idx, member_type);
|
||||||
body->append(create<ast::VariableDeclStatement>(
|
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "local" + member_name,
|
Source{}, // source
|
||||||
ast::StorageClass::kNone, member_type)));
|
"local" + member_name, // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
member_type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}))); // decorations
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto member : members) {
|
for (auto member : members) {
|
||||||
|
@ -496,7 +524,13 @@ class InspectorHelper {
|
||||||
|
|
||||||
void AddGlobalVariable(const std::string& name, ast::type::Type* type) {
|
void AddGlobalVariable(const std::string& name, ast::type::Type* type) {
|
||||||
mod()->AddGlobalVariable(create<ast::Variable>(
|
mod()->AddGlobalVariable(create<ast::Variable>(
|
||||||
Source{}, name, ast::StorageClass::kUniformConstant, type));
|
Source{}, // source
|
||||||
|
name, // name
|
||||||
|
ast::StorageClass::kUniformConstant, // storage_class
|
||||||
|
type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a depth texture variable to the module
|
/// Adds a depth texture variable to the module
|
||||||
|
@ -504,7 +538,13 @@ class InspectorHelper {
|
||||||
/// @param type the type to use
|
/// @param type the type to use
|
||||||
void AddDepthTexture(const std::string& name, ast::type::Type* type) {
|
void AddDepthTexture(const std::string& name, ast::type::Type* type) {
|
||||||
mod()->AddGlobalVariable(create<ast::Variable>(
|
mod()->AddGlobalVariable(create<ast::Variable>(
|
||||||
Source{}, name, ast::StorageClass::kUniformConstant, type));
|
Source{}, // source
|
||||||
|
name, // name
|
||||||
|
ast::StorageClass::kUniformConstant, // storage_class
|
||||||
|
type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a function that references a specific sampler variable
|
/// Generates a function that references a specific sampler variable
|
||||||
|
@ -526,9 +566,14 @@ class InspectorHelper {
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
|
|
||||||
auto* call_result = create<ast::Variable>(Source{}, "sampler_result",
|
auto* call_result =
|
||||||
ast::StorageClass::kFunction,
|
create<ast::Variable>(Source{}, // source
|
||||||
vec_type(base_type, 4));
|
"sampler_result", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
vec_type(base_type, 4), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
body->append(create<ast::VariableDeclStatement>(call_result));
|
body->append(create<ast::VariableDeclStatement>(call_result));
|
||||||
|
|
||||||
ast::ExpressionList call_params;
|
ast::ExpressionList call_params;
|
||||||
|
@ -567,9 +612,14 @@ class InspectorHelper {
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
|
|
||||||
auto* call_result = create<ast::Variable>(Source{}, "sampler_result",
|
auto* call_result =
|
||||||
ast::StorageClass::kFunction,
|
create<ast::Variable>(Source{}, // source
|
||||||
vec_type(base_type, 4));
|
"sampler_result", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
vec_type(base_type, 4), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
body->append(create<ast::VariableDeclStatement>(call_result));
|
body->append(create<ast::VariableDeclStatement>(call_result));
|
||||||
|
|
||||||
ast::ExpressionList call_params;
|
ast::ExpressionList call_params;
|
||||||
|
@ -610,8 +660,14 @@ class InspectorHelper {
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
|
|
||||||
auto* call_result = create<ast::Variable>(
|
auto* call_result =
|
||||||
Source{}, "sampler_result", ast::StorageClass::kFunction, base_type);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"sampler_result", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
base_type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
body->append(create<ast::VariableDeclStatement>(call_result));
|
body->append(create<ast::VariableDeclStatement>(call_result));
|
||||||
|
|
||||||
ast::ExpressionList call_params;
|
ast::ExpressionList call_params;
|
||||||
|
|
|
@ -803,9 +803,9 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
|
||||||
auto* ast_type = parser_impl_.ConvertType(param->type_id());
|
auto* ast_type = parser_impl_.ConvertType(param->type_id());
|
||||||
if (ast_type != nullptr) {
|
if (ast_type != nullptr) {
|
||||||
auto* ast_param = parser_impl_.MakeVariable(
|
auto* ast_param = parser_impl_.MakeVariable(
|
||||||
param->result_id(), ast::StorageClass::kNone, ast_type);
|
param->result_id(), ast::StorageClass::kNone, ast_type, true,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
// Parameters are treated as const declarations.
|
// Parameters are treated as const declarations.
|
||||||
ast_param->set_is_const(true);
|
|
||||||
ast_params.emplace_back(ast_param);
|
ast_params.emplace_back(ast_param);
|
||||||
// The value is accessible by name.
|
// The value is accessible by name.
|
||||||
identifier_values_.insert(param->result_id());
|
identifier_values_.insert(param->result_id());
|
||||||
|
@ -1864,16 +1864,18 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
||||||
if (failed()) {
|
if (failed()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto* var = parser_impl_.MakeVariable(
|
ast::Expression* constructor = nullptr;
|
||||||
inst.result_id(), ast::StorageClass::kFunction, var_store_type);
|
|
||||||
if (inst.NumInOperands() > 1) {
|
if (inst.NumInOperands() > 1) {
|
||||||
// SPIR-V initializers are always constants.
|
// SPIR-V initializers are always constants.
|
||||||
// (OpenCL also allows the ID of an OpVariable, but we don't handle that
|
// (OpenCL also allows the ID of an OpVariable, but we don't handle that
|
||||||
// here.)
|
// here.)
|
||||||
var->set_constructor(
|
constructor =
|
||||||
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
|
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
|
||||||
.expr);
|
.expr;
|
||||||
}
|
}
|
||||||
|
auto* var = parser_impl_.MakeVariable(
|
||||||
|
inst.result_id(), ast::StorageClass::kFunction, var_store_type, false,
|
||||||
|
constructor, ast::VariableDecorationList{});
|
||||||
auto* var_decl_stmt = create<ast::VariableDeclStatement>(var);
|
auto* var_decl_stmt = create<ast::VariableDeclStatement>(var);
|
||||||
AddStatementForInstruction(var_decl_stmt, inst);
|
AddStatementForInstruction(var_decl_stmt, inst);
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
|
@ -2141,10 +2143,14 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
|
||||||
const std::string guard_name = block_info.flow_guard_name;
|
const std::string guard_name = block_info.flow_guard_name;
|
||||||
if (!guard_name.empty()) {
|
if (!guard_name.empty()) {
|
||||||
// Declare the guard variable just before the "if", initialized to true.
|
// Declare the guard variable just before the "if", initialized to true.
|
||||||
auto* guard_var = create<ast::Variable>(Source{}, guard_name,
|
auto* guard_var =
|
||||||
ast::StorageClass::kFunction,
|
create<ast::Variable>(Source{}, // source
|
||||||
parser_impl_.Bool());
|
guard_name, // name
|
||||||
guard_var->set_constructor(MakeTrue());
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
parser_impl_.Bool(), // type
|
||||||
|
false, // is_const
|
||||||
|
MakeTrue(), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* guard_decl = create<ast::VariableDeclStatement>(guard_var);
|
auto* guard_decl = create<ast::VariableDeclStatement>(guard_var);
|
||||||
AddStatement(guard_decl);
|
AddStatement(guard_decl);
|
||||||
}
|
}
|
||||||
|
@ -2674,8 +2680,9 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
assert(def_inst);
|
assert(def_inst);
|
||||||
auto* ast_type =
|
auto* ast_type =
|
||||||
RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
|
RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
|
||||||
AddStatement(create<ast::VariableDeclStatement>(
|
AddStatement(create<ast::VariableDeclStatement>(parser_impl_.MakeVariable(
|
||||||
parser_impl_.MakeVariable(id, ast::StorageClass::kFunction, ast_type)));
|
id, ast::StorageClass::kFunction, ast_type, false, nullptr,
|
||||||
|
ast::VariableDecorationList{})));
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
identifier_values_.insert(id);
|
identifier_values_.insert(id);
|
||||||
}
|
}
|
||||||
|
@ -2686,8 +2693,13 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
const auto phi_var_name = GetDefInfo(id)->phi_var;
|
const auto phi_var_name = GetDefInfo(id)->phi_var;
|
||||||
assert(!phi_var_name.empty());
|
assert(!phi_var_name.empty());
|
||||||
auto* var = create<ast::Variable>(
|
auto* var = create<ast::Variable>(
|
||||||
Source{}, phi_var_name, ast::StorageClass::kFunction,
|
Source{}, // source
|
||||||
parser_impl_.ConvertType(def_inst->type_id()));
|
phi_var_name, // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
parser_impl_.ConvertType(def_inst->type_id()), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
AddStatement(create<ast::VariableDeclStatement>(var));
|
AddStatement(create<ast::VariableDeclStatement>(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2734,12 +2746,11 @@ bool FunctionEmitter::EmitConstDefinition(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto* ast_const = parser_impl_.MakeVariable(
|
auto* ast_const = parser_impl_.MakeVariable(
|
||||||
inst.result_id(), ast::StorageClass::kNone, ast_expr.type);
|
inst.result_id(), ast::StorageClass::kNone, ast_expr.type, true,
|
||||||
|
ast_expr.expr, ast::VariableDecorationList{});
|
||||||
if (!ast_const) {
|
if (!ast_const) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ast_const->set_constructor(ast_expr.expr);
|
|
||||||
ast_const->set_is_const(true);
|
|
||||||
AddStatementForInstruction(create<ast::VariableDeclStatement>(ast_const),
|
AddStatementForInstruction(create<ast::VariableDeclStatement>(ast_const),
|
||||||
inst);
|
inst);
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
|
@ -1064,8 +1063,6 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ast_type && ast_expr) {
|
if (ast_type && ast_expr) {
|
||||||
auto* ast_var =
|
|
||||||
MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type);
|
|
||||||
ast::VariableDecorationList spec_id_decos;
|
ast::VariableDecorationList spec_id_decos;
|
||||||
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
||||||
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
||||||
|
@ -1074,18 +1071,10 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spec_id_decos.empty()) {
|
auto* ast_var =
|
||||||
// Register it as a named constant, without specialization id.
|
MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type,
|
||||||
ast_var->set_is_const(true);
|
true, ast_expr, std::move(spec_id_decos));
|
||||||
ast_var->set_constructor(ast_expr);
|
ast_module_.AddGlobalVariable(ast_var);
|
||||||
ast_module_.AddGlobalVariable(ast_var);
|
|
||||||
} else {
|
|
||||||
auto* ast_deco_var = create<ast::DecoratedVariable>(ast_var);
|
|
||||||
ast_deco_var->set_is_const(true);
|
|
||||||
ast_deco_var->set_constructor(ast_expr);
|
|
||||||
ast_deco_var->set_decorations(std::move(spec_id_decos));
|
|
||||||
ast_module_.AddGlobalVariable(ast_deco_var);
|
|
||||||
}
|
|
||||||
scalar_spec_constants_.insert(inst.result_id());
|
scalar_spec_constants_.insert(inst.result_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,15 +1179,17 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
||||||
auto* ast_store_type = ast_type->As<ast::type::Pointer>()->type();
|
auto* ast_store_type = ast_type->As<ast::type::Pointer>()->type();
|
||||||
auto ast_storage_class =
|
auto ast_storage_class =
|
||||||
ast_type->As<ast::type::Pointer>()->storage_class();
|
ast_type->As<ast::type::Pointer>()->storage_class();
|
||||||
auto* ast_var =
|
ast::Expression* ast_constructor = nullptr;
|
||||||
MakeVariable(var.result_id(), ast_storage_class, ast_store_type);
|
|
||||||
if (var.NumInOperands() > 1) {
|
if (var.NumInOperands() > 1) {
|
||||||
// SPIR-V initializers are always constants.
|
// SPIR-V initializers are always constants.
|
||||||
// (OpenCL also allows the ID of an OpVariable, but we don't handle that
|
// (OpenCL also allows the ID of an OpVariable, but we don't handle that
|
||||||
// here.)
|
// here.)
|
||||||
ast_var->set_constructor(
|
ast_constructor =
|
||||||
MakeConstantExpression(var.GetSingleWordInOperand(1)).expr);
|
MakeConstantExpression(var.GetSingleWordInOperand(1)).expr;
|
||||||
}
|
}
|
||||||
|
auto* ast_var =
|
||||||
|
MakeVariable(var.result_id(), ast_storage_class, ast_store_type, false,
|
||||||
|
ast_constructor, ast::VariableDecorationList{});
|
||||||
// TODO(dneto): initializers (a.k.a. constructor expression)
|
// TODO(dneto): initializers (a.k.a. constructor expression)
|
||||||
ast_module_.AddGlobalVariable(ast_var);
|
ast_module_.AddGlobalVariable(ast_var);
|
||||||
}
|
}
|
||||||
|
@ -1208,23 +1199,26 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
||||||
// Make sure the variable has a name.
|
// Make sure the variable has a name.
|
||||||
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
|
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
|
||||||
"gl_Position");
|
"gl_Position");
|
||||||
auto* var = create<ast::DecoratedVariable>(MakeVariable(
|
auto* var = MakeVariable(
|
||||||
builtin_position_.per_vertex_var_id,
|
builtin_position_.per_vertex_var_id,
|
||||||
enum_converter_.ToStorageClass(builtin_position_.storage_class),
|
enum_converter_.ToStorageClass(builtin_position_.storage_class),
|
||||||
ConvertType(builtin_position_.member_type_id)));
|
ConvertType(builtin_position_.member_type_id), false, nullptr,
|
||||||
ast::VariableDecorationList decos;
|
ast::VariableDecorationList{
|
||||||
decos.push_back(
|
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}),
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
|
});
|
||||||
var->set_decorations(std::move(decos));
|
|
||||||
|
|
||||||
ast_module_.AddGlobalVariable(var);
|
ast_module_.AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
return success_;
|
return success_;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
ast::Variable* ParserImpl::MakeVariable(
|
||||||
ast::StorageClass sc,
|
uint32_t id,
|
||||||
ast::type::Type* type) {
|
ast::StorageClass sc,
|
||||||
|
ast::type::Type* type,
|
||||||
|
bool is_const,
|
||||||
|
ast::Expression* constructor,
|
||||||
|
ast::VariableDecorationList decorations) {
|
||||||
if (type == nullptr) {
|
if (type == nullptr) {
|
||||||
Fail() << "internal error: can't make ast::Variable for null type";
|
Fail() << "internal error: can't make ast::Variable for null type";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1238,9 +1232,6 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
||||||
type = ast_module_.create<ast::type::AccessControl>(access, type);
|
type = ast_module_.create<ast::type::AccessControl>(access, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* ast_var = create<ast::Variable>(Source{}, namer_.Name(id), sc, type);
|
|
||||||
|
|
||||||
ast::VariableDecorationList ast_decorations;
|
|
||||||
for (auto& deco : GetDecorationsFor(id)) {
|
for (auto& deco : GetDecorationsFor(id)) {
|
||||||
if (deco.empty()) {
|
if (deco.empty()) {
|
||||||
Fail() << "malformed decoration on ID " << id << ": it is empty";
|
Fail() << "malformed decoration on ID " << id << ": it is empty";
|
||||||
|
@ -1257,7 +1248,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
||||||
if (ast_builtin == ast::Builtin::kNone) {
|
if (ast_builtin == ast::Builtin::kNone) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
decorations.emplace_back(
|
||||||
create<ast::BuiltinDecoration>(ast_builtin, Source{}));
|
create<ast::BuiltinDecoration>(ast_builtin, Source{}));
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationLocation) {
|
if (deco[0] == SpvDecorationLocation) {
|
||||||
|
@ -1266,7 +1257,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
||||||
<< ": requires one literal operand";
|
<< ": requires one literal operand";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
decorations.emplace_back(
|
||||||
create<ast::LocationDecoration>(deco[1], Source{}));
|
create<ast::LocationDecoration>(deco[1], Source{}));
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationDescriptorSet) {
|
if (deco[0] == SpvDecorationDescriptorSet) {
|
||||||
|
@ -1275,8 +1266,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
||||||
<< ": has no operand";
|
<< ": has no operand";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
decorations.emplace_back(create<ast::SetDecoration>(deco[1], Source{}));
|
||||||
create<ast::SetDecoration>(deco[1], Source{}));
|
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationBinding) {
|
if (deco[0] == SpvDecorationBinding) {
|
||||||
if (deco.size() == 1) {
|
if (deco.size() == 1) {
|
||||||
|
@ -1284,16 +1274,18 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
||||||
<< ": has no operand";
|
<< ": has no operand";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
decorations.emplace_back(
|
||||||
create<ast::BindingDecoration>(deco[1], Source{}));
|
create<ast::BindingDecoration>(deco[1], Source{}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ast_decorations.empty()) {
|
|
||||||
auto* decorated_var = create<ast::DecoratedVariable>(ast_var);
|
return create<ast::Variable>(Source{}, // source
|
||||||
decorated_var->set_decorations(std::move(ast_decorations));
|
namer_.Name(id), // name
|
||||||
ast_var = std::move(decorated_var);
|
sc, // storage_class
|
||||||
}
|
type, // type
|
||||||
return ast_var;
|
is_const, // is_const
|
||||||
|
constructor, // constructor
|
||||||
|
decorations); // decorations
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
|
TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
|
||||||
|
|
|
@ -291,10 +291,16 @@ class ParserImpl : Reader {
|
||||||
/// @param id the SPIR-V result ID
|
/// @param id the SPIR-V result ID
|
||||||
/// @param sc the storage class, which cannot be ast::StorageClass::kNone
|
/// @param sc the storage class, which cannot be ast::StorageClass::kNone
|
||||||
/// @param type the type
|
/// @param type the type
|
||||||
|
/// @param is_const if true, the variable is const
|
||||||
|
/// @param constructor the variable constructor
|
||||||
|
/// @param decorations the variable decorations
|
||||||
/// @returns a new Variable node, or null in the error case
|
/// @returns a new Variable node, or null in the error case
|
||||||
ast::Variable* MakeVariable(uint32_t id,
|
ast::Variable* MakeVariable(uint32_t id,
|
||||||
ast::StorageClass sc,
|
ast::StorageClass sc,
|
||||||
ast::type::Type* type);
|
ast::type::Type* type,
|
||||||
|
bool is_const,
|
||||||
|
ast::Expression* constructor,
|
||||||
|
ast::VariableDecorationList decorations);
|
||||||
|
|
||||||
/// Creates an AST expression node for a SPIR-V constant.
|
/// Creates an AST expression node for a SPIR-V constant.
|
||||||
/// @param id the SPIR-V ID of the constant
|
/// @param id the SPIR-V ID of the constant
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ INSTANTIATE_TEST_SUITE_P(Samplers,
|
||||||
%10 = OpVariable %ptr UniformConstant
|
%10 = OpVariable %ptr UniformConstant
|
||||||
)",
|
)",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1159,7 +1159,7 @@ INSTANTIATE_TEST_SUITE_P(Images,
|
||||||
%10 = OpVariable %ptr_f_texture_1d UniformConstant
|
%10 = OpVariable %ptr_f_texture_1d UniformConstant
|
||||||
)",
|
)",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1175,7 +1175,7 @@ INSTANTIATE_TEST_SUITE_P(Images,
|
||||||
%10 = OpVariable %ptr_f_storage_1d UniformConstant
|
%10 = OpVariable %ptr_f_storage_1d UniformConstant
|
||||||
)",
|
)",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1191,7 +1191,7 @@ INSTANTIATE_TEST_SUITE_P(Images,
|
||||||
%10 = OpVariable %ptr_f_storage_1d UniformConstant
|
%10 = OpVariable %ptr_f_storage_1d UniformConstant
|
||||||
)",
|
)",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1343,7 +1343,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
"%v4float %sampled_image %coords12",
|
"%v4float %sampled_image %coords12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1352,7 +1352,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1376,7 +1376,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
"%v4float %sampled_image %coords123",
|
"%v4float %sampled_image %coords123",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1385,7 +1385,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1420,7 +1420,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
"%v4float %sampled_image %coords12 ConstOffset %offsets2d",
|
"%v4float %sampled_image %coords12 ConstOffset %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1429,7 +1429,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1455,7 +1455,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
"%v4float %sampled_image %coords123 ConstOffset %offsets2d",
|
"%v4float %sampled_image %coords123 ConstOffset %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1464,7 +1464,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1499,7 +1499,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
"%v4float %sampled_image %coords12 Bias %float_7",
|
"%v4float %sampled_image %coords12 Bias %float_7",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1508,7 +1508,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1533,7 +1533,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
"%v4float %sampled_image %coords123 Bias %float_7",
|
"%v4float %sampled_image %coords123 Bias %float_7",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1542,7 +1542,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1580,7 +1580,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%v4float %sampled_image %coords12 Bias|ConstOffset "
|
"%v4float %sampled_image %coords12 Bias|ConstOffset "
|
||||||
"%float_7 %offsets2d",
|
"%float_7 %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1589,7 +1589,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1615,7 +1615,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%v4float %sampled_image %coords123 Bias|ConstOffset "
|
"%v4float %sampled_image %coords123 Bias|ConstOffset "
|
||||||
"%float_7 %offsets2d",
|
"%float_7 %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1624,7 +1624,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1672,7 +1672,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
%210 = OpImageSampleDrefImplicitLod %v4float %sampled_dref_image %coords12 %depth
|
%210 = OpImageSampleDrefImplicitLod %v4float %sampled_dref_image %coords12 %depth
|
||||||
)",
|
)",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1681,7 +1681,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1690,7 +1690,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__depth_texture_2d
|
__depth_texture_2d
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1745,7 +1745,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleDrefImplicitLod "
|
"%result = OpImageSampleDrefImplicitLod "
|
||||||
"%v4float %sampled_image %coords12 %depth",
|
"%v4float %sampled_image %coords12 %depth",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1754,7 +1754,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_comparison
|
__sampler_comparison
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1778,7 +1778,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleDrefImplicitLod "
|
"%result = OpImageSampleDrefImplicitLod "
|
||||||
"%v4float %sampled_image %coords123 %depth",
|
"%v4float %sampled_image %coords123 %depth",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1787,7 +1787,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_comparison
|
__sampler_comparison
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1822,7 +1822,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleDrefImplicitLod %v4float "
|
"%result = OpImageSampleDrefImplicitLod %v4float "
|
||||||
"%sampled_image %coords12 %depth ConstOffset %offsets2d",
|
"%sampled_image %coords12 %depth ConstOffset %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1831,7 +1831,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_comparison
|
__sampler_comparison
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1857,7 +1857,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleDrefImplicitLod %v4float "
|
"%result = OpImageSampleDrefImplicitLod %v4float "
|
||||||
"%sampled_image %coords123 %depth ConstOffset %offsets2d",
|
"%sampled_image %coords123 %depth ConstOffset %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1866,7 +1866,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_comparison
|
__sampler_comparison
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1907,7 +1907,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleExplicitLod "
|
"%result = OpImageSampleExplicitLod "
|
||||||
"%v4float %sampled_image %coords12 Lod %float_null",
|
"%v4float %sampled_image %coords12 Lod %float_null",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1916,7 +1916,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1941,7 +1941,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleExplicitLod "
|
"%result = OpImageSampleExplicitLod "
|
||||||
"%v4float %sampled_image %coords123 Lod %float_null",
|
"%v4float %sampled_image %coords123 Lod %float_null",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1950,7 +1950,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -1988,7 +1988,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%v4float %sampled_image %coords12 Lod|ConstOffset "
|
"%v4float %sampled_image %coords12 Lod|ConstOffset "
|
||||||
"%float_null %offsets2d",
|
"%float_null %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -1997,7 +1997,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2024,7 +2024,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%v4float %sampled_image %coords123 Lod|ConstOffset "
|
"%v4float %sampled_image %coords123 Lod|ConstOffset "
|
||||||
"%float_null %offsets2d",
|
"%float_null %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2033,7 +2033,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2070,7 +2070,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleExplicitLod "
|
"%result = OpImageSampleExplicitLod "
|
||||||
"%v4float %sampled_image %coords12 Grad %float_7 %float_null",
|
"%v4float %sampled_image %coords12 Grad %float_7 %float_null",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2079,7 +2079,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2106,7 +2106,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleExplicitLod "
|
"%result = OpImageSampleExplicitLod "
|
||||||
"%v4float %sampled_image %coords123 Grad %float_7 %float_null",
|
"%v4float %sampled_image %coords123 Grad %float_7 %float_null",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2115,7 +2115,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2154,7 +2154,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%v4float %sampled_image %coords12 Grad|ConstOffset "
|
"%v4float %sampled_image %coords12 Grad|ConstOffset "
|
||||||
"%float_7 %float_null %offsets2d",
|
"%float_7 %float_null %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2163,7 +2163,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2192,7 +2192,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%v4float %sampled_image %coords123 Grad|ConstOffset "
|
"%v4float %sampled_image %coords123 Grad|ConstOffset "
|
||||||
"%float_7 %float_null %offsets2d",
|
"%float_7 %float_null %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2201,7 +2201,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2248,7 +2248,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleExplicitLod %v4float "
|
"%result = OpImageSampleExplicitLod %v4float "
|
||||||
"%sampled_image %vf12 Lod %f1",
|
"%sampled_image %vf12 Lod %f1",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2257,7 +2257,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2281,7 +2281,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleExplicitLod %v4float "
|
"%result = OpImageSampleExplicitLod %v4float "
|
||||||
"%sampled_image %vf12 Lod %f1",
|
"%sampled_image %vf12 Lod %f1",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -2290,7 +2290,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2387,7 +2387,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// OpImageWrite with no extra params
|
// OpImageWrite with no extra params
|
||||||
{"%float 2D 0 0 0 2 Rgba32f", "OpImageWrite %im %vu12 %vf1234",
|
{"%float 2D 0 0 0 2 Rgba32f", "OpImageWrite %im %vu12 %vf1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2408,7 +2408,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%float 2D 0 0 0 2 Rgba32f",
|
{"%float 2D 0 0 0 2 Rgba32f",
|
||||||
"OpImageWrite %im %vu12 %vf1234 ConstOffset %offsets2d",
|
"OpImageWrite %im %vu12 %vf1234 ConstOffset %offsets2d",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2437,7 +2437,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 1 component, dest 1 component
|
// Source 1 component, dest 1 component
|
||||||
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %f1",
|
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %f1",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2457,7 +2457,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 2 component, dest 1 component
|
// Source 2 component, dest 1 component
|
||||||
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf12",
|
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2480,7 +2480,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 3 component, dest 1 component
|
// Source 3 component, dest 1 component
|
||||||
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf123",
|
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf123",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2503,7 +2503,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 4 component, dest 1 component
|
// Source 4 component, dest 1 component
|
||||||
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf1234",
|
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2526,7 +2526,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 2 component, dest 2 component
|
// Source 2 component, dest 2 component
|
||||||
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf12",
|
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2546,7 +2546,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 3 component, dest 2 component
|
// Source 3 component, dest 2 component
|
||||||
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf123",
|
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf123",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2569,7 +2569,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 4 component, dest 2 component
|
// Source 4 component, dest 2 component
|
||||||
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf1234",
|
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2593,7 +2593,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Source 4 component, dest 4 component
|
// Source 4 component, dest 4 component
|
||||||
{"%float 2D 0 0 0 2 Rgba32f", "OpImageWrite %im %vu12 %vf1234",
|
{"%float 2D 0 0 0 2 Rgba32f", "OpImageWrite %im %vu12 %vf1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2759,7 +2759,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Sampled type is unsigned int, texel is unsigned int
|
// Sampled type is unsigned int, texel is unsigned int
|
||||||
{"%uint 2D 0 0 0 2 Rgba32ui", "OpImageWrite %im %vu12 %vu1234",
|
{"%uint 2D 0 0 0 2 Rgba32ui", "OpImageWrite %im %vu12 %vu1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2779,7 +2779,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Sampled type is unsigned int, texel is signed int
|
// Sampled type is unsigned int, texel is signed int
|
||||||
{"%uint 2D 0 0 0 2 Rgba32ui", "OpImageWrite %im %vu12 %vi1234",
|
{"%uint 2D 0 0 0 2 Rgba32ui", "OpImageWrite %im %vu12 %vi1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2801,7 +2801,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Sampled type is signed int, texel is unsigned int
|
// Sampled type is signed int, texel is unsigned int
|
||||||
{"%int 2D 0 0 0 2 Rgba32i", "OpImageWrite %im %vu12 %vu1234",
|
{"%int 2D 0 0 0 2 Rgba32i", "OpImageWrite %im %vu12 %vu1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2823,7 +2823,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// Sampled type is signed int, texel is signed int
|
// Sampled type is signed int, texel is signed int
|
||||||
{"%int 2D 0 0 0 2 Rgba32i", "OpImageWrite %im %vu12 %vi1234",
|
{"%int 2D 0 0 0 2 Rgba32i", "OpImageWrite %im %vu12 %vi1234",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2847,7 +2847,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
||||||
// OpImageRead with no extra params
|
// OpImageRead with no extra params
|
||||||
{"%float 2D 0 0 0 2 Rgba32f", "%99 = OpImageRead %v4float %im %vu12",
|
{"%float 2D 0 0 0 2 Rgba32f", "%99 = OpImageRead %v4float %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2875,7 +2875,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// OpImageRead with ConstOffset
|
// OpImageRead with ConstOffset
|
||||||
{"%float 2D 0 0 0 2 Rgba32f",
|
{"%float 2D 0 0 0 2 Rgba32f",
|
||||||
"%99 = OpImageRead %v4float %im %vu12 ConstOffset %offsets2d",
|
"%99 = OpImageRead %v4float %im %vu12 ConstOffset %offsets2d",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2908,7 +2908,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
||||||
// OpImageFetch with no extra params
|
// OpImageFetch with no extra params
|
||||||
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vu12",
|
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2936,7 +2936,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// OpImageFetch with ConstOffset
|
// OpImageFetch with ConstOffset
|
||||||
{"%float 2D 0 0 0 1 Unknown",
|
{"%float 2D 0 0 0 1 Unknown",
|
||||||
"%99 = OpImageFetch %v4float %im %vu12 ConstOffset %offsets2d",
|
"%99 = OpImageFetch %v4float %im %vu12 ConstOffset %offsets2d",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -2983,7 +2983,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
|
|
||||||
// OpImageFetch requires no conversion, float -> v4float
|
// OpImageFetch requires no conversion, float -> v4float
|
||||||
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vu12",
|
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3010,7 +3010,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageFetch requires no conversion, uint -> v4uint
|
// OpImageFetch requires no conversion, uint -> v4uint
|
||||||
{"%uint 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4uint %im %vu12",
|
{"%uint 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4uint %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3037,7 +3037,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageFetch requires conversion, uint -> v4int
|
// OpImageFetch requires conversion, uint -> v4int
|
||||||
{"%uint 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4int %im %vu12",
|
{"%uint 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4int %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3066,7 +3066,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageFetch requires no conversion, int -> v4int
|
// OpImageFetch requires no conversion, int -> v4int
|
||||||
{"%int 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4int %im %vu12",
|
{"%int 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4int %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3093,7 +3093,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageFetch requires conversion, int -> v4uint
|
// OpImageFetch requires conversion, int -> v4uint
|
||||||
{"%int 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4uint %im %vu12",
|
{"%int 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4uint %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3127,7 +3127,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
|
|
||||||
// OpImageRead requires no conversion, float -> v4float
|
// OpImageRead requires no conversion, float -> v4float
|
||||||
{"%float 2D 0 0 0 1 Rgba32f", "%99 = OpImageRead %v4float %im %vu12",
|
{"%float 2D 0 0 0 1 Rgba32f", "%99 = OpImageRead %v4float %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3154,7 +3154,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageRead requires no conversion, uint -> v4uint
|
// OpImageRead requires no conversion, uint -> v4uint
|
||||||
{"%uint 2D 0 0 0 1 Rgba32ui", "%99 = OpImageRead %v4uint %im %vu12",
|
{"%uint 2D 0 0 0 1 Rgba32ui", "%99 = OpImageRead %v4uint %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3181,7 +3181,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageRead requires conversion, uint -> v4int
|
// OpImageRead requires conversion, uint -> v4int
|
||||||
{"%uint 2D 0 0 0 1 Rgba32ui", "%99 = OpImageRead %v4int %im %vu12",
|
{"%uint 2D 0 0 0 1 Rgba32ui", "%99 = OpImageRead %v4int %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3210,7 +3210,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageRead requires no conversion, int -> v4int
|
// OpImageRead requires no conversion, int -> v4int
|
||||||
{"%int 2D 0 0 0 1 Rgba32i", "%99 = OpImageRead %v4int %im %vu12",
|
{"%int 2D 0 0 0 1 Rgba32i", "%99 = OpImageRead %v4int %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3237,7 +3237,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
})"},
|
})"},
|
||||||
// OpImageRead requires conversion, int -> v4uint
|
// OpImageRead requires conversion, int -> v4uint
|
||||||
{"%int 2D 0 0 0 1 Rgba32i", "%99 = OpImageRead %v4uint %im %vu12",
|
{"%int 2D 0 0 0 1 Rgba32i", "%99 = OpImageRead %v4uint %im %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3273,7 +3273,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%float 2D 0 0 0 1 Unknown",
|
{"%float 2D 0 0 0 1 Unknown",
|
||||||
"%99 = OpImageSampleImplicitLod %v4float %sampled_image %vu12",
|
"%99 = OpImageSampleImplicitLod %v4float %sampled_image %vu12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -3282,7 +3282,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3312,7 +3312,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%uint 2D 0 0 0 1 Unknown",
|
{"%uint 2D 0 0 0 1 Unknown",
|
||||||
"%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vu12",
|
"%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vu12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -3321,7 +3321,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3351,7 +3351,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%uint 2D 0 0 0 1 Unknown",
|
{"%uint 2D 0 0 0 1 Unknown",
|
||||||
"%99 = OpImageSampleImplicitLod %v4int %sampled_image %vu12",
|
"%99 = OpImageSampleImplicitLod %v4int %sampled_image %vu12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -3360,7 +3360,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3392,7 +3392,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%int 2D 0 0 0 1 Unknown",
|
{"%int 2D 0 0 0 1 Unknown",
|
||||||
"%99 = OpImageSampleImplicitLod %v4int %sampled_image %vu12",
|
"%99 = OpImageSampleImplicitLod %v4int %sampled_image %vu12",
|
||||||
R"(
|
R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{0}
|
SetDecoration{0}
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -3401,7 +3401,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
uniform_constant
|
uniform_constant
|
||||||
__sampler_sampler
|
__sampler_sampler
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
@ -3430,7 +3430,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// OpImageSampleImplicitLod requires conversion, int -> v4uint
|
// OpImageSampleImplicitLod requires conversion, int -> v4uint
|
||||||
{"%int 2D 0 0 0 1 Unknown",
|
{"%int 2D 0 0 0 1 Unknown",
|
||||||
"%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vu12",
|
"%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vu12",
|
||||||
R"(DecoratedVariable{
|
R"(Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
|
|
|
@ -199,7 +199,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BuiltinVertexIndex) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BuiltinPosition_MapsToModuleScopeVec4Var) {
|
||||||
EXPECT_EQ(position_info.per_vertex_var_id, 1u);
|
EXPECT_EQ(position_info.per_vertex_var_id, 1u);
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{position}
|
BuiltinDecoration{position}
|
||||||
}
|
}
|
||||||
|
@ -1146,7 +1146,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_LocationDecoration_Valid) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
LocationDecoration{3}
|
LocationDecoration{3}
|
||||||
}
|
}
|
||||||
|
@ -1198,7 +1198,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_DescriptorSetDecoration_Valid) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
SetDecoration{3}
|
SetDecoration{3}
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1252,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BindingDecoration_Valid) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{3}
|
BindingDecoration{3}
|
||||||
}
|
}
|
||||||
|
@ -1501,7 +1501,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_True) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariableConst{
|
VariableConst{
|
||||||
Decorations{
|
Decorations{
|
||||||
ConstantIdDecoration{12}
|
ConstantIdDecoration{12}
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1526,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_False) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariableConst{
|
VariableConst{
|
||||||
Decorations{
|
Decorations{
|
||||||
ConstantIdDecoration{12}
|
ConstantIdDecoration{12}
|
||||||
}
|
}
|
||||||
|
@ -1551,7 +1551,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_U32) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariableConst{
|
VariableConst{
|
||||||
Decorations{
|
Decorations{
|
||||||
ConstantIdDecoration{12}
|
ConstantIdDecoration{12}
|
||||||
}
|
}
|
||||||
|
@ -1576,7 +1576,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_I32) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariableConst{
|
VariableConst{
|
||||||
Decorations{
|
Decorations{
|
||||||
ConstantIdDecoration{12}
|
ConstantIdDecoration{12}
|
||||||
}
|
}
|
||||||
|
@ -1601,7 +1601,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_F32) {
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
const auto module_str = p->module().to_str();
|
const auto module_str = p->module().to_str();
|
||||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||||
DecoratedVariableConst{
|
VariableConst{
|
||||||
Decorations{
|
Decorations{
|
||||||
ConstantIdDecoration{12}
|
ConstantIdDecoration{12}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
|
@ -67,6 +66,7 @@
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
#include "src/ast/unary_op.h"
|
#include "src/ast/unary_op.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_decoration.h"
|
||||||
#include "src/reader/wgsl/lexer.h"
|
#include "src/reader/wgsl/lexer.h"
|
||||||
|
@ -419,25 +419,25 @@ Maybe<ast::Variable*> ParserImpl::global_variable_decl(
|
||||||
if (!decl.matched)
|
if (!decl.matched)
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
|
|
||||||
auto* var = decl.value;
|
|
||||||
|
|
||||||
auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
|
auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
|
||||||
if (var_decos.errored)
|
if (var_decos.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
if (var_decos.value.size() > 0) {
|
ast::Expression* constructor = nullptr;
|
||||||
auto* dv = create<ast::DecoratedVariable>(var);
|
|
||||||
dv->set_decorations(var_decos.value);
|
|
||||||
var = dv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match(Token::Type::kEqual)) {
|
if (match(Token::Type::kEqual)) {
|
||||||
auto expr = expect_const_expr();
|
auto expr = expect_const_expr();
|
||||||
if (expr.errored)
|
if (expr.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
var->set_constructor(expr.value);
|
constructor = expr.value;
|
||||||
}
|
}
|
||||||
return var;
|
|
||||||
|
return create<ast::Variable>(decl->source, // source
|
||||||
|
decl->name, // name
|
||||||
|
decl->storage_class, // storage_class
|
||||||
|
decl->type, // type
|
||||||
|
false, // is_const
|
||||||
|
constructor, // constructor
|
||||||
|
std::move(var_decos.value)); // decorations
|
||||||
}
|
}
|
||||||
|
|
||||||
// global_constant_decl
|
// global_constant_decl
|
||||||
|
@ -452,10 +452,6 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
|
||||||
if (decl.errored)
|
if (decl.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(decl->source, decl->name,
|
|
||||||
ast::StorageClass::kNone, decl->type);
|
|
||||||
var->set_is_const(true);
|
|
||||||
|
|
||||||
if (!expect(use, Token::Type::kEqual))
|
if (!expect(use, Token::Type::kEqual))
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
|
@ -463,14 +459,18 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
|
||||||
if (init.errored)
|
if (init.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
var->set_constructor(init.value);
|
return create<ast::Variable>(decl->source, // source
|
||||||
|
decl->name, // name
|
||||||
return var;
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
decl->type, // type
|
||||||
|
true, // is_const
|
||||||
|
init.value, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
}
|
}
|
||||||
|
|
||||||
// variable_decl
|
// variable_decl
|
||||||
// : VAR variable_storage_decoration? variable_ident_decl
|
// : VAR variable_storage_decoration? variable_ident_decl
|
||||||
Maybe<ast::Variable*> ParserImpl::variable_decl() {
|
Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
|
||||||
if (!match(Token::Type::kVar))
|
if (!match(Token::Type::kVar))
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
|
|
||||||
|
@ -482,9 +482,9 @@ Maybe<ast::Variable*> ParserImpl::variable_decl() {
|
||||||
if (decl.errored)
|
if (decl.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::Variable>(decl->source, decl->name,
|
return VarDeclInfo{decl->source, decl->name,
|
||||||
sc.matched ? sc.value : ast::StorageClass::kNone,
|
sc.matched ? sc.value : ast::StorageClass::kNone,
|
||||||
decl->type);
|
decl->type};
|
||||||
}
|
}
|
||||||
|
|
||||||
// texture_sampler_types
|
// texture_sampler_types
|
||||||
|
@ -1349,13 +1349,18 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
|
||||||
|
|
||||||
ast::VariableList ret;
|
ast::VariableList ret;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto* var = create<ast::Variable>(decl->source, decl->name,
|
auto* var =
|
||||||
ast::StorageClass::kNone, decl->type);
|
create<ast::Variable>(decl->source, // source
|
||||||
|
decl->name, // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
decl->type, // type
|
||||||
|
true, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
// Formal parameters are treated like a const declaration where the
|
// Formal parameters are treated like a const declaration where the
|
||||||
// initializer value is provided by the call's argument. The key point is
|
// initializer value is provided by the call's argument. The key point is
|
||||||
// that it's not updatable after intially set. This is unlike C or GLSL
|
// that it's not updatable after intially set. This is unlike C or GLSL
|
||||||
// which treat formal parameters like local variables that can be updated.
|
// which treat formal parameters like local variables that can be updated.
|
||||||
var->set_is_const(true);
|
|
||||||
ret.push_back(var);
|
ret.push_back(var);
|
||||||
|
|
||||||
if (!match(Token::Type::kComma))
|
if (!match(Token::Type::kComma))
|
||||||
|
@ -1610,31 +1615,45 @@ Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
|
||||||
if (!constructor.matched)
|
if (!constructor.matched)
|
||||||
return add_error(peek(), "missing constructor for const declaration");
|
return add_error(peek(), "missing constructor for const declaration");
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(decl->source, decl->name,
|
auto* var =
|
||||||
ast::StorageClass::kNone, decl->type);
|
create<ast::Variable>(decl->source, // source
|
||||||
var->set_is_const(true);
|
decl->name, // name
|
||||||
var->set_constructor(constructor.value);
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
decl->type, // type
|
||||||
|
true, // is_const
|
||||||
|
constructor.value, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
return create<ast::VariableDeclStatement>(decl->source, var);
|
return create<ast::VariableDeclStatement>(decl->source, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto var = variable_decl();
|
auto decl = variable_decl();
|
||||||
if (var.errored)
|
if (decl.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (!var.matched)
|
if (!decl.matched)
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
|
|
||||||
|
ast::Expression* constructor = nullptr;
|
||||||
if (match(Token::Type::kEqual)) {
|
if (match(Token::Type::kEqual)) {
|
||||||
auto constructor = logical_or_expression();
|
auto constructor_expr = logical_or_expression();
|
||||||
if (constructor.errored)
|
if (constructor_expr.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (!constructor.matched)
|
if (!constructor_expr.matched)
|
||||||
return add_error(peek(), "missing constructor for variable declaration");
|
return add_error(peek(), "missing constructor for variable declaration");
|
||||||
|
|
||||||
var->set_constructor(constructor.value);
|
constructor = constructor_expr.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<ast::VariableDeclStatement>(var->source(), var.value);
|
auto* var =
|
||||||
|
create<ast::Variable>(decl->source, // source
|
||||||
|
decl->name, // name
|
||||||
|
decl->storage_class, // storage_class
|
||||||
|
decl->type, // type
|
||||||
|
false, // is_const
|
||||||
|
constructor, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
|
return create<ast::VariableDeclStatement>(var->source(), var);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if_stmt
|
// if_stmt
|
||||||
|
|
|
@ -262,6 +262,18 @@ class ParserImpl {
|
||||||
ast::type::Type* return_type;
|
ast::type::Type* return_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// VarDeclInfo contains the parsed information for variable declaration.
|
||||||
|
struct VarDeclInfo {
|
||||||
|
/// Variable declaration source
|
||||||
|
Source source;
|
||||||
|
/// Variable name
|
||||||
|
std::string name;
|
||||||
|
/// Variable storage class
|
||||||
|
ast::StorageClass storage_class;
|
||||||
|
/// Variable type
|
||||||
|
ast::type::Type* type;
|
||||||
|
};
|
||||||
|
|
||||||
/// Creates a new parser using the given file
|
/// Creates a new parser using the given file
|
||||||
/// @param file the input source file to parse
|
/// @param file the input source file to parse
|
||||||
explicit ParserImpl(Source::File const* file);
|
explicit ParserImpl(Source::File const* file);
|
||||||
|
@ -356,8 +368,8 @@ class ParserImpl {
|
||||||
/// @returns the const object or nullptr
|
/// @returns the const object or nullptr
|
||||||
Maybe<ast::Variable*> global_constant_decl();
|
Maybe<ast::Variable*> global_constant_decl();
|
||||||
/// Parses a `variable_decl` grammar element
|
/// Parses a `variable_decl` grammar element
|
||||||
/// @returns the parsed variable or nullptr otherwise
|
/// @returns the parsed variable declaration info
|
||||||
Maybe<ast::Variable*> variable_decl();
|
Maybe<VarDeclInfo> variable_decl();
|
||||||
/// Parses a `variable_ident_decl` grammar element, erroring on parse
|
/// Parses a `variable_ident_decl` grammar element, erroring on parse
|
||||||
/// failure.
|
/// failure.
|
||||||
/// @param use a description of what was being parsed if an error was raised.
|
/// @param use a description of what was being parsed if an error was raised.
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decoration.h"
|
#include "src/ast/variable_decoration.h"
|
||||||
#include "src/reader/wgsl/parser_impl.h"
|
#include "src/reader/wgsl/parser_impl.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decoration.h"
|
#include "src/ast/variable_decoration.h"
|
||||||
#include "src/reader/wgsl/parser_impl.h"
|
#include "src/reader/wgsl/parser_impl.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
@ -46,7 +46,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
|
||||||
EXPECT_EQ(e->source().range.end.column, 11u);
|
EXPECT_EQ(e->source().range.end.column, 11u);
|
||||||
|
|
||||||
ASSERT_EQ(e->constructor(), nullptr);
|
ASSERT_EQ(e->constructor(), nullptr);
|
||||||
ASSERT_FALSE(e->Is<ast::DecoratedVariable>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
||||||
|
@ -72,8 +71,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
||||||
ASSERT_NE(e->constructor(), nullptr);
|
ASSERT_NE(e->constructor(), nullptr);
|
||||||
ASSERT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
|
ASSERT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
|
||||||
ASSERT_TRUE(e->constructor()->Is<ast::ScalarConstructorExpression>());
|
ASSERT_TRUE(e->constructor()->Is<ast::ScalarConstructorExpression>());
|
||||||
|
|
||||||
ASSERT_FALSE(e->Is<ast::DecoratedVariable>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
||||||
|
@ -86,7 +83,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
|
|
||||||
|
|
||||||
EXPECT_EQ(e->name(), "a");
|
EXPECT_EQ(e->name(), "a");
|
||||||
ASSERT_NE(e->type(), nullptr);
|
ASSERT_NE(e->type(), nullptr);
|
||||||
|
@ -100,10 +96,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
||||||
|
|
||||||
ASSERT_EQ(e->constructor(), nullptr);
|
ASSERT_EQ(e->constructor(), nullptr);
|
||||||
|
|
||||||
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
|
auto& decorations = e->decorations();
|
||||||
auto* v = e->As<ast::DecoratedVariable>();
|
|
||||||
|
|
||||||
auto& decorations = v->decorations();
|
|
||||||
ASSERT_EQ(decorations.size(), 2u);
|
ASSERT_EQ(decorations.size(), 2u);
|
||||||
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
||||||
ASSERT_TRUE(decorations[1]->Is<ast::SetDecoration>());
|
ASSERT_TRUE(decorations[1]->Is<ast::SetDecoration>());
|
||||||
|
@ -120,7 +113,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
|
|
||||||
|
|
||||||
EXPECT_EQ(e->name(), "a");
|
EXPECT_EQ(e->name(), "a");
|
||||||
ASSERT_NE(e->type(), nullptr);
|
ASSERT_NE(e->type(), nullptr);
|
||||||
|
@ -134,10 +126,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
|
||||||
|
|
||||||
ASSERT_EQ(e->constructor(), nullptr);
|
ASSERT_EQ(e->constructor(), nullptr);
|
||||||
|
|
||||||
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
|
auto& decorations = e->decorations();
|
||||||
auto* v = e->As<ast::DecoratedVariable>();
|
|
||||||
|
|
||||||
auto& decorations = v->decorations();
|
|
||||||
ASSERT_EQ(decorations.size(), 2u);
|
ASSERT_EQ(decorations.size(), 2u);
|
||||||
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
||||||
ASSERT_TRUE(decorations[1]->Is<ast::SetDecoration>());
|
ASSERT_TRUE(decorations[1]->Is<ast::SetDecoration>());
|
||||||
|
|
|
@ -25,25 +25,23 @@ namespace {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecl_Parses) {
|
TEST_F(ParserImplTest, VariableDecl_Parses) {
|
||||||
auto p = parser("var my_var : f32");
|
auto p = parser("var my_var : f32");
|
||||||
auto var = p->variable_decl();
|
auto v = p->variable_decl();
|
||||||
EXPECT_FALSE(p->has_error());
|
EXPECT_FALSE(p->has_error());
|
||||||
EXPECT_TRUE(var.matched);
|
EXPECT_TRUE(v.matched);
|
||||||
EXPECT_FALSE(var.errored);
|
EXPECT_FALSE(v.errored);
|
||||||
ASSERT_NE(var.value, nullptr);
|
EXPECT_EQ(v->name, "my_var");
|
||||||
EXPECT_EQ(var->name(), "my_var");
|
EXPECT_NE(v->type, nullptr);
|
||||||
EXPECT_NE(var->type(), nullptr);
|
EXPECT_TRUE(v->type->Is<ast::type::F32>());
|
||||||
EXPECT_TRUE(var->type()->Is<ast::type::F32>());
|
|
||||||
|
|
||||||
EXPECT_EQ(var->source().range.begin.line, 1u);
|
EXPECT_EQ(v->source.range.begin.line, 1u);
|
||||||
EXPECT_EQ(var->source().range.begin.column, 5u);
|
EXPECT_EQ(v->source.range.begin.column, 5u);
|
||||||
EXPECT_EQ(var->source().range.end.line, 1u);
|
EXPECT_EQ(v->source.range.end.line, 1u);
|
||||||
EXPECT_EQ(var->source().range.end.column, 11u);
|
EXPECT_EQ(v->source.range.end.column, 11u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecl_MissingVar) {
|
TEST_F(ParserImplTest, VariableDecl_MissingVar) {
|
||||||
auto p = parser("my_var : f32");
|
auto p = parser("my_var : f32");
|
||||||
auto v = p->variable_decl();
|
auto v = p->variable_decl();
|
||||||
EXPECT_EQ(v.value, nullptr);
|
|
||||||
EXPECT_FALSE(v.matched);
|
EXPECT_FALSE(v.matched);
|
||||||
EXPECT_FALSE(v.errored);
|
EXPECT_FALSE(v.errored);
|
||||||
EXPECT_FALSE(p->has_error());
|
EXPECT_FALSE(p->has_error());
|
||||||
|
@ -58,7 +56,6 @@ TEST_F(ParserImplTest, VariableDecl_InvalidIdentDecl) {
|
||||||
EXPECT_FALSE(v.matched);
|
EXPECT_FALSE(v.matched);
|
||||||
EXPECT_TRUE(v.errored);
|
EXPECT_TRUE(v.errored);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(v.value, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:12: expected ':' for variable declaration");
|
EXPECT_EQ(p->error(), "1:12: expected ':' for variable declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,15 +65,14 @@ TEST_F(ParserImplTest, VariableDecl_WithStorageClass) {
|
||||||
EXPECT_TRUE(v.matched);
|
EXPECT_TRUE(v.matched);
|
||||||
EXPECT_FALSE(v.errored);
|
EXPECT_FALSE(v.errored);
|
||||||
EXPECT_FALSE(p->has_error());
|
EXPECT_FALSE(p->has_error());
|
||||||
ASSERT_NE(v.value, nullptr);
|
EXPECT_EQ(v->name, "my_var");
|
||||||
EXPECT_EQ(v->name(), "my_var");
|
EXPECT_TRUE(v->type->Is<ast::type::F32>());
|
||||||
EXPECT_TRUE(v->type()->Is<ast::type::F32>());
|
EXPECT_EQ(v->storage_class, ast::StorageClass::kPrivate);
|
||||||
EXPECT_EQ(v->storage_class(), ast::StorageClass::kPrivate);
|
|
||||||
|
|
||||||
EXPECT_EQ(v->source().range.begin.line, 1u);
|
EXPECT_EQ(v->source.range.begin.line, 1u);
|
||||||
EXPECT_EQ(v->source().range.begin.column, 14u);
|
EXPECT_EQ(v->source.range.begin.column, 14u);
|
||||||
EXPECT_EQ(v->source().range.end.line, 1u);
|
EXPECT_EQ(v->source.range.end.line, 1u);
|
||||||
EXPECT_EQ(v->source().range.end.column, 20u);
|
EXPECT_EQ(v->source.range.end.column, 20u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
|
TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
|
||||||
|
@ -85,7 +81,6 @@ TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
|
||||||
EXPECT_FALSE(v.matched);
|
EXPECT_FALSE(v.matched);
|
||||||
EXPECT_TRUE(v.errored);
|
EXPECT_TRUE(v.errored);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(v.value, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:5: invalid storage class for variable decoration");
|
EXPECT_EQ(p->error(), "1:5: invalid storage class for variable decoration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ TEST_F(ScopeStackTest, Global) {
|
||||||
|
|
||||||
TEST_F(ScopeStackTest, Global_SetWithPointer) {
|
TEST_F(ScopeStackTest, Global_SetWithPointer) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "test", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "my_var", ast::StorageClass::kNone, &f32, false,
|
||||||
v.set_name("my_var");
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ScopeStack<ast::Variable*> s;
|
ScopeStack<ast::Variable*> s;
|
||||||
s.set_global("var", &v);
|
s.set_global("var", &v);
|
||||||
|
|
|
@ -122,8 +122,7 @@ TEST_F(BoundArrayAccessorsTest, Ptrs_Clamp) {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
||||||
Const("c", ast::StorageClass::kFunction, ty.u32);
|
Const("c", ast::StorageClass::kFunction, ty.u32);
|
||||||
Const("b", ast::StorageClass::kFunction,
|
Const("b", ast::StorageClass::kFunction,
|
||||||
ty.pointer<f32>(ast::StorageClass::kFunction))
|
ty.pointer<f32>(ast::StorageClass::kFunction), Index("a", "c"), {});
|
||||||
->set_constructor(Index("a", "c"));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,8 +170,8 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Nested_Scalar) {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.array<f32, 5>());
|
Var("b", ast::StorageClass::kFunction, ty.array<f32, 5>());
|
||||||
Var("i", ast::StorageClass::kFunction, ty.u32);
|
Var("i", ast::StorageClass::kFunction, ty.u32);
|
||||||
Const("c", ast::StorageClass::kFunction, ty.f32)
|
Const("c", ast::StorageClass::kFunction, ty.f32,
|
||||||
->set_constructor(Index("a", Index("b", "i")));
|
Index("a", Index("b", "i")), {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -241,8 +240,7 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Scalar) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.array(ty.f32, 3));
|
Var("a", ast::StorageClass::kFunction, ty.array(ty.f32, 3));
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 1u), {});
|
||||||
->set_constructor(Index("a", 1u));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,8 +272,8 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Expr) {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
||||||
Var("c", ast::StorageClass::kFunction, ty.u32);
|
Var("c", ast::StorageClass::kFunction, ty.u32);
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32,
|
||||||
->set_constructor(Index("a", Add("c", Sub(2u, 3u))));
|
Index("a", Add("c", Sub(2u, 3u))), {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -340,8 +338,7 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Negative) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", -1), {});
|
||||||
->set_constructor(Index("a", -1));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -371,8 +368,7 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_OutOfBounds) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 3u), {});
|
||||||
->set_constructor(Index("a", 3u));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -402,8 +398,7 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_Scalar) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 1u), {});
|
||||||
->set_constructor(Index("a", 1u));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -435,8 +430,8 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_Expr) {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
||||||
Var("c", ast::StorageClass::kFunction, ty.u32);
|
Var("c", ast::StorageClass::kFunction, ty.u32);
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32,
|
||||||
->set_constructor(Index("a", Add("c", Sub(2u, 3u))));
|
Index("a", Add("c", Sub(2u, 3u))), {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -499,8 +494,7 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_Negative) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", -1), {});
|
||||||
->set_constructor(Index("a", -1));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -530,8 +524,7 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_OutOfBounds) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 3u), {});
|
||||||
->set_constructor(Index("a", 3u));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -561,8 +554,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Scalar) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 2u), 1u),
|
||||||
->set_constructor(Index(Index("a", 2u), 1u));
|
{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -607,8 +600,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Expr_Column) {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("c", ast::StorageClass::kFunction, ty.u32);
|
Var("c", ast::StorageClass::kFunction, ty.u32);
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32,
|
||||||
->set_constructor(Index(Index("a", Add("c", Sub(2u, 3u))), 1u));
|
Index(Index("a", Add("c", Sub(2u, 3u))), 1u), {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -687,8 +680,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Expr_Row) {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("c", ast::StorageClass::kFunction, ty.u32);
|
Var("c", ast::StorageClass::kFunction, ty.u32);
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32,
|
||||||
->set_constructor(Index(Index("a", 1u), Add("c", Sub(2u, 3u))));
|
Index(Index("a", 1u), Add("c", Sub(2u, 3u))), {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -765,8 +758,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Negative_Column) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", -1), 1),
|
||||||
->set_constructor(Index(Index("a", -1), 1));
|
{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -809,8 +802,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Negative_Row) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 2), -1),
|
||||||
->set_constructor(Index(Index("a", 2), -1));
|
{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -853,8 +846,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_OutOfBounds_Column) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 5u), 1u),
|
||||||
->set_constructor(Index(Index("a", 5u), 1u));
|
{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -897,8 +890,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_OutOfBounds_Row) {
|
||||||
struct Builder : ModuleBuilder {
|
struct Builder : ModuleBuilder {
|
||||||
void Build() override {
|
void Build() override {
|
||||||
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
|
||||||
Var("b", ast::StorageClass::kFunction, ty.f32)
|
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 2u), 5u),
|
||||||
->set_constructor(Index(Index("a", 2u), 5u));
|
{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
|
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/block_statement.h"
|
#include "src/ast/block_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
#include "src/ast/type_manager.h"
|
#include "src/ast/type_manager.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace transform {
|
namespace transform {
|
||||||
|
@ -51,11 +51,17 @@ Transform::Output EmitVertexPointSize::Run(ast::Module* in) {
|
||||||
|
|
||||||
// Declare the pointsize builtin output variable.
|
// Declare the pointsize builtin output variable.
|
||||||
auto* pointsize_var =
|
auto* pointsize_var =
|
||||||
mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
|
mod->create<ast::Variable>(Source{}, // source
|
||||||
Source{}, kPointSizeVar, ast::StorageClass::kOutput, f32));
|
kPointSizeVar, // name
|
||||||
pointsize_var->set_decorations({
|
ast::StorageClass::kOutput, // storage_class
|
||||||
mod->create<ast::BuiltinDecoration>(ast::Builtin::kPointSize, Source{}),
|
f32, // type
|
||||||
});
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
mod->create<ast::BuiltinDecoration>(
|
||||||
|
ast::Builtin::kPointSize, Source{}),
|
||||||
|
});
|
||||||
mod->AddGlobalVariable(pointsize_var);
|
mod->AddGlobalVariable(pointsize_var);
|
||||||
|
|
||||||
// Build the AST expression & statement for assigning pointsize one.
|
// Build the AST expression & statement for assigning pointsize one.
|
||||||
|
|
|
@ -83,7 +83,7 @@ TEST_F(EmitVertexPointSizeTest, VertexStageBasic) {
|
||||||
<< diag::Formatter().format(result.diagnostics);
|
<< diag::Formatter().format(result.diagnostics);
|
||||||
|
|
||||||
auto* expected = R"(Module{
|
auto* expected = R"(Module{
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{pointsize}
|
BuiltinDecoration{pointsize}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ TEST_F(EmitVertexPointSizeTest, VertexStageEmpty) {
|
||||||
<< diag::Formatter().format(result.diagnostics);
|
<< diag::Formatter().format(result.diagnostics);
|
||||||
|
|
||||||
auto* expected = R"(Module{
|
auto* expected = R"(Module{
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{pointsize}
|
BuiltinDecoration{pointsize}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/clone_context.h"
|
#include "src/ast/clone_context.h"
|
||||||
#include "src/ast/constructor_expression.h"
|
#include "src/ast/constructor_expression.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/expression.h"
|
#include "src/ast/expression.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
|
@ -62,18 +61,17 @@ constexpr char kFirstVertexName[] = "tint_first_vertex_index";
|
||||||
constexpr char kFirstInstanceName[] = "tint_first_instance_index";
|
constexpr char kFirstInstanceName[] = "tint_first_instance_index";
|
||||||
constexpr char kIndexOffsetPrefix[] = "tint_first_index_offset_";
|
constexpr char kIndexOffsetPrefix[] = "tint_first_index_offset_";
|
||||||
|
|
||||||
ast::DecoratedVariable* clone_variable_with_new_name(ast::CloneContext* ctx,
|
ast::Variable* clone_variable_with_new_name(ast::CloneContext* ctx,
|
||||||
ast::DecoratedVariable* in,
|
ast::Variable* in,
|
||||||
std::string new_name) {
|
std::string new_name) {
|
||||||
auto* var = ctx->mod->create<ast::Variable>(ctx->Clone(in->source()),
|
return ctx->mod->create<ast::Variable>(
|
||||||
new_name, in->storage_class(),
|
ctx->Clone(in->source()), // source
|
||||||
ctx->Clone(in->type()));
|
new_name, // name
|
||||||
var->set_is_const(in->is_const());
|
in->storage_class(), // storage_class
|
||||||
var->set_constructor(ctx->Clone(in->constructor()));
|
ctx->Clone(in->type()), // type
|
||||||
|
in->is_const(), // is_const
|
||||||
auto* out = ctx->mod->create<ast::DecoratedVariable>(var);
|
ctx->Clone(in->constructor()), // constructor
|
||||||
out->set_decorations(ctx->Clone(in->decorations()));
|
ctx->Clone(in->decorations())); // decorations
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -86,7 +84,7 @@ FirstIndexOffset::~FirstIndexOffset() = default;
|
||||||
Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
||||||
// First do a quick check to see if the transform has already been applied.
|
// First do a quick check to see if the transform has already been applied.
|
||||||
for (ast::Variable* var : in->global_variables()) {
|
for (ast::Variable* var : in->global_variables()) {
|
||||||
if (auto* dec_var = var->As<ast::DecoratedVariable>()) {
|
if (auto* dec_var = var->As<ast::Variable>()) {
|
||||||
if (dec_var->name() == kBufferName) {
|
if (dec_var->name() == kBufferName) {
|
||||||
diag::Diagnostic err;
|
diag::Diagnostic err;
|
||||||
err.message = "First index offset transform has already been applied.";
|
err.message = "First index offset transform has already been applied.";
|
||||||
|
@ -129,7 +127,7 @@ Transform::Output FirstIndexOffset::Run(ast::Module* in) {
|
||||||
// a CreateFirstIndexOffset() statement to each function that uses one of
|
// a CreateFirstIndexOffset() statement to each function that uses one of
|
||||||
// these builtins.
|
// these builtins.
|
||||||
ast::CloneContext ctx(&out.module);
|
ast::CloneContext ctx(&out.module);
|
||||||
ctx.ReplaceAll([&](ast::DecoratedVariable* var) -> ast::DecoratedVariable* {
|
ctx.ReplaceAll([&](ast::Variable* var) -> ast::Variable* {
|
||||||
for (ast::VariableDecoration* dec : var->decorations()) {
|
for (ast::VariableDecoration* dec : var->decorations()) {
|
||||||
if (auto* blt_dec = dec->As<ast::BuiltinDecoration>()) {
|
if (auto* blt_dec = dec->As<ast::BuiltinDecoration>()) {
|
||||||
ast::Builtin blt_type = blt_dec->value();
|
ast::Builtin blt_type = blt_dec->value();
|
||||||
|
@ -229,13 +227,17 @@ ast::Variable* FirstIndexOffset::AddUniformBuffer(ast::Module* mod) {
|
||||||
kStructName,
|
kStructName,
|
||||||
mod->create<ast::Struct>(std::move(decos), std::move(members)));
|
mod->create<ast::Struct>(std::move(decos), std::move(members)));
|
||||||
|
|
||||||
auto* idx_var =
|
auto* idx_var = mod->create<ast::Variable>(
|
||||||
mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
|
Source{}, // source
|
||||||
Source{}, kBufferName, ast::StorageClass::kUniform, struct_type));
|
kBufferName, // name
|
||||||
idx_var->set_decorations({
|
ast::StorageClass::kUniform, // storage_class
|
||||||
mod->create<ast::BindingDecoration>(binding_, Source{}),
|
struct_type, // type
|
||||||
mod->create<ast::SetDecoration>(set_, Source{}),
|
false, // is_const
|
||||||
});
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
mod->create<ast::BindingDecoration>(binding_, Source{}),
|
||||||
|
mod->create<ast::SetDecoration>(set_, Source{}),
|
||||||
|
}); // decorations
|
||||||
|
|
||||||
mod->AddGlobalVariable(idx_var);
|
mod->AddGlobalVariable(idx_var);
|
||||||
|
|
||||||
|
@ -250,16 +252,20 @@ ast::VariableDeclStatement* FirstIndexOffset::CreateFirstIndexOffset(
|
||||||
ast::Variable* buffer_var,
|
ast::Variable* buffer_var,
|
||||||
ast::Module* mod) {
|
ast::Module* mod) {
|
||||||
auto* buffer = mod->create<ast::IdentifierExpression>(buffer_var->name());
|
auto* buffer = mod->create<ast::IdentifierExpression>(buffer_var->name());
|
||||||
auto* var = mod->create<ast::Variable>(Source{}, original_name,
|
auto* constructor = mod->create<ast::BinaryExpression>(
|
||||||
ast::StorageClass::kNone,
|
|
||||||
mod->create<ast::type::U32>());
|
|
||||||
|
|
||||||
var->set_is_const(true);
|
|
||||||
var->set_constructor(mod->create<ast::BinaryExpression>(
|
|
||||||
ast::BinaryOp::kAdd,
|
ast::BinaryOp::kAdd,
|
||||||
mod->create<ast::IdentifierExpression>(kIndexOffsetPrefix + var->name()),
|
mod->create<ast::IdentifierExpression>(kIndexOffsetPrefix +
|
||||||
|
original_name),
|
||||||
mod->create<ast::MemberAccessorExpression>(
|
mod->create<ast::MemberAccessorExpression>(
|
||||||
buffer, mod->create<ast::IdentifierExpression>(field_name))));
|
buffer, mod->create<ast::IdentifierExpression>(field_name)));
|
||||||
|
auto* var =
|
||||||
|
mod->create<ast::Variable>(Source{}, // source
|
||||||
|
original_name, // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
mod->create<ast::type::U32>(), // type
|
||||||
|
true, // is_const
|
||||||
|
constructor, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
return mod->create<ast::VariableDeclStatement>(var);
|
return mod->create<ast::VariableDeclStatement>(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
@ -52,12 +51,9 @@ struct ModuleBuilder : public ast::BuilderWithModule {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void AddBuiltinInput(const std::string& name, ast::Builtin builtin) {
|
void AddBuiltinInput(const std::string& name, ast::Builtin builtin) {
|
||||||
auto* var = Var(name, ast::StorageClass::kInput, ty.u32);
|
mod->AddGlobalVariable(
|
||||||
auto* dec_var = create<ast::DecoratedVariable>(var);
|
Var(name, ast::StorageClass::kInput, ty.u32, nullptr,
|
||||||
ast::VariableDecorationList decs;
|
{create<ast::BuiltinDecoration>(builtin, Source{})}));
|
||||||
decs.push_back(create<ast::BuiltinDecoration>(builtin, Source{}));
|
|
||||||
dec_var->set_decorations(std::move(decs));
|
|
||||||
mod->AddGlobalVariable(dec_var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Function* AddFunction(const std::string& name,
|
ast::Function* AddFunction(const std::string& name,
|
||||||
|
@ -141,7 +137,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
|
||||||
[[block]]
|
[[block]]
|
||||||
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
|
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +145,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
|
||||||
in
|
in
|
||||||
__u32
|
__u32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
|
@ -216,7 +212,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
|
||||||
[[block]]
|
[[block]]
|
||||||
StructMember{[[ offset 0 ]] tint_first_instance_index: __u32}
|
StructMember{[[ offset 0 ]] tint_first_instance_index: __u32}
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{instance_idx}
|
BuiltinDecoration{instance_idx}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +220,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
|
||||||
in
|
in
|
||||||
__u32
|
__u32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
SetDecoration{7}
|
SetDecoration{7}
|
||||||
|
@ -296,7 +292,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
|
||||||
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
|
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
|
||||||
StructMember{[[ offset 4 ]] tint_first_instance_index: __u32}
|
StructMember{[[ offset 4 ]] tint_first_instance_index: __u32}
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{instance_idx}
|
BuiltinDecoration{instance_idx}
|
||||||
}
|
}
|
||||||
|
@ -304,7 +300,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
|
||||||
in
|
in
|
||||||
__u32
|
__u32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -312,7 +308,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
|
||||||
in
|
in
|
||||||
__u32
|
__u32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
SetDecoration{7}
|
SetDecoration{7}
|
||||||
|
@ -376,7 +372,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) {
|
||||||
[[block]]
|
[[block]]
|
||||||
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
|
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -384,7 +380,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) {
|
||||||
in
|
in
|
||||||
__u32
|
__u32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{2}
|
BindingDecoration{2}
|
||||||
SetDecoration{2}
|
SetDecoration{2}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#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"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/stride_decoration.h"
|
#include "src/ast/stride_decoration.h"
|
||||||
|
@ -37,6 +36,7 @@
|
||||||
#include "src/ast/type/vector_type.h"
|
#include "src/ast/type/vector_type.h"
|
||||||
#include "src/ast/type_constructor_expression.h"
|
#include "src/ast/type_constructor_expression.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -143,13 +143,11 @@ void VertexPulling::State::FindOrInsertVertexIndexIfUsed() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = v->As<ast::DecoratedVariable>()) {
|
for (auto* d : v->decorations()) {
|
||||||
for (auto* d : decorated->decorations()) {
|
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
|
||||||
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
|
if (builtin->value() == ast::Builtin::kVertexIdx) {
|
||||||
if (builtin->value() == ast::Builtin::kVertexIdx) {
|
vertex_index_name = v->name();
|
||||||
vertex_index_name = v->name();
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,14 +156,19 @@ void VertexPulling::State::FindOrInsertVertexIndexIfUsed() {
|
||||||
// We didn't find a vertex index builtin, so create one
|
// We didn't find a vertex index builtin, so create one
|
||||||
vertex_index_name = kDefaultVertexIndexName;
|
vertex_index_name = kDefaultVertexIndexName;
|
||||||
|
|
||||||
auto* var = mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
|
auto* var =
|
||||||
Source{}, vertex_index_name, ast::StorageClass::kInput, GetI32Type()));
|
mod->create<ast::Variable>(Source{}, // source
|
||||||
|
vertex_index_name, // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
GetI32Type(), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
mod->create<ast::BuiltinDecoration>(
|
||||||
|
ast::Builtin::kVertexIdx, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::VariableDecorationList decorations;
|
|
||||||
decorations.push_back(
|
|
||||||
mod->create<ast::BuiltinDecoration>(ast::Builtin::kVertexIdx, Source{}));
|
|
||||||
|
|
||||||
var->set_decorations(std::move(decorations));
|
|
||||||
mod->AddGlobalVariable(var);
|
mod->AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,13 +190,11 @@ void VertexPulling::State::FindOrInsertInstanceIndexIfUsed() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = v->As<ast::DecoratedVariable>()) {
|
for (auto* d : v->decorations()) {
|
||||||
for (auto* d : decorated->decorations()) {
|
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
|
||||||
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
|
if (builtin->value() == ast::Builtin::kInstanceIdx) {
|
||||||
if (builtin->value() == ast::Builtin::kInstanceIdx) {
|
instance_index_name = v->name();
|
||||||
instance_index_name = v->name();
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,14 +203,18 @@ void VertexPulling::State::FindOrInsertInstanceIndexIfUsed() {
|
||||||
// We didn't find an instance index builtin, so create one
|
// We didn't find an instance index builtin, so create one
|
||||||
instance_index_name = kDefaultInstanceIndexName;
|
instance_index_name = kDefaultInstanceIndexName;
|
||||||
|
|
||||||
auto* var = mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
|
auto* var =
|
||||||
Source{}, instance_index_name, ast::StorageClass::kInput, GetI32Type()));
|
mod->create<ast::Variable>(Source{}, // source
|
||||||
|
instance_index_name, // name
|
||||||
ast::VariableDecorationList decorations;
|
ast::StorageClass::kInput, // storage_class
|
||||||
decorations.push_back(mod->create<ast::BuiltinDecoration>(
|
GetI32Type(), // type
|
||||||
ast::Builtin::kInstanceIdx, Source{}));
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
var->set_decorations(std::move(decorations));
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
mod->create<ast::BuiltinDecoration>(
|
||||||
|
ast::Builtin::kInstanceIdx, Source{}),
|
||||||
|
});
|
||||||
mod->AddGlobalVariable(var);
|
mod->AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,18 +224,22 @@ void VertexPulling::State::ConvertVertexInputVariablesToPrivate() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* decorated = v->As<ast::DecoratedVariable>()) {
|
for (auto* d : v->decorations()) {
|
||||||
for (auto* d : decorated->decorations()) {
|
if (auto* l = d->As<ast::LocationDecoration>()) {
|
||||||
if (auto* l = d->As<ast::LocationDecoration>()) {
|
uint32_t location = l->value();
|
||||||
uint32_t location = l->value();
|
// This is where the replacement happens. Expressions use identifier
|
||||||
// This is where the replacement happens. Expressions use identifier
|
// strings instead of pointers, so we don't need to update any other
|
||||||
// strings instead of pointers, so we don't need to update any other
|
// place in the AST.
|
||||||
// place in the AST.
|
v = mod->create<ast::Variable>(
|
||||||
v = mod->create<ast::Variable>(
|
Source{}, // source
|
||||||
Source{}, v->name(), ast::StorageClass::kPrivate, v->type());
|
v->name(), // name
|
||||||
location_to_var[location] = v;
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
break;
|
v->type(), // type
|
||||||
}
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
location_to_var[location] = v;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,17 +272,18 @@ void VertexPulling::State::AddVertexStorageBuffers() {
|
||||||
|
|
||||||
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
|
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
|
||||||
// The decorated variable with struct type
|
// The decorated variable with struct type
|
||||||
auto* var = mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
|
auto* var = mod->create<ast::Variable>(
|
||||||
Source{}, GetVertexBufferName(i), ast::StorageClass::kStorageBuffer,
|
Source{}, // source
|
||||||
struct_type));
|
GetVertexBufferName(i), // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
// Add decorations
|
struct_type, // type
|
||||||
ast::VariableDecorationList decorations;
|
false, // is_const
|
||||||
decorations.push_back(mod->create<ast::BindingDecoration>(i, Source{}));
|
nullptr, // constructor
|
||||||
decorations.push_back(
|
ast::VariableDecorationList{
|
||||||
mod->create<ast::SetDecoration>(cfg.pulling_set, Source{}));
|
// decorations
|
||||||
var->set_decorations(std::move(decorations));
|
mod->create<ast::BindingDecoration>(i, Source{}),
|
||||||
|
mod->create<ast::SetDecoration>(cfg.pulling_set, Source{}),
|
||||||
|
});
|
||||||
mod->AddGlobalVariable(var);
|
mod->AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
mod->AddConstructedType(struct_type);
|
mod->AddConstructedType(struct_type);
|
||||||
|
@ -288,9 +298,15 @@ void VertexPulling::State::AddVertexPullingPreamble(
|
||||||
auto* block = mod->create<ast::BlockStatement>();
|
auto* block = mod->create<ast::BlockStatement>();
|
||||||
|
|
||||||
// Declare the |kPullingPosVarName| variable in the shader
|
// Declare the |kPullingPosVarName| variable in the shader
|
||||||
auto* pos_declaration = mod->create<ast::VariableDeclStatement>(
|
auto* pos_declaration =
|
||||||
mod->create<ast::Variable>(Source{}, kPullingPosVarName,
|
mod->create<ast::VariableDeclStatement>(mod->create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, GetI32Type()));
|
Source{}, // source
|
||||||
|
kPullingPosVarName, // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
GetI32Type(), // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
// |kPullingPosVarName| refers to the byte location of the current read. We
|
// |kPullingPosVarName| refers to the byte location of the current read. We
|
||||||
// declare a variable in the shader to avoid having to reuse Expression
|
// declare a variable in the shader to avoid having to reuse Expression
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
|
@ -25,6 +24,7 @@
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
#include "src/ast/type/i32_type.h"
|
#include "src/ast/type/i32_type.h"
|
||||||
#include "src/ast/type/void_type.h"
|
#include "src/ast/type/void_type.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/diagnostic/formatter.h"
|
#include "src/diagnostic/formatter.h"
|
||||||
#include "src/transform/manager.h"
|
#include "src/transform/manager.h"
|
||||||
#include "src/type_determiner.h"
|
#include "src/type_determiner.h"
|
||||||
|
@ -69,13 +69,18 @@ class VertexPullingHelper {
|
||||||
void AddVertexInputVariable(uint32_t location,
|
void AddVertexInputVariable(uint32_t location,
|
||||||
std::string name,
|
std::string name,
|
||||||
ast::type::Type* type) {
|
ast::type::Type* type) {
|
||||||
auto* var = create<ast::DecoratedVariable>(
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, name, ast::StorageClass::kInput, type));
|
Source{}, // source
|
||||||
|
name, // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(location, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::VariableDecorationList decorations;
|
|
||||||
decorations.push_back(create<ast::LocationDecoration>(location, Source{}));
|
|
||||||
|
|
||||||
var->set_decorations(decorations);
|
|
||||||
mod_->AddGlobalVariable(var);
|
mod_->AddGlobalVariable(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +176,7 @@ TEST_F(VertexPullingTest, OneAttribute) {
|
||||||
private
|
private
|
||||||
__f32
|
__f32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +184,7 @@ TEST_F(VertexPullingTest, OneAttribute) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -257,7 +262,7 @@ TEST_F(VertexPullingTest, OneInstancedAttribute) {
|
||||||
private
|
private
|
||||||
__f32
|
__f32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{instance_idx}
|
BuiltinDecoration{instance_idx}
|
||||||
}
|
}
|
||||||
|
@ -265,7 +270,7 @@ TEST_F(VertexPullingTest, OneInstancedAttribute) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -343,7 +348,7 @@ TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet) {
|
||||||
private
|
private
|
||||||
__f32
|
__f32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -351,7 +356,7 @@ TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
SetDecoration{5}
|
SetDecoration{5}
|
||||||
|
@ -416,31 +421,30 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
|
||||||
AddVertexInputVariable(1, "var_b", &f32);
|
AddVertexInputVariable(1, "var_b", &f32);
|
||||||
|
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
{
|
|
||||||
auto* vertex_index_var =
|
|
||||||
create<ast::DecoratedVariable>(create<ast::Variable>(
|
|
||||||
Source{}, "custom_vertex_index", ast::StorageClass::kInput, &i32));
|
|
||||||
|
|
||||||
ast::VariableDecorationList decorations;
|
mod()->AddGlobalVariable(create<ast::Variable>(
|
||||||
decorations.push_back(
|
Source{}, // source
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kVertexIdx, Source{}));
|
"custom_vertex_index", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kVertexIdx, Source{}),
|
||||||
|
}));
|
||||||
|
|
||||||
vertex_index_var->set_decorations(decorations);
|
mod()->AddGlobalVariable(create<ast::Variable>(
|
||||||
mod()->AddGlobalVariable(vertex_index_var);
|
Source{}, // source
|
||||||
}
|
"custom_instance_index", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
{
|
&i32, // type
|
||||||
auto* instance_index_var = create<ast::DecoratedVariable>(
|
false, // is_const
|
||||||
create<ast::Variable>(Source{}, "custom_instance_index",
|
nullptr, // constructor
|
||||||
ast::StorageClass::kInput, &i32));
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
ast::VariableDecorationList decorations;
|
create<ast::BuiltinDecoration>(ast::Builtin::kInstanceIdx, Source{}),
|
||||||
decorations.push_back(
|
}));
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kInstanceIdx, Source{}));
|
|
||||||
|
|
||||||
instance_index_var->set_decorations(decorations);
|
|
||||||
mod()->AddGlobalVariable(instance_index_var);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitTransform(
|
InitTransform(
|
||||||
{{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}},
|
{{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}},
|
||||||
|
@ -464,7 +468,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
|
||||||
private
|
private
|
||||||
__f32
|
__f32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +476,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{instance_idx}
|
BuiltinDecoration{instance_idx}
|
||||||
}
|
}
|
||||||
|
@ -480,7 +484,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -489,7 +493,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
|
||||||
storage_buffer
|
storage_buffer
|
||||||
__struct_TintVertexData
|
__struct_TintVertexData
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -605,7 +609,7 @@ TEST_F(VertexPullingTest, TwoAttributesSameBuffer) {
|
||||||
private
|
private
|
||||||
__array__f32_4
|
__array__f32_4
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -613,7 +617,7 @@ TEST_F(VertexPullingTest, TwoAttributesSameBuffer) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -796,7 +800,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
|
||||||
private
|
private
|
||||||
__array__f32_4
|
__array__f32_4
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
}
|
}
|
||||||
|
@ -804,7 +808,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -813,7 +817,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
|
||||||
storage_buffer
|
storage_buffer
|
||||||
__struct_TintVertexData
|
__struct_TintVertexData
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{1}
|
BindingDecoration{1}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
@ -822,7 +826,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
|
||||||
storage_buffer
|
storage_buffer
|
||||||
__struct_TintVertexData
|
__struct_TintVertexData
|
||||||
}
|
}
|
||||||
DecoratedVariable{
|
Variable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{2}
|
BindingDecoration{2}
|
||||||
SetDecoration{4}
|
SetDecoration{4}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,10 +43,15 @@ TEST_F(ValidateControlBlockTest, SwitchSelectorExpressionNoneIntegerType_Fail) {
|
||||||
// default: {}
|
// default: {}
|
||||||
// }
|
// }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&f32, 3.14f)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&f32, 3.14f)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* cond =
|
auto* cond =
|
||||||
create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
|
create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
|
||||||
|
@ -72,10 +77,15 @@ TEST_F(ValidateControlBlockTest, SwitchWithoutDefault_Fail) {
|
||||||
// case 1: {}
|
// case 1: {}
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
ast::CaseSelectorList csl;
|
ast::CaseSelectorList csl;
|
||||||
|
@ -104,10 +114,15 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) {
|
||||||
// default: {}
|
// default: {}
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::CaseStatementList switch_body;
|
ast::CaseStatementList switch_body;
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
|
@ -148,10 +163,15 @@ TEST_F(ValidateControlBlockTest,
|
||||||
// }
|
// }
|
||||||
ast::type::U32 u32;
|
ast::type::U32 u32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::CaseStatementList switch_body;
|
ast::CaseStatementList switch_body;
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
|
@ -185,10 +205,15 @@ TEST_F(ValidateControlBlockTest,
|
||||||
// }
|
// }
|
||||||
ast::type::U32 u32;
|
ast::type::U32 u32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &u32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::UintLiteral>(&u32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&u32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::UintLiteral>(&u32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::CaseStatementList switch_body;
|
ast::CaseStatementList switch_body;
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
|
@ -221,10 +246,15 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) {
|
||||||
// default: {}
|
// default: {}
|
||||||
// }
|
// }
|
||||||
ast::type::U32 u32;
|
ast::type::U32 u32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &u32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::UintLiteral>(&u32, 3)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&u32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::UintLiteral>(&u32, 3)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::CaseStatementList switch_body;
|
ast::CaseStatementList switch_body;
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
|
@ -263,10 +293,15 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) {
|
||||||
// default: {}
|
// default: {}
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::CaseStatementList switch_body;
|
ast::CaseStatementList switch_body;
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
|
@ -305,10 +340,15 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) {
|
||||||
// default: { fallthrough; }
|
// default: { fallthrough; }
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
ast::CaseSelectorList default_csl;
|
ast::CaseSelectorList default_csl;
|
||||||
|
@ -336,10 +376,15 @@ TEST_F(ValidateControlBlockTest, SwitchCase_Pass) {
|
||||||
// case 5: {}
|
// case 5: {}
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
ast::CaseSelectorList default_csl;
|
ast::CaseSelectorList default_csl;
|
||||||
|
@ -370,10 +415,15 @@ TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
|
||||||
ast::type::U32 u32;
|
ast::type::U32 u32;
|
||||||
ast::type::Alias my_int{"MyInt", &u32};
|
ast::type::Alias my_int{"MyInt", &u32};
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &my_int);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&u32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&my_int, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&u32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* cond = create<ast::IdentifierExpression>("a");
|
auto* cond = create<ast::IdentifierExpression>("a");
|
||||||
ast::CaseSelectorList default_csl;
|
ast::CaseSelectorList default_csl;
|
||||||
|
|
|
@ -39,10 +39,15 @@ TEST_F(ValidateFunctionTest, VoidFunctionEndWithoutReturnStatement_Pass) {
|
||||||
// [[stage(vertex)]]
|
// [[stage(vertex)]]
|
||||||
// fn func -> void { var a:i32 = 2; }
|
// fn func -> void { var a:i32 = 2; }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
@ -81,10 +86,15 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
|
||||||
// fn func -> int { var a:i32 = 2; }
|
// fn func -> int { var a:i32 = 2; }
|
||||||
|
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
@ -239,13 +249,18 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
|
||||||
TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
|
TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
|
||||||
// fn func() -> i32 {var a: i32 = func(); return 2; }
|
// fn func() -> i32 {var a: i32 = func(); return 2; }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
|
||||||
ast::ExpressionList call_params;
|
ast::ExpressionList call_params;
|
||||||
auto* call_expr = create<ast::CallExpression>(
|
auto* call_expr = create<ast::CallExpression>(
|
||||||
Source{Source::Location{12, 34}},
|
Source{Source::Location{12, 34}},
|
||||||
create<ast::IdentifierExpression>("func"), call_params);
|
create<ast::IdentifierExpression>("func"), call_params);
|
||||||
var->set_constructor(call_expr);
|
auto* var =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
call_expr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
ast::VariableList params0;
|
ast::VariableList params0;
|
||||||
auto* body0 = create<ast::BlockStatement>();
|
auto* body0 = create<ast::BlockStatement>();
|
||||||
body0->append(create<ast::VariableDeclStatement>(var));
|
body0->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -292,7 +307,13 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(Source{}));
|
body->append(create<ast::ReturnStatement>(Source{}));
|
||||||
auto* func = create<ast::Function>(
|
auto* func = create<ast::Function>(
|
||||||
|
|
|
@ -115,10 +115,15 @@ TEST_F(ValidatorTest, AssignCompatibleTypes_Pass) {
|
||||||
// var a :i32 = 2;
|
// var a :i32 = 2;
|
||||||
// a = 2
|
// a = 2
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -140,10 +145,16 @@ TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 2.3f));
|
create<ast::FloatLiteral>(&f32, 2.3f));
|
||||||
|
@ -167,10 +178,15 @@ TEST_F(ValidatorTest, AssignCompatibleTypesInBlockStatement_Pass) {
|
||||||
// a = 2
|
// a = 2
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -196,10 +212,15 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 2.3f));
|
create<ast::FloatLiteral>(&f32, 2.3f));
|
||||||
|
@ -223,10 +244,14 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
|
||||||
TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
|
TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
|
||||||
// var<in> gloabl_var: f32;
|
// var<in> gloabl_var: f32;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* global_var =
|
mod()->AddGlobalVariable(
|
||||||
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
|
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
|
||||||
ast::StorageClass::kInput, &f32);
|
"global_var", // name
|
||||||
mod()->AddGlobalVariable(global_var);
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables()))
|
EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables()))
|
||||||
<< v()->error();
|
<< v()->error();
|
||||||
}
|
}
|
||||||
|
@ -234,24 +259,31 @@ TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
|
||||||
TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
|
TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
|
||||||
// var gloabl_var: f32;
|
// var gloabl_var: f32;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* global_var =
|
mod()->AddGlobalVariable(
|
||||||
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
|
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
|
||||||
ast::StorageClass::kNone, &f32);
|
"global_var", // name
|
||||||
mod()->AddGlobalVariable(global_var);
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||||
EXPECT_FALSE(v()->Validate(mod()));
|
EXPECT_FALSE(v()->Validate(mod()));
|
||||||
EXPECT_EQ(v()->error(),
|
EXPECT_EQ(v()->error(),
|
||||||
"12:34 v-0022: global variables must have a storage class");
|
"12:34 v-0022: global variables must have a storage class");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
|
TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
|
||||||
// const<in> gloabl_var: f32;
|
// const<in> gloabl_var: f32;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* global_var =
|
mod()->AddGlobalVariable(
|
||||||
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
|
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
|
||||||
ast::StorageClass::kInput, &f32);
|
"global_var", // name
|
||||||
global_var->set_is_const(true);
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
mod()->AddGlobalVariable(global_var);
|
true, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||||
EXPECT_FALSE(v()->Validate(mod()));
|
EXPECT_FALSE(v()->Validate(mod()));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
|
@ -262,12 +294,14 @@ TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
|
||||||
TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
|
TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
|
||||||
// const gloabl_var: f32;
|
// const gloabl_var: f32;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* global_var =
|
mod()->AddGlobalVariable(
|
||||||
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
|
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
|
||||||
ast::StorageClass::kNone, &f32);
|
"global_var", // name
|
||||||
global_var->set_is_const(true);
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
mod()->AddGlobalVariable(global_var);
|
true, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||||
EXPECT_FALSE(v()->Validate(mod())) << v()->error();
|
EXPECT_FALSE(v()->Validate(mod())) << v()->error();
|
||||||
}
|
}
|
||||||
|
@ -278,11 +312,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
|
||||||
// not_global_var = 3.14f;
|
// not_global_var = 3.14f;
|
||||||
// }
|
// }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* global_var = create<ast::Variable>(Source{}, "global_var",
|
mod()->AddGlobalVariable(create<ast::Variable>(
|
||||||
ast::StorageClass::kPrivate, &f32);
|
Source{}, // source
|
||||||
global_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"global_var", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.1)));
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
mod()->AddGlobalVariable(global_var);
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.1)), // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>(
|
auto* lhs = create<ast::IdentifierExpression>(
|
||||||
Source{Source::Location{12, 34}}, "not_global_var");
|
Source{Source::Location{12, 34}}, "not_global_var");
|
||||||
|
@ -311,11 +349,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
|
||||||
auto* global_var = create<ast::Variable>(Source{}, "global_var",
|
mod()->AddGlobalVariable(create<ast::Variable>(
|
||||||
ast::StorageClass::kPrivate, &f32);
|
Source{}, // source
|
||||||
global_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"global_var", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.1)));
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
mod()->AddGlobalVariable(global_var);
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.1)), // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("global_var");
|
auto* lhs = create<ast::IdentifierExpression>("global_var");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -344,10 +386,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) {
|
||||||
// a = 3.14;
|
// a = 3.14;
|
||||||
// }
|
// }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
auto* cond = create<ast::ScalarConstructorExpression>(
|
auto* cond = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -379,10 +426,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) {
|
||||||
// if (true) { a = 3.14; }
|
// if (true) { a = 3.14; }
|
||||||
// }
|
// }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs =
|
auto* lhs =
|
||||||
create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
|
create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
|
||||||
|
@ -411,17 +463,26 @@ TEST_F(ValidatorTest, GlobalVariableUnique_Pass) {
|
||||||
// var global_var1 : i32 = 0;
|
// var global_var1 : i32 = 0;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var0 = create<ast::Variable>(Source{}, "global_var0",
|
auto* var0 = create<ast::Variable>(
|
||||||
ast::StorageClass::kPrivate, &f32);
|
Source{}, // source
|
||||||
var0->set_constructor(create<ast::ScalarConstructorExpression>(
|
"global_var0", // name
|
||||||
create<ast::FloatLiteral>(&f32, 0.1)));
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 0.1)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
mod()->AddGlobalVariable(var0);
|
mod()->AddGlobalVariable(var0);
|
||||||
|
|
||||||
auto* var1 =
|
auto* var1 = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var1",
|
Source{Source::Location{12, 34}}, // source
|
||||||
ast::StorageClass::kPrivate, &f32);
|
"global_var1", // name
|
||||||
var1->set_constructor(create<ast::ScalarConstructorExpression>(
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
create<ast::SintLiteral>(&i32, 0)));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
mod()->AddGlobalVariable(var1);
|
mod()->AddGlobalVariable(var1);
|
||||||
|
|
||||||
EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables()))
|
EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables()))
|
||||||
|
@ -433,17 +494,26 @@ TEST_F(ValidatorTest, GlobalVariableNotUnique_Fail) {
|
||||||
// var global_var : i32 = 0;
|
// var global_var : i32 = 0;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var0 = create<ast::Variable>(Source{}, "global_var",
|
auto* var0 = create<ast::Variable>(
|
||||||
ast::StorageClass::kPrivate, &f32);
|
Source{}, // source
|
||||||
var0->set_constructor(create<ast::ScalarConstructorExpression>(
|
"global_var", // name
|
||||||
create<ast::FloatLiteral>(&f32, 0.1)));
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 0.1)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
mod()->AddGlobalVariable(var0);
|
mod()->AddGlobalVariable(var0);
|
||||||
|
|
||||||
auto* var1 =
|
auto* var1 = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
|
Source{Source::Location{12, 34}}, // source
|
||||||
ast::StorageClass::kPrivate, &f32);
|
"global_var", // name
|
||||||
var1->set_constructor(create<ast::ScalarConstructorExpression>(
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
create<ast::SintLiteral>(&i32, 0)));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
mod()->AddGlobalVariable(var1);
|
mod()->AddGlobalVariable(var1);
|
||||||
|
|
||||||
EXPECT_FALSE(v()->ValidateGlobalVariables(mod()->global_variables()));
|
EXPECT_FALSE(v()->ValidateGlobalVariables(mod()->global_variables()));
|
||||||
|
@ -457,11 +527,15 @@ TEST_F(ValidatorTest, AssignToConstant_Fail) {
|
||||||
// a = 2
|
// a = 2
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
var->set_is_const(true);
|
&i32, // type
|
||||||
|
true, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -489,16 +563,26 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
|
||||||
|
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* global_var =
|
auto* global_var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32);
|
Source{}, // source
|
||||||
global_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.1)));
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.1)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
mod()->AddGlobalVariable(global_var);
|
mod()->AddGlobalVariable(global_var);
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(
|
body->append(create<ast::VariableDeclStatement>(
|
||||||
|
@ -522,15 +606,25 @@ TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::SintLiteral>(&i32, 2)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* var_a_float =
|
auto* var_a_float = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 0.1)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 0.1)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
|
@ -554,10 +648,15 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
|
||||||
// var a : f32 = 3.14;
|
// var a : f32 = 3.14;
|
||||||
// }
|
// }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
auto* cond = create<ast::ScalarConstructorExpression>(
|
auto* cond = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -565,10 +664,15 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
|
||||||
auto* var_a_float =
|
auto* var_a_float = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 3.14)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 3.14)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* outer_body = create<ast::BlockStatement>();
|
auto* outer_body = create<ast::BlockStatement>();
|
||||||
outer_body->append(
|
outer_body->append(
|
||||||
|
@ -588,15 +692,25 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
|
||||||
// if (true) { var a : f32 = 2.0; }
|
// if (true) { var a : f32 = 2.0; }
|
||||||
// }
|
// }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var_a_float =
|
auto* var_a_float = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 3.14)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 3.14)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
auto* cond = create<ast::ScalarConstructorExpression>(
|
auto* cond = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -620,15 +734,25 @@ TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
|
||||||
// func1 { var a : f32 = 3.0; return; }
|
// func1 { var a : f32 = 3.0; return; }
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
auto* var0 =
|
auto* var0 = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
Source{}, // source
|
||||||
var0->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* var1 = create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone,
|
auto* var1 = create<ast::Variable>(
|
||||||
&void_type);
|
Source{}, // source
|
||||||
var1->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::FloatLiteral>(&f32, 1.0)));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&void_type, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 1.0)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableList params0;
|
ast::VariableList params0;
|
||||||
auto* body0 = create<ast::BlockStatement>();
|
auto* body0 = create<ast::BlockStatement>();
|
||||||
|
@ -663,7 +787,13 @@ TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {
|
||||||
// }
|
// }
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td()->RegisterVariableForTesting(var);
|
td()->RegisterVariableForTesting(var);
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
|
|
|
@ -194,7 +194,13 @@ TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
|
||||||
ast::type::Array array(&i32, 0, ast::ArrayDecorationList{});
|
ast::type::Array array(&i32, 0, ast::ArrayDecorationList{});
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &array);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&array, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
|
@ -56,6 +56,7 @@
|
||||||
#include "src/ast/type/void_type.h"
|
#include "src/ast/type/void_type.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/writer/append_vector.h"
|
#include "src/writer/append_vector.h"
|
||||||
#include "src/writer/float_to_string.h"
|
#include "src/writer/float_to_string.h"
|
||||||
|
@ -1035,12 +1036,9 @@ bool GeneratorImpl::EmitExpression(std::ostream& pre,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
|
bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
|
||||||
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
|
if (var->HasLocationDecoration() || var->HasBuiltinDecoration()) {
|
||||||
if (decorated->HasLocationDecoration() ||
|
return var->storage_class() == ast::StorageClass::kInput ||
|
||||||
decorated->HasBuiltinDecoration()) {
|
var->storage_class() == ast::StorageClass::kOutput;
|
||||||
return var->storage_class() == ast::StorageClass::kInput ||
|
|
||||||
var->storage_class() == ast::StorageClass::kOutput;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2237,7 +2235,7 @@ bool GeneratorImpl::EmitVariable(std::ostream& out,
|
||||||
make_indent(out);
|
make_indent(out);
|
||||||
|
|
||||||
// TODO(dsinclair): Handle variable decorations
|
// TODO(dsinclair): Handle variable decorations
|
||||||
if (var->Is<ast::DecoratedVariable>()) {
|
if (!var->decorations().empty()) {
|
||||||
error_ = "Variable decorations are not handled yet";
|
error_ = "Variable decorations are not handled yet";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2271,10 +2269,11 @@ bool GeneratorImpl::EmitProgramConstVariable(std::ostream& out,
|
||||||
const ast::Variable* var) {
|
const ast::Variable* var) {
|
||||||
make_indent(out);
|
make_indent(out);
|
||||||
|
|
||||||
auto* decorated = var->As<ast::DecoratedVariable>();
|
for (auto* d : var->decorations()) {
|
||||||
if (decorated != nullptr && !decorated->HasConstantIdDecoration()) {
|
if (!d->Is<ast::ConstantIdDecoration>()) {
|
||||||
error_ = "Decorated const values not valid";
|
error_ = "Decorated const values not valid";
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!var->is_const()) {
|
if (!var->is_const()) {
|
||||||
error_ = "Expected a const value";
|
error_ = "Expected a const value";
|
||||||
|
@ -2290,8 +2289,8 @@ bool GeneratorImpl::EmitProgramConstVariable(std::ostream& out,
|
||||||
out << pre.str();
|
out << pre.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decorated != nullptr && decorated->HasConstantIdDecoration()) {
|
if (var->HasConstantIdDecoration()) {
|
||||||
auto const_id = decorated->constant_id();
|
auto const_id = var->constant_id();
|
||||||
|
|
||||||
out << "#ifndef WGSL_SPEC_CONSTANT_" << const_id << std::endl;
|
out << "#ifndef WGSL_SPEC_CONSTANT_" << const_id << std::endl;
|
||||||
|
|
||||||
|
|
|
@ -62,10 +62,22 @@ TEST_P(HlslBinaryTest, Emit_f32) {
|
||||||
|
|
||||||
auto params = GetParam();
|
auto params = GetParam();
|
||||||
|
|
||||||
auto* left_var = create<ast::Variable>(Source{}, "left",
|
auto* left_var =
|
||||||
ast::StorageClass::kFunction, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
auto* right_var = create<ast::Variable>(Source{}, "right",
|
"left", // name
|
||||||
ast::StorageClass::kFunction, &f32);
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* right_var =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"right", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* left = create<ast::IdentifierExpression>("left");
|
auto* left = create<ast::IdentifierExpression>("left");
|
||||||
auto* right = create<ast::IdentifierExpression>("right");
|
auto* right = create<ast::IdentifierExpression>("right");
|
||||||
|
@ -84,10 +96,22 @@ TEST_P(HlslBinaryTest, Emit_u32) {
|
||||||
|
|
||||||
auto params = GetParam();
|
auto params = GetParam();
|
||||||
|
|
||||||
auto* left_var = create<ast::Variable>(Source{}, "left",
|
auto* left_var =
|
||||||
ast::StorageClass::kFunction, &u32);
|
create<ast::Variable>(Source{}, // source
|
||||||
auto* right_var = create<ast::Variable>(Source{}, "right",
|
"left", // name
|
||||||
ast::StorageClass::kFunction, &u32);
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&u32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* right_var =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"right", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&u32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* left = create<ast::IdentifierExpression>("left");
|
auto* left = create<ast::IdentifierExpression>("left");
|
||||||
auto* right = create<ast::IdentifierExpression>("right");
|
auto* right = create<ast::IdentifierExpression>("right");
|
||||||
|
@ -106,10 +130,22 @@ TEST_P(HlslBinaryTest, Emit_i32) {
|
||||||
|
|
||||||
auto params = GetParam();
|
auto params = GetParam();
|
||||||
|
|
||||||
auto* left_var = create<ast::Variable>(Source{}, "left",
|
auto* left_var =
|
||||||
ast::StorageClass::kFunction, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
auto* right_var = create<ast::Variable>(Source{}, "right",
|
"left", // name
|
||||||
ast::StorageClass::kFunction, &i32);
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* right_var =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"right", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* left = create<ast::IdentifierExpression>("left");
|
auto* left = create<ast::IdentifierExpression>("left");
|
||||||
auto* right = create<ast::IdentifierExpression>("right");
|
auto* right = create<ast::IdentifierExpression>("right");
|
||||||
|
@ -199,8 +235,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("mat");
|
auto* lhs = create<ast::IdentifierExpression>("mat");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.f));
|
create<ast::FloatLiteral>(&f32, 1.f));
|
||||||
|
@ -218,8 +260,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::ScalarConstructorExpression>(
|
auto* lhs = create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.f));
|
create<ast::FloatLiteral>(&f32, 1.f));
|
||||||
auto* rhs = create<ast::IdentifierExpression>("mat");
|
auto* rhs = create<ast::IdentifierExpression>("mat");
|
||||||
|
@ -238,8 +286,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("mat");
|
auto* lhs = create<ast::IdentifierExpression>("mat");
|
||||||
|
|
||||||
ast::ExpressionList vals;
|
ast::ExpressionList vals;
|
||||||
|
@ -265,8 +319,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ExpressionList vals;
|
ast::ExpressionList vals;
|
||||||
vals.push_back(create<ast::ScalarConstructorExpression>(
|
vals.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -293,8 +353,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("mat");
|
auto* lhs = create<ast::IdentifierExpression>("mat");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("mat");
|
auto* rhs = create<ast::IdentifierExpression>("mat");
|
||||||
|
|
||||||
|
@ -489,11 +555,17 @@ TEST_F(HlslGeneratorImplTest_Binary, Decl_WithLogical) {
|
||||||
auto* c = create<ast::IdentifierExpression>("c");
|
auto* c = create<ast::IdentifierExpression>("c");
|
||||||
auto* d = create<ast::IdentifierExpression>("d");
|
auto* d = create<ast::IdentifierExpression>("d");
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction,
|
auto* var = create<ast::Variable>(
|
||||||
&bool_type);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::BinaryExpression>(
|
"a", // name
|
||||||
ast::BinaryOp::kLogicalOr,
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, b, c), d));
|
&bool_type, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::BinaryExpression>(
|
||||||
|
ast::BinaryOp::kLogicalOr,
|
||||||
|
create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, b, c),
|
||||||
|
d), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement expr(var);
|
ast::VariableDeclStatement expr(var);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
|
@ -52,13 +51,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -108,13 +123,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -165,13 +196,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -222,13 +269,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -275,17 +338,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* bar_var =
|
||||||
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations(decos);
|
"bar", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
&i32, // type
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
|
false, // is_const
|
||||||
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
|
nullptr, // constructor
|
||||||
bar_var->set_decorations(decos);
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -327,17 +402,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"foo", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* bar_var =
|
||||||
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations(decos);
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
&i32, // type
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
|
false, // is_const
|
||||||
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
|
nullptr, // constructor
|
||||||
bar_var->set_decorations(decos);
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -386,15 +473,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var = create<ast::Variable>(
|
||||||
Source{}, "coord", ast::StorageClass::kInput, &vec4));
|
Source{}, // source
|
||||||
coord_var->set_decorations(
|
"coord", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&vec4, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
depth_var->set_decorations(
|
"depth", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_decoration.h"
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
@ -99,9 +98,21 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
|
||||||
|
@ -126,13 +137,29 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -179,16 +206,29 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var = create<ast::Variable>(
|
||||||
Source{}, "coord", ast::StorageClass::kInput, &vec4));
|
Source{}, // source
|
||||||
|
"coord", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&vec4, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
coord_var->set_decorations(
|
auto* depth_var = create<ast::Variable>(
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
|
Source{}, // source
|
||||||
|
"depth", // name
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
ast::StorageClass::kOutput, // storage_class
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
&f32, // type
|
||||||
depth_var->set_decorations(
|
false, // is_const
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
@ -237,23 +277,33 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kUniform, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&vec4, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("coord"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("x")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("coord"),
|
||||||
|
create<ast::IdentifierExpression>("x")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -294,27 +344,37 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
|
|
||||||
ast::type::Struct s("Uniforms", str);
|
ast::type::Struct s("Uniforms", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "uniforms", ast::StorageClass::kUniform, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"uniforms", // name
|
||||||
|
ast::StorageClass::kUniform, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
|
||||||
coord_var->set_decorations(decos);
|
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("uniforms"),
|
create<ast::MemberAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("coord")),
|
create<ast::IdentifierExpression>("uniforms"),
|
||||||
create<ast::IdentifierExpression>("x")));
|
create<ast::IdentifierExpression>("coord")),
|
||||||
|
create<ast::IdentifierExpression>("x")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -363,23 +423,33 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("coord"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("b")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("coord"),
|
||||||
|
create<ast::IdentifierExpression>("b")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -424,23 +494,33 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadOnly, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadOnly, &s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("coord"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("b")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("coord"),
|
||||||
|
create<ast::IdentifierExpression>("b")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -485,13 +565,18 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
|
@ -534,17 +619,41 @@ TEST_F(
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* val_var = create<ast::DecoratedVariable>(
|
auto* val_var =
|
||||||
create<ast::Variable>(Source{}, "val", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
val_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"val", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -555,8 +664,14 @@ TEST_F(
|
||||||
mod.AddGlobalVariable(val_var);
|
mod.AddGlobalVariable(val_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::AssignmentStatement>(
|
body->append(create<ast::AssignmentStatement>(
|
||||||
|
@ -622,21 +737,31 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
|
"depth", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kOutput, // storage_class
|
||||||
decos.push_back(
|
&f32, // type
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
|
false, // is_const
|
||||||
depth_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(depth_var);
|
mod.AddGlobalVariable(depth_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -690,15 +815,29 @@ TEST_F(
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var = create<ast::Variable>(
|
||||||
Source{}, "coord", ast::StorageClass::kInput, &vec4));
|
Source{}, // source
|
||||||
coord_var->set_decorations(
|
"coord", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&vec4, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
depth_var->set_decorations(
|
"depth", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
@ -707,8 +846,14 @@ TEST_F(
|
||||||
mod.AddGlobalVariable(depth_var);
|
mod.AddGlobalVariable(depth_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::AssignmentStatement>(
|
body->append(create<ast::AssignmentStatement>(
|
||||||
|
@ -771,21 +916,32 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kUniform, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&vec4, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -801,10 +957,15 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
expr.push_back(create<ast::ScalarConstructorExpression>(
|
expr.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.0f)));
|
create<ast::FloatLiteral>(&f32, 1.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::CallExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("sub_func"), expr));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
|
||||||
|
expr), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
body = create<ast::BlockStatement>();
|
body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -841,21 +1002,32 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &vec4);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &vec4);
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -871,10 +1043,15 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
expr.push_back(create<ast::ScalarConstructorExpression>(
|
expr.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.0f)));
|
create<ast::FloatLiteral>(&f32, 1.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::CallExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("sub_func"), expr));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
|
||||||
|
expr), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
body = create<ast::BlockStatement>();
|
body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -909,11 +1086,17 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
ast::VariableDecorationList decos;
|
"bar", // name
|
||||||
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
|
ast::StorageClass::kOutput, // storage_class
|
||||||
bar_var->set_decorations(decos);
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
mod.AddGlobalVariable(bar_var);
|
mod.AddGlobalVariable(bar_var);
|
||||||
|
@ -1041,7 +1224,13 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &ary));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&ary, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
|
||||||
|
@ -1095,13 +1284,18 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
||||||
|
|
||||||
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* data_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(0, Source{}));
|
false, // is_const
|
||||||
data_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
td.RegisterVariableForTesting(data_var);
|
td.RegisterVariableForTesting(data_var);
|
||||||
|
@ -1109,11 +1303,16 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -1130,11 +1329,16 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
|
|
@ -268,8 +268,14 @@ TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat(&f32, 3, 3);
|
ast::type::Matrix mat(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "var",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.push_back(create<ast::IdentifierExpression>("var"));
|
params.push_back(create<ast::IdentifierExpression>("var"));
|
||||||
|
|
|
@ -76,9 +76,21 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, DISABLED_Intrinsic_OuterProduct) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
|
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec2);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&vec2, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* b =
|
auto* b =
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &vec3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&vec3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.push_back(create<ast::IdentifierExpression>("a"));
|
params.push_back(create<ast::IdentifierExpression>("a"));
|
||||||
|
@ -115,8 +127,10 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
|
||||||
|
|
||||||
ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params);
|
ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params);
|
||||||
|
|
||||||
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec);
|
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec,
|
||||||
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec);
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v1);
|
td.RegisterVariableForTesting(&v1);
|
||||||
td.RegisterVariableForTesting(&v2);
|
td.RegisterVariableForTesting(&v2);
|
||||||
|
|
|
@ -144,15 +144,26 @@ TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopWithVarUsedInContinuing) {
|
||||||
|
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "lhs",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"lhs", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.4)));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.4)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
|
body->append(create<ast::VariableDeclStatement>(
|
||||||
Source{}, "other", ast::StorageClass::kFunction, &f32)));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"other", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}))); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("lhs");
|
auto* lhs = create<ast::IdentifierExpression>("lhs");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("rhs");
|
auto* rhs = create<ast::IdentifierExpression>("rhs");
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "src/ast/array_accessor_expression.h"
|
#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/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
|
@ -35,6 +34,7 @@
|
||||||
#include "src/ast/type/struct_type.h"
|
#include "src/ast/type/struct_type.h"
|
||||||
#include "src/ast/type/vector_type.h"
|
#include "src/ast/type/vector_type.h"
|
||||||
#include "src/ast/type_constructor_expression.h"
|
#include "src/ast/type_constructor_expression.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/type_determiner.h"
|
#include "src/type_determiner.h"
|
||||||
#include "src/writer/hlsl/test_helper.h"
|
#include "src/writer/hlsl/test_helper.h"
|
||||||
|
|
||||||
|
@ -57,8 +57,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
|
||||||
|
|
||||||
ast::type::Struct s("Str", strct);
|
ast::type::Struct s("Str", strct);
|
||||||
|
|
||||||
auto* str_var = create<ast::DecoratedVariable>(
|
auto* str_var =
|
||||||
create<ast::Variable>(Source{}, "str", ast::StorageClass::kPrivate, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"str", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* str = create<ast::IdentifierExpression>("str");
|
auto* str = create<ast::IdentifierExpression>("str");
|
||||||
auto* mem = create<ast::IdentifierExpression>("mem");
|
auto* mem = create<ast::IdentifierExpression>("mem");
|
||||||
|
@ -100,8 +106,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
||||||
create<ast::IdentifierExpression>("b"));
|
create<ast::IdentifierExpression>("b"));
|
||||||
|
@ -143,8 +155,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
||||||
create<ast::IdentifierExpression>("a"));
|
create<ast::IdentifierExpression>("a"));
|
||||||
|
@ -190,10 +208,22 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* b_var =
|
auto* b_var =
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kPrivate, &mat);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&mat, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* coord_var = create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::MemberAccessorExpression>(
|
auto* lhs = create<ast::MemberAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("data"),
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
@ -249,8 +279,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::MemberAccessorExpression>(
|
auto* lhs = create<ast::MemberAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("data"),
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
@ -304,8 +340,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
||||||
create<ast::IdentifierExpression>("a"));
|
create<ast::IdentifierExpression>("a"));
|
||||||
|
@ -354,8 +396,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
||||||
create<ast::IdentifierExpression>("a"));
|
create<ast::IdentifierExpression>("a"));
|
||||||
|
@ -396,8 +444,14 @@ TEST_F(
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
|
||||||
create<ast::IdentifierExpression>("a"));
|
create<ast::IdentifierExpression>("a"));
|
||||||
|
@ -442,8 +496,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(
|
ast::ArrayAccessorExpression expr(
|
||||||
create<ast::ArrayAccessorExpression>(
|
create<ast::ArrayAccessorExpression>(
|
||||||
|
@ -491,8 +551,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(
|
ast::ArrayAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -537,8 +603,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(
|
ast::ArrayAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -593,8 +665,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -641,8 +719,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -693,8 +777,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -744,8 +834,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -790,8 +886,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -868,8 +970,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct pre_struct("Pre", pre_str);
|
ast::type::Struct pre_struct("Pre", pre_str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&pre_struct, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -939,8 +1047,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct pre_struct("Pre", pre_str);
|
ast::type::Struct pre_struct("Pre", pre_str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&pre_struct, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -1011,8 +1125,14 @@ TEST_F(
|
||||||
|
|
||||||
ast::type::Struct pre_struct("Pre", pre_str);
|
ast::type::Struct pre_struct("Pre", pre_str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&pre_struct, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -1082,8 +1202,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct pre_struct("Pre", pre_str);
|
ast::type::Struct pre_struct("Pre", pre_str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&pre_struct, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -1154,8 +1280,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct pre_struct("Pre", pre_str);
|
ast::type::Struct pre_struct("Pre", pre_str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&pre_struct, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
@ -1237,8 +1369,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
|
||||||
|
|
||||||
ast::type::Struct pre_struct("Pre", pre_str);
|
ast::type::Struct pre_struct("Pre", pre_str);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
|
&pre_struct, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
gen.register_global(coord_var);
|
gen.register_global(coord_var);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
|
@ -45,10 +44,14 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
|
||||||
exprs.push_back(create<ast::ScalarConstructorExpression>(
|
exprs.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 3.0f)));
|
create<ast::FloatLiteral>(&f32, 3.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &ary);
|
Source{}, // source
|
||||||
var->set_is_const(true);
|
"pos", // name
|
||||||
var->set_constructor(create<ast::TypeConstructorExpression>(&ary, exprs));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&ary, // type
|
||||||
|
true, // is_const
|
||||||
|
create<ast::TypeConstructorExpression>(&ary, exprs), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
|
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
|
||||||
EXPECT_EQ(result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n");
|
EXPECT_EQ(result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n");
|
||||||
|
@ -57,15 +60,18 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
|
||||||
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
|
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* var = create<ast::Variable>(
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
|
Source{}, // source
|
||||||
|
"pos", // name
|
||||||
auto* var = create<ast::DecoratedVariable>(
|
ast::StorageClass::kNone, // storage_class
|
||||||
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32));
|
&f32, // type
|
||||||
var->set_decorations(decos);
|
true, // is_const
|
||||||
var->set_is_const(true);
|
create<ast::ScalarConstructorExpression>(
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
create<ast::FloatLiteral>(&f32, 3.0f)), // constructor
|
||||||
create<ast::FloatLiteral>(&f32, 3.0f)));
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(23, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
|
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
|
||||||
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
|
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
|
||||||
|
@ -79,13 +85,17 @@ static const float pos = WGSL_SPEC_CONSTANT_23;
|
||||||
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
|
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* var =
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"pos", // name
|
||||||
auto* var = create<ast::DecoratedVariable>(
|
ast::StorageClass::kNone, // storage_class
|
||||||
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32));
|
&f32, // type
|
||||||
var->set_decorations(decos);
|
true, // is_const
|
||||||
var->set_is_const(true);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(23, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
|
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
|
||||||
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
|
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
|
||||||
|
|
|
@ -35,7 +35,13 @@ using HlslGeneratorImplTest_VariableDecl = TestHelper;
|
||||||
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
|
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -47,8 +53,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
|
||||||
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
|
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_is_const(true);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
true, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -62,7 +73,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
|
||||||
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
|
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &ary);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&ary, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -75,7 +92,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
|
||||||
Emit_VariableDeclStatement_Function) {
|
Emit_VariableDeclStatement_Function) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -87,7 +110,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
|
||||||
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
|
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -102,8 +131,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
|
||||||
|
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_constructor(ident);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
ident, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();
|
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();
|
||||||
|
@ -120,8 +154,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
|
||||||
auto* zero_vec = create<ast::TypeConstructorExpression>(&vec, values);
|
auto* zero_vec = create<ast::TypeConstructorExpression>(&vec, values);
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_constructor(zero_vec);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&vec, // type
|
||||||
|
false, // is_const
|
||||||
|
zero_vec, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();
|
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();
|
||||||
|
@ -138,8 +177,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
|
||||||
auto* zero_mat = create<ast::TypeConstructorExpression>(&mat, values);
|
auto* zero_mat = create<ast::TypeConstructorExpression>(&mat, values);
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &mat);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_constructor(zero_mat);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&mat, // type
|
||||||
|
false, // is_const
|
||||||
|
zero_mat, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();
|
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
|
@ -63,6 +63,7 @@
|
||||||
#include "src/ast/type/void_type.h"
|
#include "src/ast/type/void_type.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/writer/float_to_string.h"
|
#include "src/writer/float_to_string.h"
|
||||||
|
|
||||||
|
@ -1507,13 +1508,12 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
|
bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
|
||||||
auto* decorated = var->As<ast::DecoratedVariable>();
|
|
||||||
bool in_or_out_struct_has_location =
|
bool in_or_out_struct_has_location =
|
||||||
decorated != nullptr && decorated->HasLocationDecoration() &&
|
var != nullptr && var->HasLocationDecoration() &&
|
||||||
(var->storage_class() == ast::StorageClass::kInput ||
|
(var->storage_class() == ast::StorageClass::kInput ||
|
||||||
var->storage_class() == ast::StorageClass::kOutput);
|
var->storage_class() == ast::StorageClass::kOutput);
|
||||||
bool in_struct_has_builtin =
|
bool in_struct_has_builtin =
|
||||||
decorated != nullptr && decorated->HasBuiltinDecoration() &&
|
var != nullptr && var->HasBuiltinDecoration() &&
|
||||||
var->storage_class() == ast::StorageClass::kOutput;
|
var->storage_class() == ast::StorageClass::kOutput;
|
||||||
return in_or_out_struct_has_location || in_struct_has_builtin;
|
return in_or_out_struct_has_location || in_struct_has_builtin;
|
||||||
}
|
}
|
||||||
|
@ -2013,11 +2013,10 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var, bool skip_constructor) {
|
||||||
make_indent();
|
make_indent();
|
||||||
|
|
||||||
// TODO(dsinclair): Handle variable decorations
|
// TODO(dsinclair): Handle variable decorations
|
||||||
if (var->Is<ast::DecoratedVariable>()) {
|
if (!var->decorations().empty()) {
|
||||||
error_ = "Variable decorations are not handled yet";
|
error_ = "Variable decorations are not handled yet";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var->is_const()) {
|
if (var->is_const()) {
|
||||||
out_ << "const ";
|
out_ << "const ";
|
||||||
}
|
}
|
||||||
|
@ -2051,10 +2050,11 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var, bool skip_constructor) {
|
||||||
bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
|
bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
|
||||||
make_indent();
|
make_indent();
|
||||||
|
|
||||||
auto* decorated = var->As<ast::DecoratedVariable>();
|
for (auto* d : var->decorations()) {
|
||||||
if (decorated != nullptr && !decorated->HasConstantIdDecoration()) {
|
if (!d->Is<ast::ConstantIdDecoration>()) {
|
||||||
error_ = "Decorated const values not valid";
|
error_ = "Decorated const values not valid";
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!var->is_const()) {
|
if (!var->is_const()) {
|
||||||
error_ = "Expected a const value";
|
error_ = "Expected a const value";
|
||||||
|
@ -2069,8 +2069,8 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
|
||||||
out_ << " " << var->name();
|
out_ << " " << var->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decorated != nullptr && decorated->HasConstantIdDecoration()) {
|
if (var->HasConstantIdDecoration()) {
|
||||||
out_ << " [[function_constant(" << decorated->constant_id() << ")]]";
|
out_ << " [[function_constant(" << var->constant_id() << ")]]";
|
||||||
} else if (var->constructor() != nullptr) {
|
} else if (var->constructor() != nullptr) {
|
||||||
out_ << " = ";
|
out_ << " = ";
|
||||||
if (!EmitExpression(var->constructor())) {
|
if (!EmitExpression(var->constructor())) {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
|
@ -51,13 +50,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Input) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -105,13 +120,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Output) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -159,13 +190,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Input) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -212,13 +259,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Output) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -263,17 +326,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Input) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* bar_var =
|
||||||
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations(decos);
|
"bar", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
&i32, // type
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
|
false, // is_const
|
||||||
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
|
nullptr, // constructor
|
||||||
bar_var->set_decorations(decos);
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -313,17 +388,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Output) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"foo", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* bar_var =
|
||||||
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations(decos);
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
&i32, // type
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
|
false, // is_const
|
||||||
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
|
nullptr, // constructor
|
||||||
bar_var->set_decorations(decos);
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -369,15 +456,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Builtins) {
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var = create<ast::Variable>(
|
||||||
Source{}, "coord", ast::StorageClass::kInput, &vec4));
|
Source{}, // source
|
||||||
coord_var->set_decorations(
|
"coord", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&vec4, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
depth_var->set_decorations(
|
"depth", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_decoration.h"
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
@ -106,9 +105,21 @@ TEST_F(MslGeneratorImplTest, Emit_Function_WithParams) {
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
|
||||||
|
@ -134,13 +145,29 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_WithInOutVars) {
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -190,15 +217,29 @@ TEST_F(MslGeneratorImplTest,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var = create<ast::Variable>(
|
||||||
Source{}, "coord", ast::StorageClass::kInput, &vec4));
|
Source{}, // source
|
||||||
coord_var->set_decorations(
|
"coord", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&vec4, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
depth_var->set_decorations(
|
"depth", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
@ -246,24 +287,34 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_With_Uniform) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kUniform, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&vec4, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("coord"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("x")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("coord"),
|
||||||
|
create<ast::IdentifierExpression>("x")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -312,24 +363,34 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("coord"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("b")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("coord"),
|
||||||
|
create<ast::IdentifierExpression>("b")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -382,13 +443,18 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
|
@ -396,11 +462,16 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("coord"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("b")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("coord"),
|
||||||
|
create<ast::IdentifierExpression>("b")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -438,17 +509,41 @@ TEST_F(
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* foo_var = create<ast::DecoratedVariable>(
|
auto* foo_var =
|
||||||
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"foo", // name
|
||||||
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
|
"bar", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* val_var = create<ast::DecoratedVariable>(
|
auto* val_var =
|
||||||
create<ast::Variable>(Source{}, "val", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
val_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
|
"val", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(foo_var);
|
td.RegisterVariableForTesting(foo_var);
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
|
@ -459,8 +554,14 @@ TEST_F(
|
||||||
mod.AddGlobalVariable(val_var);
|
mod.AddGlobalVariable(val_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::AssignmentStatement>(
|
body->append(create<ast::AssignmentStatement>(
|
||||||
|
@ -529,21 +630,31 @@ TEST_F(MslGeneratorImplTest,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
|
"depth", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kOutput, // storage_class
|
||||||
decos.push_back(
|
&f32, // type
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
|
false, // is_const
|
||||||
depth_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(depth_var);
|
mod.AddGlobalVariable(depth_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -601,15 +712,29 @@ TEST_F(
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var = create<ast::Variable>(
|
||||||
Source{}, "coord", ast::StorageClass::kInput, &vec4));
|
Source{}, // source
|
||||||
coord_var->set_decorations(
|
"coord", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
|
ast::StorageClass::kInput, // storage_class
|
||||||
|
&vec4, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* depth_var = create<ast::Variable>(
|
||||||
Source{}, "depth", ast::StorageClass::kOutput, &f32));
|
Source{}, // source
|
||||||
depth_var->set_decorations(
|
"depth", // name
|
||||||
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
td.RegisterVariableForTesting(depth_var);
|
td.RegisterVariableForTesting(depth_var);
|
||||||
|
@ -618,8 +743,14 @@ TEST_F(
|
||||||
mod.AddGlobalVariable(depth_var);
|
mod.AddGlobalVariable(depth_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::AssignmentStatement>(
|
body->append(create<ast::AssignmentStatement>(
|
||||||
|
@ -680,21 +811,32 @@ TEST_F(MslGeneratorImplTest,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec4(&f32, 4);
|
ast::type::Vector vec4(&f32, 4);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kUniform, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&vec4, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
|
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -710,10 +852,15 @@ TEST_F(MslGeneratorImplTest,
|
||||||
expr.push_back(create<ast::ScalarConstructorExpression>(
|
expr.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.0f)));
|
create<ast::FloatLiteral>(&f32, 1.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::CallExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("sub_func"), expr));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
|
||||||
|
expr), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
body = create<ast::BlockStatement>();
|
body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -765,20 +912,31 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -794,10 +952,15 @@ TEST_F(MslGeneratorImplTest,
|
||||||
expr.push_back(create<ast::ScalarConstructorExpression>(
|
expr.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.0f)));
|
create<ast::FloatLiteral>(&f32, 1.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::CallExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("sub_func"), expr));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
|
||||||
|
expr), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
body = create<ast::BlockStatement>();
|
body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -855,20 +1018,31 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* coord_var =
|
||||||
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"coord", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
false, // is_const
|
||||||
coord_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(coord_var);
|
td.RegisterVariableForTesting(coord_var);
|
||||||
mod.AddGlobalVariable(coord_var);
|
mod.AddGlobalVariable(coord_var);
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(create<ast::Variable>(Source{}, "param",
|
params.push_back(
|
||||||
ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"param", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -884,10 +1058,15 @@ TEST_F(MslGeneratorImplTest,
|
||||||
expr.push_back(create<ast::ScalarConstructorExpression>(
|
expr.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.0f)));
|
create<ast::FloatLiteral>(&f32, 1.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::CallExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("sub_func"), expr));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
|
||||||
|
expr), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
body = create<ast::BlockStatement>();
|
body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -929,11 +1108,17 @@ TEST_F(MslGeneratorImplTest,
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
auto* bar_var = create<ast::DecoratedVariable>(
|
auto* bar_var =
|
||||||
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
ast::VariableDecorationList decos;
|
"bar", // name
|
||||||
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
|
ast::StorageClass::kOutput, // storage_class
|
||||||
bar_var->set_decorations(decos);
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(1, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(bar_var);
|
td.RegisterVariableForTesting(bar_var);
|
||||||
mod.AddGlobalVariable(bar_var);
|
mod.AddGlobalVariable(bar_var);
|
||||||
|
@ -1015,7 +1200,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &ary));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&ary, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
|
|
||||||
|
@ -1072,13 +1263,18 @@ TEST_F(MslGeneratorImplTest,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
||||||
|
|
||||||
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* data_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(0, Source{}));
|
false, // is_const
|
||||||
data_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
|
@ -1087,11 +1283,16 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -1109,11 +1310,16 @@ TEST_F(MslGeneratorImplTest,
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
|
|
@ -267,8 +267,14 @@ TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat(&f32, 3, 3);
|
ast::type::Matrix mat(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "var",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.push_back(create<ast::IdentifierExpression>("var"));
|
params.push_back(create<ast::IdentifierExpression>("var"));
|
||||||
|
|
|
@ -71,9 +71,21 @@ TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
|
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec2);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&vec2, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* b =
|
auto* b =
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &vec3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&vec3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.push_back(create<ast::IdentifierExpression>("a"));
|
params.push_back(create<ast::IdentifierExpression>("a"));
|
||||||
|
@ -110,8 +122,10 @@ TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
|
||||||
|
|
||||||
ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params);
|
ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params);
|
||||||
|
|
||||||
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec);
|
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec,
|
||||||
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec);
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v1);
|
td.RegisterVariableForTesting(&v1);
|
||||||
td.RegisterVariableForTesting(&v2);
|
td.RegisterVariableForTesting(&v2);
|
||||||
|
|
|
@ -149,15 +149,26 @@ TEST_F(MslGeneratorImplTest, Emit_LoopWithVarUsedInContinuing) {
|
||||||
|
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "lhs",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"lhs", // name
|
||||||
create<ast::FloatLiteral>(&f32, 2.4)));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.4)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
|
body->append(create<ast::VariableDeclStatement>(
|
||||||
Source{}, "other", ast::StorageClass::kFunction, &f32)));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"other", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}))); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("lhs");
|
auto* lhs = create<ast::IdentifierExpression>("lhs");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("rhs");
|
auto* rhs = create<ast::IdentifierExpression>("rhs");
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
|
@ -47,10 +46,14 @@ TEST_F(MslGeneratorImplTest, Emit_ModuleConstant) {
|
||||||
exprs.push_back(create<ast::ScalarConstructorExpression>(
|
exprs.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 3.0f)));
|
create<ast::FloatLiteral>(&f32, 3.0f)));
|
||||||
|
|
||||||
auto* var =
|
auto* var = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &ary);
|
Source{}, // source
|
||||||
var->set_is_const(true);
|
"pos", // name
|
||||||
var->set_constructor(create<ast::TypeConstructorExpression>(&ary, exprs));
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&ary, // type
|
||||||
|
true, // is_const
|
||||||
|
create<ast::TypeConstructorExpression>(&ary, exprs), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
|
ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
|
||||||
EXPECT_EQ(gen.result(), "constant float pos[3] = {1.0f, 2.0f, 3.0f};\n");
|
EXPECT_EQ(gen.result(), "constant float pos[3] = {1.0f, 2.0f, 3.0f};\n");
|
||||||
|
@ -59,15 +62,18 @@ TEST_F(MslGeneratorImplTest, Emit_ModuleConstant) {
|
||||||
TEST_F(MslGeneratorImplTest, Emit_SpecConstant) {
|
TEST_F(MslGeneratorImplTest, Emit_SpecConstant) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* var = create<ast::Variable>(
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
|
Source{}, // source
|
||||||
|
"pos", // name
|
||||||
auto* var = create<ast::DecoratedVariable>(
|
ast::StorageClass::kNone, // storage_class
|
||||||
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32));
|
&f32, // type
|
||||||
var->set_decorations(decos);
|
true, // is_const
|
||||||
var->set_is_const(true);
|
create<ast::ScalarConstructorExpression>(
|
||||||
var->set_constructor(create<ast::ScalarConstructorExpression>(
|
create<ast::FloatLiteral>(&f32, 3.0f)), // constructor
|
||||||
create<ast::FloatLiteral>(&f32, 3.0f)));
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(23, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
|
ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
|
||||||
EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");
|
EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");
|
||||||
|
|
|
@ -43,7 +43,13 @@ using MslGeneratorImplTest = TestHelper;
|
||||||
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
|
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -56,8 +62,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
|
||||||
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
|
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_is_const(true);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
true, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -72,7 +83,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) {
|
||||||
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
|
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &ary);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&ary, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -98,7 +115,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
|
||||||
ast::type::Struct s("S", str);
|
ast::type::Struct s("S", str);
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &s);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&s, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -114,7 +137,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) {
|
||||||
ast::type::Vector vec(&f32, 2);
|
ast::type::Vector vec(&f32, 2);
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &vec);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&vec, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -128,7 +157,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat(&f32, 2, 3);
|
ast::type::Matrix mat(&f32, 2, 3);
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &mat);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -141,7 +176,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
|
||||||
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
|
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -156,8 +197,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {
|
||||||
|
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_constructor(ident);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
ident, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -174,8 +220,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_ZeroVec) {
|
||||||
auto* zero_vec = create<ast::TypeConstructorExpression>(&vec, values);
|
auto* zero_vec = create<ast::TypeConstructorExpression>(&vec, values);
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec);
|
create<ast::Variable>(Source{}, // source
|
||||||
var->set_constructor(zero_vec);
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&vec, // type
|
||||||
|
false, // is_const
|
||||||
|
zero_vec, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/constructor_expression.h"
|
#include "src/ast/constructor_expression.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
|
@ -72,6 +71,7 @@
|
||||||
#include "src/ast/type_constructor_expression.h"
|
#include "src/ast/type_constructor_expression.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/writer/append_vector.h"
|
#include "src/writer/append_vector.h"
|
||||||
|
|
||||||
|
@ -739,8 +739,7 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
|
||||||
// one
|
// one
|
||||||
// 2- If we don't have a constructor and we're an Output or Private variable
|
// 2- If we don't have a constructor and we're an Output or Private variable
|
||||||
// then WGSL requires an initializer.
|
// then WGSL requires an initializer.
|
||||||
auto* decorated = var->As<ast::DecoratedVariable>();
|
if (var->HasConstantIdDecoration()) {
|
||||||
if (decorated != nullptr && decorated->HasConstantIdDecoration()) {
|
|
||||||
if (type->Is<ast::type::F32>()) {
|
if (type->Is<ast::type::F32>()) {
|
||||||
ast::FloatLiteral l(type, 0.0f);
|
ast::FloatLiteral l(type, 0.0f);
|
||||||
init_id = GenerateLiteralIfNeeded(var, &l);
|
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||||
|
@ -775,33 +774,31 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
|
||||||
|
|
||||||
push_type(spv::Op::OpVariable, std::move(ops));
|
push_type(spv::Op::OpVariable, std::move(ops));
|
||||||
|
|
||||||
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
|
for (auto* deco : var->decorations()) {
|
||||||
for (auto* deco : decorated->decorations()) {
|
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
|
||||||
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
|
push_annot(spv::Op::OpDecorate,
|
||||||
push_annot(spv::Op::OpDecorate,
|
{Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
|
||||||
{Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
|
Operand::Int(ConvertBuiltin(builtin->value()))});
|
||||||
Operand::Int(ConvertBuiltin(builtin->value()))});
|
} else if (auto* location = deco->As<ast::LocationDecoration>()) {
|
||||||
} else if (auto* location = deco->As<ast::LocationDecoration>()) {
|
push_annot(spv::Op::OpDecorate,
|
||||||
push_annot(spv::Op::OpDecorate,
|
{Operand::Int(var_id), Operand::Int(SpvDecorationLocation),
|
||||||
{Operand::Int(var_id), Operand::Int(SpvDecorationLocation),
|
Operand::Int(location->value())});
|
||||||
Operand::Int(location->value())});
|
} else if (auto* binding = deco->As<ast::BindingDecoration>()) {
|
||||||
} else if (auto* binding = deco->As<ast::BindingDecoration>()) {
|
push_annot(spv::Op::OpDecorate,
|
||||||
push_annot(spv::Op::OpDecorate,
|
{Operand::Int(var_id), Operand::Int(SpvDecorationBinding),
|
||||||
{Operand::Int(var_id), Operand::Int(SpvDecorationBinding),
|
Operand::Int(binding->value())});
|
||||||
Operand::Int(binding->value())});
|
} else if (auto* set = deco->As<ast::SetDecoration>()) {
|
||||||
} else if (auto* set = deco->As<ast::SetDecoration>()) {
|
push_annot(spv::Op::OpDecorate, {Operand::Int(var_id),
|
||||||
push_annot(
|
Operand::Int(SpvDecorationDescriptorSet),
|
||||||
spv::Op::OpDecorate,
|
Operand::Int(set->value())});
|
||||||
{Operand::Int(var_id), Operand::Int(SpvDecorationDescriptorSet),
|
} else if (deco->Is<ast::ConstantIdDecoration>()) {
|
||||||
Operand::Int(set->value())});
|
// Spec constants are handled elsewhere
|
||||||
} else if (deco->Is<ast::ConstantIdDecoration>()) {
|
} else {
|
||||||
// Spec constants are handled elsewhere
|
error_ = "unknown decoration";
|
||||||
} else {
|
return false;
|
||||||
error_ = "unknown decoration";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope_stack_.set_global(var->name(), var_id);
|
scope_stack_.set_global(var->name(), var_id);
|
||||||
spirv_id_to_variable_[var_id] = var;
|
spirv_id_to_variable_[var_id] = var;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1455,8 +1452,7 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Variable* var,
|
||||||
|
|
||||||
auto name = lit->name();
|
auto name = lit->name();
|
||||||
bool is_spec_constant = false;
|
bool is_spec_constant = false;
|
||||||
if (var && var->Is<ast::DecoratedVariable>() &&
|
if (var && var->HasConstantIdDecoration()) {
|
||||||
var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
|
|
||||||
name = "__spec" + name;
|
name = "__spec" + name;
|
||||||
is_spec_constant = true;
|
is_spec_constant = true;
|
||||||
}
|
}
|
||||||
|
@ -1470,10 +1466,9 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Variable* var,
|
||||||
auto result_id = result.to_i();
|
auto result_id = result.to_i();
|
||||||
|
|
||||||
if (is_spec_constant) {
|
if (is_spec_constant) {
|
||||||
push_annot(
|
push_annot(spv::Op::OpDecorate,
|
||||||
spv::Op::OpDecorate,
|
{Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
|
||||||
{Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
|
Operand::Int(var->constant_id())});
|
||||||
Operand::Int(var->As<ast::DecoratedVariable>()->constant_id())});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* l = lit->As<ast::BoolLiteral>()) {
|
if (auto* l = lit->As<ast::BoolLiteral>()) {
|
||||||
|
|
|
@ -53,7 +53,8 @@ TEST_F(BuilderTest, ArrayAccessor) {
|
||||||
// vec3<f32> ary;
|
// vec3<f32> ary;
|
||||||
// ary[1] -> ptr<f32>
|
// ary[1] -> ptr<f32>
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ary = create<ast::IdentifierExpression>("ary");
|
auto* ary = create<ast::IdentifierExpression>("ary");
|
||||||
auto* idx_expr = create<ast::ScalarConstructorExpression>(
|
auto* idx_expr = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -94,8 +95,10 @@ TEST_F(BuilderTest, Accessor_Array_LoadIndex) {
|
||||||
// idx : i32;
|
// idx : i32;
|
||||||
// ary[idx] -> ptr<f32>
|
// ary[idx] -> ptr<f32>
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
|
||||||
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32);
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ary = create<ast::IdentifierExpression>("ary");
|
auto* ary = create<ast::IdentifierExpression>("ary");
|
||||||
auto* idx_expr = create<ast::IdentifierExpression>("idx");
|
auto* idx_expr = create<ast::IdentifierExpression>("idx");
|
||||||
|
@ -139,7 +142,8 @@ TEST_F(BuilderTest, ArrayAccessor_Dynamic) {
|
||||||
// vec3<f32> ary;
|
// vec3<f32> ary;
|
||||||
// ary[1 + 2] -> ptr<f32>
|
// ary[1 + 2] -> ptr<f32>
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ary = create<ast::IdentifierExpression>("ary");
|
auto* ary = create<ast::IdentifierExpression>("ary");
|
||||||
|
|
||||||
|
@ -186,7 +190,8 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
|
||||||
// ary = array<vec3<f32>, 4>
|
// ary = array<vec3<f32>, 4>
|
||||||
// ary[3][2];
|
// ary[3][2];
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4);
|
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(
|
ast::ArrayAccessorExpression expr(
|
||||||
create<ast::ArrayAccessorExpression>(
|
create<ast::ArrayAccessorExpression>(
|
||||||
|
@ -233,7 +238,8 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
|
||||||
// var a : array<vec3<f32>, 4>;
|
// var a : array<vec3<f32>, 4>;
|
||||||
// a[2].xy;
|
// a[2].xy;
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4);
|
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(
|
ast::MemberAccessorExpression expr(
|
||||||
create<ast::ArrayAccessorExpression>(
|
create<ast::ArrayAccessorExpression>(
|
||||||
|
@ -289,7 +295,8 @@ TEST_F(BuilderTest, MemberAccessor) {
|
||||||
auto* s = create<ast::Struct>(members);
|
auto* s = create<ast::Struct>(members);
|
||||||
ast::type::Struct s_type("my_struct", s);
|
ast::type::Struct s_type("my_struct", s);
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
|
||||||
create<ast::IdentifierExpression>("b"));
|
create<ast::IdentifierExpression>("b"));
|
||||||
|
@ -343,7 +350,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
|
||||||
|
|
||||||
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
|
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(
|
ast::MemberAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -403,7 +411,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
|
||||||
|
|
||||||
ast::type::Struct s_type("Outer", create<ast::Struct>(outer_members));
|
ast::type::Struct s_type("Outer", create<ast::Struct>(outer_members));
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(
|
ast::MemberAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -462,7 +471,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
|
||||||
|
|
||||||
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
|
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* lhs = create<ast::MemberAccessorExpression>(
|
auto* lhs = create<ast::MemberAccessorExpression>(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -528,8 +538,10 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
|
||||||
|
|
||||||
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
|
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
|
||||||
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32);
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("store");
|
auto* lhs = create<ast::IdentifierExpression>("store");
|
||||||
|
|
||||||
|
@ -578,7 +590,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
|
||||||
|
|
||||||
// ident.y
|
// ident.y
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
|
||||||
create<ast::IdentifierExpression>("y"));
|
create<ast::IdentifierExpression>("y"));
|
||||||
|
@ -613,7 +626,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
|
||||||
|
|
||||||
// ident.yx
|
// ident.yx
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
|
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
|
||||||
create<ast::IdentifierExpression>("yx"));
|
create<ast::IdentifierExpression>("yx"));
|
||||||
|
@ -647,7 +661,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
|
||||||
|
|
||||||
// ident.yxz.xz
|
// ident.yxz.xz
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(
|
ast::MemberAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -685,7 +700,8 @@ TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
|
||||||
|
|
||||||
// ident.yxz.x
|
// ident.yxz.x
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(
|
ast::MemberAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -723,7 +739,8 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
|
||||||
|
|
||||||
// index.yxz[1]
|
// index.yxz[1]
|
||||||
|
|
||||||
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3);
|
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(
|
ast::ArrayAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -793,7 +810,7 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
|
||||||
ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{});
|
ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{});
|
||||||
|
|
||||||
ast::Variable var(Source{}, "index", ast::StorageClass::kFunction,
|
ast::Variable var(Source{}, "index", ast::StorageClass::kFunction,
|
||||||
&a_ary_type);
|
&a_ary_type, false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::MemberAccessorExpression expr(
|
ast::MemberAccessorExpression expr(
|
||||||
create<ast::MemberAccessorExpression>(
|
create<ast::MemberAccessorExpression>(
|
||||||
|
@ -885,9 +902,9 @@ TEST_F(BuilderTest, Accessor_Array_Of_Vec) {
|
||||||
create<ast::FloatLiteral>(&f32, -0.5)),
|
create<ast::FloatLiteral>(&f32, -0.5)),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &arr);
|
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &arr, true,
|
||||||
var.set_is_const(true);
|
create<ast::TypeConstructorExpression>(&arr, ary_params),
|
||||||
var.set_constructor(create<ast::TypeConstructorExpression>(&arr, ary_params));
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
|
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
|
||||||
create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -941,10 +958,10 @@ TEST_F(BuilderTest, Accessor_Const_Vec) {
|
||||||
vec_params.push_back(create<ast::ScalarConstructorExpression>(
|
vec_params.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 0.5)));
|
create<ast::FloatLiteral>(&f32, 0.5)));
|
||||||
|
|
||||||
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &vec);
|
ast::Variable var(
|
||||||
var.set_is_const(true);
|
Source{}, "pos", ast::StorageClass::kPrivate, &vec, true,
|
||||||
var.set_constructor(
|
create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)),
|
||||||
create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
|
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
|
||||||
create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
|
|
@ -44,7 +44,8 @@ using BuilderTest = TestHelper;
|
||||||
TEST_F(BuilderTest, Assign_Var) {
|
TEST_F(BuilderTest, Assign_Var) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ident = create<ast::IdentifierExpression>("var");
|
auto* ident = create<ast::IdentifierExpression>("var");
|
||||||
auto* val = create<ast::ScalarConstructorExpression>(
|
auto* val = create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -78,7 +79,8 @@ TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec(&f32, 3);
|
ast::type::Vector vec(&f32, 3);
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ident = create<ast::IdentifierExpression>("var");
|
auto* ident = create<ast::IdentifierExpression>("var");
|
||||||
ast::ExpressionList vals;
|
ast::ExpressionList vals;
|
||||||
|
@ -128,7 +130,8 @@ TEST_F(BuilderTest, Assign_Var_Complex_ConstructorWithExtract) {
|
||||||
create<ast::FloatLiteral>(&f32, 3.0f)),
|
create<ast::FloatLiteral>(&f32, 3.0f)),
|
||||||
});
|
});
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
|
ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
|
||||||
init);
|
init);
|
||||||
|
@ -176,7 +179,8 @@ TEST_F(BuilderTest, Assign_Var_Complex_Constructor) {
|
||||||
|
|
||||||
auto* init = create<ast::TypeConstructorExpression>(&vec3, vals);
|
auto* init = create<ast::TypeConstructorExpression>(&vec3, vals);
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
|
ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
|
||||||
init);
|
init);
|
||||||
|
@ -223,7 +227,8 @@ TEST_F(BuilderTest, Assign_StructMember) {
|
||||||
auto* s = create<ast::Struct>(members);
|
auto* s = create<ast::Struct>(members);
|
||||||
ast::type::Struct s_type("my_struct", s);
|
ast::type::Struct s_type("my_struct", s);
|
||||||
|
|
||||||
ast::Variable v(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
|
ast::Variable v(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ident = create<ast::MemberAccessorExpression>(
|
auto* ident = create<ast::MemberAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("ident"),
|
create<ast::IdentifierExpression>("ident"),
|
||||||
|
@ -265,7 +270,8 @@ TEST_F(BuilderTest, Assign_Vector) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ident = create<ast::IdentifierExpression>("var");
|
auto* ident = create<ast::IdentifierExpression>("var");
|
||||||
|
|
||||||
|
@ -312,7 +318,8 @@ TEST_F(BuilderTest, Assign_Vector_MemberByName) {
|
||||||
|
|
||||||
// var.y = 1
|
// var.y = 1
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ident = create<ast::MemberAccessorExpression>(
|
auto* ident = create<ast::MemberAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("var"),
|
create<ast::IdentifierExpression>("var"),
|
||||||
|
@ -357,7 +364,8 @@ TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
|
||||||
|
|
||||||
// var[1] = 1
|
// var[1] = 1
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* ident = create<ast::ArrayAccessorExpression>(
|
auto* ident = create<ast::ArrayAccessorExpression>(
|
||||||
create<ast::IdentifierExpression>("var"),
|
create<ast::IdentifierExpression>("var"),
|
||||||
|
|
|
@ -121,7 +121,8 @@ TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) {
|
||||||
|
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &i32);
|
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &i32,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("param");
|
auto* lhs = create<ast::IdentifierExpression>("param");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("param");
|
auto* rhs = create<ast::IdentifierExpression>("param");
|
||||||
|
@ -633,8 +634,14 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixScalar) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("mat");
|
auto* lhs = create<ast::IdentifierExpression>("mat");
|
||||||
auto* rhs = create<ast::ScalarConstructorExpression>(
|
auto* rhs = create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.f));
|
create<ast::FloatLiteral>(&f32, 1.f));
|
||||||
|
@ -666,8 +673,14 @@ TEST_F(BuilderTest, Binary_Multiply_ScalarMatrix) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::ScalarConstructorExpression>(
|
auto* lhs = create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.f));
|
create<ast::FloatLiteral>(&f32, 1.f));
|
||||||
auto* rhs = create<ast::IdentifierExpression>("mat");
|
auto* rhs = create<ast::IdentifierExpression>("mat");
|
||||||
|
@ -700,8 +713,14 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixVector) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("mat");
|
auto* lhs = create<ast::IdentifierExpression>("mat");
|
||||||
|
|
||||||
ast::ExpressionList vals;
|
ast::ExpressionList vals;
|
||||||
|
@ -742,8 +761,14 @@ TEST_F(BuilderTest, Binary_Multiply_VectorMatrix) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::ExpressionList vals;
|
ast::ExpressionList vals;
|
||||||
vals.push_back(create<ast::ScalarConstructorExpression>(
|
vals.push_back(create<ast::ScalarConstructorExpression>(
|
||||||
|
@ -785,8 +810,14 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixMatrix) {
|
||||||
ast::type::Vector vec3(&f32, 3);
|
ast::type::Vector vec3(&f32, 3);
|
||||||
ast::type::Matrix mat3(&f32, 3, 3);
|
ast::type::Matrix mat3(&f32, 3, 3);
|
||||||
|
|
||||||
auto* var = create<ast::Variable>(Source{}, "mat",
|
auto* var =
|
||||||
ast::StorageClass::kFunction, &mat3);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"mat", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&mat3, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* lhs = create<ast::IdentifierExpression>("mat");
|
auto* lhs = create<ast::IdentifierExpression>("mat");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("mat");
|
auto* rhs = create<ast::IdentifierExpression>("mat");
|
||||||
|
|
||||||
|
@ -861,14 +892,24 @@ OpBranch %7
|
||||||
TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
|
TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
|
|
||||||
auto* a_var = create<ast::Variable>(Source{}, "a",
|
auto* a_var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &bool_type);
|
Source{}, // source
|
||||||
a_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::BoolLiteral>(&bool_type, true)));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
auto* b_var = create<ast::Variable>(Source{}, "b",
|
&bool_type, // type
|
||||||
ast::StorageClass::kFunction, &bool_type);
|
false, // is_const
|
||||||
b_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::BoolLiteral>(&bool_type, false)));
|
create<ast::BoolLiteral>(&bool_type, true)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* b_var = create<ast::Variable>(
|
||||||
|
Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&bool_type, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::BoolLiteral>(&bool_type, false)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("b");
|
auto* rhs = create<ast::IdentifierExpression>("b");
|
||||||
|
@ -1047,14 +1088,24 @@ OpBranch %7
|
||||||
TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
|
TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
|
|
||||||
auto* a_var = create<ast::Variable>(Source{}, "a",
|
auto* a_var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &bool_type);
|
Source{}, // source
|
||||||
a_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
"a", // name
|
||||||
create<ast::BoolLiteral>(&bool_type, true)));
|
ast::StorageClass::kFunction, // storage_class
|
||||||
auto* b_var = create<ast::Variable>(Source{}, "b",
|
&bool_type, // type
|
||||||
ast::StorageClass::kFunction, &bool_type);
|
false, // is_const
|
||||||
b_var->set_constructor(create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::BoolLiteral>(&bool_type, false)));
|
create<ast::BoolLiteral>(&bool_type, true)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* b_var = create<ast::Variable>(
|
||||||
|
Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&bool_type, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::BoolLiteral>(&bool_type, false)), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>("a");
|
auto* lhs = create<ast::IdentifierExpression>("a");
|
||||||
auto* rhs = create<ast::IdentifierExpression>("b");
|
auto* rhs = create<ast::IdentifierExpression>("b");
|
||||||
|
|
|
@ -41,16 +41,28 @@ TEST_F(BuilderTest, Block) {
|
||||||
// serves to prove the block code is pushing new scopes as needed.
|
// serves to prove the block code is pushing new scopes as needed.
|
||||||
ast::BlockStatement outer;
|
ast::BlockStatement outer;
|
||||||
|
|
||||||
outer.append(create<ast::VariableDeclStatement>(create<ast::Variable>(
|
outer.append(create<ast::VariableDeclStatement>(
|
||||||
Source{}, "var", ast::StorageClass::kFunction, &f32)));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}))); // decorations
|
||||||
outer.append(create<ast::AssignmentStatement>(
|
outer.append(create<ast::AssignmentStatement>(
|
||||||
create<ast::IdentifierExpression>("var"),
|
create<ast::IdentifierExpression>("var"),
|
||||||
create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::FloatLiteral>(&f32, 1.0f))));
|
create<ast::FloatLiteral>(&f32, 1.0f))));
|
||||||
|
|
||||||
auto* inner = create<ast::BlockStatement>();
|
auto* inner = create<ast::BlockStatement>();
|
||||||
inner->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
|
inner->append(create<ast::VariableDeclStatement>(
|
||||||
Source{}, "var", ast::StorageClass::kFunction, &f32)));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}))); // decorations
|
||||||
inner->append(create<ast::AssignmentStatement>(
|
inner->append(create<ast::AssignmentStatement>(
|
||||||
create<ast::IdentifierExpression>("var"),
|
create<ast::IdentifierExpression>("var"),
|
||||||
create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
|
|
@ -44,9 +44,21 @@ TEST_F(BuilderTest, Expression_Call) {
|
||||||
|
|
||||||
ast::VariableList func_params;
|
ast::VariableList func_params;
|
||||||
func_params.push_back(
|
func_params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
func_params.push_back(
|
func_params.push_back(
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -109,9 +121,21 @@ TEST_F(BuilderTest, Statement_Call) {
|
||||||
|
|
||||||
ast::VariableList func_params;
|
ast::VariableList func_params;
|
||||||
func_params.push_back(
|
func_params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
func_params.push_back(
|
func_params.push_back(
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kFunction, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
|
|
@ -103,11 +103,29 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUnusedInterfaceIds) {
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* v_in =
|
auto* v_in =
|
||||||
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
auto* v_out = create<ast::Variable>(Source{}, "my_out",
|
"my_in", // name
|
||||||
ast::StorageClass::kOutput, &f32);
|
ast::StorageClass::kInput, // storage_class
|
||||||
auto* v_wg = create<ast::Variable>(Source{}, "my_wg",
|
&f32, // type
|
||||||
ast::StorageClass::kWorkgroup, &f32);
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* v_out =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"my_out", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* v_wg =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"my_wg", // name
|
||||||
|
ast::StorageClass::kWorkgroup, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
|
||||||
|
@ -162,11 +180,29 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* v_in =
|
auto* v_in =
|
||||||
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
auto* v_out = create<ast::Variable>(Source{}, "my_out",
|
"my_in", // name
|
||||||
ast::StorageClass::kOutput, &f32);
|
ast::StorageClass::kInput, // storage_class
|
||||||
auto* v_wg = create<ast::Variable>(Source{}, "my_wg",
|
&f32, // type
|
||||||
ast::StorageClass::kWorkgroup, &f32);
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* v_out =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"my_out", // name
|
||||||
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
auto* v_wg =
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"my_wg", // name
|
||||||
|
ast::StorageClass::kWorkgroup, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
td.RegisterVariableForTesting(v_in);
|
td.RegisterVariableForTesting(v_in);
|
||||||
td.RegisterVariableForTesting(v_out);
|
td.RegisterVariableForTesting(v_out);
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "spirv/unified1/spirv.h"
|
#include "spirv/unified1/spirv.h"
|
||||||
#include "spirv/unified1/spirv.hpp11"
|
#include "spirv/unified1/spirv.hpp11"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
@ -88,7 +87,13 @@ TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
auto* var_a =
|
auto* var_a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
td.RegisterVariableForTesting(var_a);
|
td.RegisterVariableForTesting(var_a);
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
|
@ -142,15 +147,23 @@ TEST_F(BuilderTest, Function_WithParams) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
ast::VariableList params;
|
ast::VariableList params = {
|
||||||
auto* var_a =
|
create<ast::Variable>(Source{}, // source
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32);
|
"a", // name
|
||||||
var_a->set_is_const(true);
|
ast::StorageClass::kFunction, // storage_class
|
||||||
params.push_back(var_a);
|
&f32, // type
|
||||||
auto* var_b =
|
true, // is_const
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kFunction, &i32);
|
nullptr, // constructor
|
||||||
var_b->set_is_const(true);
|
ast::VariableDecorationList{}), // decorations
|
||||||
params.push_back(var_b);
|
|
||||||
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
true, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}), // decorations
|
||||||
|
};
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::ReturnStatement>(
|
body->append(create<ast::ReturnStatement>(
|
||||||
|
@ -259,13 +272,18 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
||||||
|
|
||||||
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* data_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(0, Source{}));
|
false, // is_const
|
||||||
data_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
mod->AddConstructedType(&s);
|
mod->AddConstructedType(&s);
|
||||||
|
|
||||||
|
@ -274,11 +292,16 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -296,11 +319,16 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_decoration.h"
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
|
@ -47,7 +46,8 @@ using BuilderTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
|
TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
b.push_function(Function{});
|
b.push_function(Function{});
|
||||||
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
|
||||||
|
@ -80,8 +80,8 @@ TEST_F(BuilderTest, FunctionVar_WithConstantConstructor) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
|
||||||
v.set_constructor(init);
|
init, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructor) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kFunction, &vec);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kFunction, &vec, false,
|
||||||
v.set_constructor(init);
|
init, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
b.push_function(Function{});
|
b.push_function(Function{});
|
||||||
|
@ -164,12 +164,13 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructorLoadedFromVar) {
|
||||||
|
|
||||||
ASSERT_TRUE(td.DetermineResultType(init)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32, false,
|
||||||
v.set_constructor(init);
|
init, ast::VariableDecorationList{});
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32);
|
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32, false,
|
||||||
v2.set_constructor(create<ast::IdentifierExpression>("v"));
|
create<ast::IdentifierExpression>("v"),
|
||||||
|
ast::VariableDecorationList{});
|
||||||
td.RegisterVariableForTesting(&v2);
|
td.RegisterVariableForTesting(&v2);
|
||||||
|
|
||||||
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error();
|
||||||
|
@ -209,13 +210,13 @@ TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32);
|
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32, false,
|
||||||
v.set_constructor(init);
|
init, ast::VariableDecorationList{});
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32);
|
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32, true,
|
||||||
v2.set_is_const(true);
|
create<ast::IdentifierExpression>("v"),
|
||||||
v2.set_constructor(create<ast::IdentifierExpression>("v"));
|
ast::VariableDecorationList{});
|
||||||
td.RegisterVariableForTesting(&v2);
|
td.RegisterVariableForTesting(&v2);
|
||||||
|
|
||||||
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error();
|
||||||
|
@ -257,9 +258,8 @@ TEST_F(BuilderTest, FunctionVar_Const) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
|
||||||
v.set_constructor(init);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
@ -52,7 +51,8 @@ using BuilderTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
|
TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
@ -66,7 +66,8 @@ TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
|
||||||
|
|
||||||
TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
|
TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
@ -80,7 +81,8 @@ TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
|
||||||
|
|
||||||
TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
|
TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kInput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kInput, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
@ -107,8 +109,9 @@ TEST_F(BuilderTest, GlobalVar_WithConstructor) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
|
||||||
v.set_constructor(init);
|
init, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
@ -142,9 +145,8 @@ TEST_F(BuilderTest, GlobalVar_Const) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
|
||||||
v.set_constructor(init);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
@ -175,9 +177,8 @@ TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
|
||||||
v.set_constructor(init);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
@ -214,9 +215,8 @@ TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
|
||||||
v.set_constructor(init);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
@ -241,14 +241,18 @@ TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) {
|
||||||
TEST_F(BuilderTest, GlobalVar_WithLocation) {
|
TEST_F(BuilderTest, GlobalVar_WithLocation) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
ast::VariableDecorationList decos;
|
"var", // name
|
||||||
decos.push_back(create<ast::LocationDecoration>(5, Source{}));
|
ast::StorageClass::kOutput, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::LocationDecoration>(5, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable dv(v);
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Location 5
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Location 5
|
||||||
|
@ -263,15 +267,19 @@ TEST_F(BuilderTest, GlobalVar_WithLocation) {
|
||||||
TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) {
|
TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
ast::VariableDecorationList decos;
|
"var", // name
|
||||||
decos.push_back(create<ast::BindingDecoration>(2, Source{}));
|
ast::StorageClass::kOutput, // storage_class
|
||||||
decos.push_back(create<ast::SetDecoration>(3, Source{}));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(2, Source{}),
|
||||||
|
create<ast::SetDecoration>(3, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable dv(v);
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Binding 2
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Binding 2
|
||||||
|
@ -286,16 +294,19 @@ OpDecorate %1 DescriptorSet 3
|
||||||
|
|
||||||
TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
|
TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* v =
|
auto* v = create<ast::Variable>(
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
Source{}, // source
|
||||||
ast::VariableDecorationList decos;
|
"var", // name
|
||||||
decos.push_back(
|
ast::StorageClass::kOutput, // storage_class
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable dv(v);
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 BuiltIn Position
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 BuiltIn Position
|
||||||
|
@ -310,16 +321,20 @@ TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) {
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* v = create<ast::Variable>(
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(1200, Source{}));
|
Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&bool_type, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::BoolLiteral>(&bool_type, true)), // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(1200, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable v(create<ast::Variable>(
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
Source{}, "var", ast::StorageClass::kNone, &bool_type));
|
|
||||||
v.set_decorations(decos);
|
|
||||||
v.set_constructor(create<ast::ScalarConstructorExpression>(
|
|
||||||
create<ast::BoolLiteral>(&bool_type, true)));
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %2 SpecId 1200
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %2 SpecId 1200
|
||||||
|
@ -334,14 +349,19 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) {
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* v = create<ast::Variable>(
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(1200, Source{}));
|
Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&bool_type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(1200, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable v(create<ast::Variable>(
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
Source{}, "var", ast::StorageClass::kNone, &bool_type));
|
|
||||||
v.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 1200
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 1200
|
||||||
|
@ -356,16 +376,20 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* v = create<ast::Variable>(
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
|
Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
create<ast::FloatLiteral>(&f32, 2.0)), // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable v(
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &f32));
|
|
||||||
v.set_decorations(decos);
|
|
||||||
v.set_constructor(create<ast::ScalarConstructorExpression>(
|
|
||||||
create<ast::FloatLiteral>(&f32, 2.0)));
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %2 SpecId 0
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %2 SpecId 0
|
||||||
|
@ -380,14 +404,19 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* v =
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable v(
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &f32));
|
|
||||||
v.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
||||||
|
@ -402,14 +431,19 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) {
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) {
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* v =
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable v(
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &i32));
|
|
||||||
v.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
||||||
|
@ -424,14 +458,19 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) {
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_U32_NoConstructor) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_U32_NoConstructor) {
|
||||||
ast::type::U32 u32;
|
ast::type::U32 u32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
auto* v =
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"var", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&u32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::ConstantIdDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable v(
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &u32));
|
|
||||||
v.set_decorations(decos);
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
||||||
|
@ -493,7 +532,8 @@ TEST_F(BuilderTest, GlobalVar_DeclReadOnly) {
|
||||||
ast::type::Struct A("A", create<ast::Struct>(members));
|
ast::type::Struct A("A", create<ast::Struct>(members));
|
||||||
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A};
|
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A};
|
||||||
|
|
||||||
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac);
|
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
||||||
|
|
||||||
|
@ -529,7 +569,8 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) {
|
||||||
ast::type::Alias B("B", &A);
|
ast::type::Alias B("B", &A);
|
||||||
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &B};
|
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &B};
|
||||||
|
|
||||||
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac);
|
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
||||||
|
|
||||||
|
@ -563,7 +604,8 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) {
|
||||||
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A};
|
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A};
|
||||||
ast::type::Alias B("B", &ac);
|
ast::type::Alias B("B", &ac);
|
||||||
|
|
||||||
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &B);
|
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &B, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
||||||
|
|
||||||
|
@ -597,8 +639,10 @@ TEST_F(BuilderTest, GlobalVar_TwoVarDeclReadOnly) {
|
||||||
ast::type::AccessControl read{ast::AccessControl::kReadOnly, &A};
|
ast::type::AccessControl read{ast::AccessControl::kReadOnly, &A};
|
||||||
ast::type::AccessControl rw{ast::AccessControl::kReadWrite, &A};
|
ast::type::AccessControl rw{ast::AccessControl::kReadWrite, &A};
|
||||||
|
|
||||||
ast::Variable var_b(Source{}, "b", ast::StorageClass::kStorageBuffer, &read);
|
ast::Variable var_b(Source{}, "b", ast::StorageClass::kStorageBuffer, &read,
|
||||||
ast::Variable var_c(Source{}, "c", ast::StorageClass::kStorageBuffer, &rw);
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
ast::Variable var_c(Source{}, "c", ast::StorageClass::kStorageBuffer, &rw,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var_b)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var_b)) << b.error();
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var_c)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var_c)) << b.error();
|
||||||
|
@ -629,8 +673,8 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) {
|
||||||
ast::type::ImageFormat::kR32Uint);
|
ast::type::ImageFormat::kR32Uint);
|
||||||
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
|
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
|
||||||
|
|
||||||
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant,
|
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant, &type,
|
||||||
&type);
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
|
||||||
|
|
||||||
|
@ -650,8 +694,8 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) {
|
||||||
ast::type::ImageFormat::kR32Uint);
|
ast::type::ImageFormat::kR32Uint);
|
||||||
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
|
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
|
||||||
|
|
||||||
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant,
|
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant, &type,
|
||||||
&type);
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,8 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
|
||||||
v.set_constructor(init);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
|
@ -77,7 +76,8 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
|
||||||
|
|
||||||
TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
|
TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
|
@ -112,9 +112,8 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionConst) {
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
||||||
|
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
|
||||||
v.set_constructor(init);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
|
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
|
||||||
|
@ -134,7 +133,8 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionConst) {
|
||||||
|
|
||||||
TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
|
TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&v);
|
td.RegisterVariableForTesting(&v);
|
||||||
|
|
||||||
|
@ -160,7 +160,8 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
|
||||||
TEST_F(BuilderTest, IdentifierExpression_Load) {
|
TEST_F(BuilderTest, IdentifierExpression_Load) {
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
ast::Variable var(Source{}, "var", ast::StorageClass::kPrivate, &i32);
|
ast::Variable var(Source{}, "var", ast::StorageClass::kPrivate, &i32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&var);
|
td.RegisterVariableForTesting(&var);
|
||||||
|
|
||||||
|
@ -190,10 +191,10 @@ TEST_F(BuilderTest, IdentifierExpression_Load) {
|
||||||
TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
|
TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
|
|
||||||
ast::Variable var(Source{}, "var", ast::StorageClass::kNone, &i32);
|
ast::Variable var(Source{}, "var", ast::StorageClass::kNone, &i32, true,
|
||||||
var.set_constructor(create<ast::ScalarConstructorExpression>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
create<ast::SintLiteral>(&i32, 2)));
|
create<ast::SintLiteral>(&i32, 2)),
|
||||||
var.set_is_const(true);
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
td.RegisterVariableForTesting(&var);
|
td.RegisterVariableForTesting(&var);
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,13 @@ TEST_F(BuilderTest, If_WithStatements) {
|
||||||
// v = 2;
|
// v = 2;
|
||||||
// }
|
// }
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(
|
body->append(
|
||||||
|
@ -124,7 +130,13 @@ TEST_F(BuilderTest, If_WithElse) {
|
||||||
// v = 3;
|
// v = 3;
|
||||||
// }
|
// }
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(
|
body->append(
|
||||||
|
@ -184,7 +196,13 @@ TEST_F(BuilderTest, If_WithElseIf) {
|
||||||
// v = 3;
|
// v = 3;
|
||||||
// }
|
// }
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(
|
body->append(
|
||||||
|
@ -256,7 +274,13 @@ TEST_F(BuilderTest, If_WithMultiple) {
|
||||||
// v = 5;
|
// v = 5;
|
||||||
// }
|
// }
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(
|
body->append(
|
||||||
|
@ -609,8 +633,14 @@ TEST_F(BuilderTest, If_WithLoad_Bug327) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
ast::type::Bool bool_type;
|
ast::type::Bool bool_type;
|
||||||
auto* var = create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction,
|
auto* var =
|
||||||
&bool_type);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&bool_type, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
td.RegisterVariableForTesting(var);
|
td.RegisterVariableForTesting(var);
|
||||||
|
|
||||||
ast::IfStatement expr(Source{}, create<ast::IdentifierExpression>("a"),
|
ast::IfStatement expr(Source{}, create<ast::IdentifierExpression>("a"),
|
||||||
|
|
|
@ -1399,9 +1399,8 @@ TEST_F(IntrinsicBuilderTest, DISABLED_Call_ArrayLength_Ptr) {
|
||||||
|
|
||||||
auto* var = Var("b", ast::StorageClass::kPrivate, &s_type);
|
auto* var = Var("b", ast::StorageClass::kPrivate, &s_type);
|
||||||
|
|
||||||
auto* ptr_var = Var("ptr_var", ast::StorageClass::kPrivate, &ptr);
|
Var("ptr_var", ast::StorageClass::kPrivate, &ptr,
|
||||||
ptr_var->set_constructor(
|
create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")), {});
|
||||||
create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")));
|
|
||||||
|
|
||||||
auto expr = Call("arrayLength", "ptr_var");
|
auto expr = Call("arrayLength", "ptr_var");
|
||||||
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
|
||||||
|
|
|
@ -66,7 +66,13 @@ TEST_F(BuilderTest, Loop_WithoutContinuing) {
|
||||||
// v = 2;
|
// v = 2;
|
||||||
// }
|
// }
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(
|
body->append(
|
||||||
|
@ -113,7 +119,13 @@ TEST_F(BuilderTest, Loop_WithContinuing) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(
|
body->append(
|
||||||
|
|
|
@ -81,7 +81,8 @@ TEST_F(BuilderTest, Return_WithValue) {
|
||||||
TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) {
|
TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &f32);
|
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &f32,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::ReturnStatement ret(Source{},
|
ast::ReturnStatement ret(Source{},
|
||||||
create<ast::IdentifierExpression>("param"));
|
create<ast::IdentifierExpression>("param"));
|
||||||
|
|
|
@ -77,9 +77,21 @@ TEST_F(BuilderTest, Switch_WithCase) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* case_1_body = create<ast::BlockStatement>();
|
auto* case_1_body = create<ast::BlockStatement>();
|
||||||
case_1_body->append(
|
case_1_body->append(
|
||||||
|
@ -158,9 +170,21 @@ TEST_F(BuilderTest, Switch_WithDefault) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* default_body = create<ast::BlockStatement>();
|
auto* default_body = create<ast::BlockStatement>();
|
||||||
default_body->append(
|
default_body->append(
|
||||||
|
@ -224,9 +248,21 @@ TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* case_1_body = create<ast::BlockStatement>();
|
auto* case_1_body = create<ast::BlockStatement>();
|
||||||
case_1_body->append(
|
case_1_body->append(
|
||||||
|
@ -320,9 +356,21 @@ TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* case_1_body = create<ast::BlockStatement>();
|
auto* case_1_body = create<ast::BlockStatement>();
|
||||||
case_1_body->append(
|
case_1_body->append(
|
||||||
|
@ -412,9 +460,21 @@ TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* case_1_body = create<ast::BlockStatement>();
|
auto* case_1_body = create<ast::BlockStatement>();
|
||||||
case_1_body->append(
|
case_1_body->append(
|
||||||
|
@ -460,9 +520,21 @@ TEST_F(BuilderTest, Switch_WithNestedBreak) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* v =
|
auto* v =
|
||||||
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"v", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
auto* a =
|
auto* a =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* if_body = create<ast::BlockStatement>();
|
auto* if_body = create<ast::BlockStatement>();
|
||||||
if_body->append(create<ast::BreakStatement>());
|
if_body->append(create<ast::BreakStatement>());
|
||||||
|
|
|
@ -98,7 +98,8 @@ TEST_F(BuilderTest, UnaryOp_LoadRequired) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::type::Vector vec(&f32, 3);
|
ast::type::Vector vec(&f32, 3);
|
||||||
|
|
||||||
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &vec);
|
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &vec,
|
||||||
|
false, nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ast::UnaryOpExpression expr(ast::UnaryOp::kNegation,
|
ast::UnaryOpExpression expr(ast::UnaryOp::kNegation,
|
||||||
create<ast::IdentifierExpression>("param"));
|
create<ast::IdentifierExpression>("param"));
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/constructor_expression.h"
|
#include "src/ast/constructor_expression.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
@ -70,6 +69,7 @@
|
||||||
#include "src/ast/type_constructor_expression.h"
|
#include "src/ast/type_constructor_expression.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_decoration.h"
|
||||||
#include "src/writer/float_to_string.h"
|
#include "src/writer/float_to_string.h"
|
||||||
|
@ -582,10 +582,8 @@ bool GeneratorImpl::EmitStructType(const ast::type::Struct* str) {
|
||||||
bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
||||||
make_indent();
|
make_indent();
|
||||||
|
|
||||||
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
|
if (!var->decorations().empty() && !EmitVariableDecorations(var)) {
|
||||||
if (!EmitVariableDecorations(decorated)) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var->is_const()) {
|
if (var->is_const()) {
|
||||||
|
@ -614,7 +612,7 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitVariableDecorations(ast::DecoratedVariable* var) {
|
bool GeneratorImpl::EmitVariableDecorations(ast::Variable* var) {
|
||||||
out_ << "[[";
|
out_ << "[[";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto* deco : var->decorations()) {
|
for (auto* deco : var->decorations()) {
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/constructor_expression.h"
|
#include "src/ast/constructor_expression.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
#include "src/ast/identifier_expression.h"
|
||||||
|
@ -206,7 +205,7 @@ class GeneratorImpl : public TextGenerator {
|
||||||
/// Handles generating variable decorations
|
/// Handles generating variable decorations
|
||||||
/// @param var the decorated variable
|
/// @param var the decorated variable
|
||||||
/// @returns true if the variable decoration was emitted
|
/// @returns true if the variable decoration was emitted
|
||||||
bool EmitVariableDecorations(ast::DecoratedVariable* var);
|
bool EmitVariableDecorations(ast::Variable* var);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wgsl
|
} // namespace wgsl
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
|
@ -69,9 +68,21 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
|
||||||
ast::type::I32 i32;
|
ast::type::I32 i32;
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
params.push_back(
|
params.push_back(
|
||||||
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &i32));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"b", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&i32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{})); // decorations
|
||||||
|
|
||||||
ast::type::Void void_type;
|
ast::type::Void void_type;
|
||||||
ast::Function func(Source{}, "my_func", params, &void_type, body,
|
ast::Function func(Source{}, "my_func", params, &void_type, body,
|
||||||
|
@ -191,13 +202,18 @@ TEST_F(WgslGeneratorImplTest,
|
||||||
ast::type::Struct s("Data", str);
|
ast::type::Struct s("Data", str);
|
||||||
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
|
||||||
|
|
||||||
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
|
auto* data_var =
|
||||||
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"data", // name
|
||||||
ast::VariableDecorationList decos;
|
ast::StorageClass::kStorageBuffer, // storage_class
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
&ac, // type
|
||||||
decos.push_back(create<ast::SetDecoration>(0, Source{}));
|
false, // is_const
|
||||||
data_var->set_decorations(decos);
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
// decorations
|
||||||
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
|
create<ast::SetDecoration>(0, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
mod.AddConstructedType(&s);
|
mod.AddConstructedType(&s);
|
||||||
|
|
||||||
|
@ -206,11 +222,16 @@ TEST_F(WgslGeneratorImplTest,
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
@ -228,11 +249,16 @@ TEST_F(WgslGeneratorImplTest,
|
||||||
|
|
||||||
{
|
{
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto* var = create<ast::Variable>(Source{}, "v",
|
auto* var = create<ast::Variable>(
|
||||||
ast::StorageClass::kFunction, &f32);
|
Source{}, // source
|
||||||
var->set_constructor(create<ast::MemberAccessorExpression>(
|
"v", // name
|
||||||
create<ast::IdentifierExpression>("data"),
|
ast::StorageClass::kFunction, // storage_class
|
||||||
create<ast::IdentifierExpression>("d")));
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
create<ast::MemberAccessorExpression>(
|
||||||
|
create<ast::IdentifierExpression>("data"),
|
||||||
|
create<ast::IdentifierExpression>("d")), // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>();
|
auto* body = create<ast::BlockStatement>();
|
||||||
body->append(create<ast::VariableDeclStatement>(var));
|
body->append(create<ast::VariableDeclStatement>(var));
|
||||||
|
|
|
@ -33,7 +33,13 @@ using WgslGeneratorImplTest = TestHelper;
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
|
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kNone, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -49,7 +55,13 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
|
||||||
// https://github.com/gpuweb/gpuweb/issues/654
|
// https://github.com/gpuweb/gpuweb/issues/654
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kFunction, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
@ -62,7 +74,13 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
|
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32);
|
create<ast::Variable>(Source{}, // source
|
||||||
|
"a", // name
|
||||||
|
ast::StorageClass::kPrivate, // storage_class
|
||||||
|
&f32, // type
|
||||||
|
false, // is_const
|
||||||
|
nullptr, // constructor
|
||||||
|
ast::VariableDecorationList{}); // decorations
|
||||||
|
|
||||||
ast::VariableDeclStatement stmt(var);
|
ast::VariableDeclStatement stmt(var);
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_decoration.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/constant_id_decoration.h"
|
#include "src/ast/constant_id_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/ast/variable_decoration.h"
|
#include "src/ast/variable_decoration.h"
|
||||||
#include "src/writer/wgsl/generator_impl.h"
|
#include "src/writer/wgsl/generator_impl.h"
|
||||||
#include "src/writer/wgsl/test_helper.h"
|
#include "src/writer/wgsl/test_helper.h"
|
||||||
|
@ -35,7 +35,8 @@ using WgslGeneratorImplTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitVariable) {
|
TEST_F(WgslGeneratorImplTest, EmitVariable) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, false, nullptr,
|
||||||
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
||||||
EXPECT_EQ(gen.result(), R"(var a : f32;
|
EXPECT_EQ(gen.result(), R"(var a : f32;
|
||||||
|
@ -44,7 +45,8 @@ TEST_F(WgslGeneratorImplTest, EmitVariable) {
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
|
TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "a", ast::StorageClass::kInput, &f32);
|
ast::Variable v(Source{}, "a", ast::StorageClass::kInput, &f32, false,
|
||||||
|
nullptr, ast::VariableDecorationList{});
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
||||||
EXPECT_EQ(gen.result(), R"(var<in> a : f32;
|
EXPECT_EQ(gen.result(), R"(var<in> a : f32;
|
||||||
|
@ -54,15 +56,12 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
|
||||||
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
|
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, false, nullptr,
|
||||||
decos.push_back(create<ast::LocationDecoration>(2, Source{}));
|
ast::VariableDecorationList{
|
||||||
|
create<ast::LocationDecoration>(2, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable dv;
|
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
||||||
dv.set_name("a");
|
|
||||||
dv.set_type(&f32);
|
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(&dv)) << gen.error();
|
|
||||||
EXPECT_EQ(gen.result(), R"([[location(2)]] var a : f32;
|
EXPECT_EQ(gen.result(), R"([[location(2)]] var a : f32;
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
@ -70,20 +69,17 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
|
||||||
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) {
|
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) {
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
ast::Variable v(
|
||||||
decos.push_back(
|
Source{}, "a", ast::StorageClass::kNone, &f32, false, nullptr,
|
||||||
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
|
ast::VariableDecorationList{
|
||||||
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
|
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}),
|
||||||
decos.push_back(create<ast::SetDecoration>(1, Source{}));
|
create<ast::BindingDecoration>(0, Source{}),
|
||||||
decos.push_back(create<ast::LocationDecoration>(2, Source{}));
|
create<ast::SetDecoration>(1, Source{}),
|
||||||
decos.push_back(create<ast::ConstantIdDecoration>(42, Source{}));
|
create<ast::LocationDecoration>(2, Source{}),
|
||||||
|
create<ast::ConstantIdDecoration>(42, Source{}),
|
||||||
|
});
|
||||||
|
|
||||||
ast::DecoratedVariable dv;
|
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
||||||
dv.set_name("a");
|
|
||||||
dv.set_type(&f32);
|
|
||||||
dv.set_decorations(decos);
|
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(&dv)) << gen.error();
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
gen.result(),
|
gen.result(),
|
||||||
R"([[builtin(position), binding(0), set(1), location(2), constant_id(42)]] var a : f32;
|
R"([[builtin(position), binding(0), set(1), location(2), constant_id(42)]] var a : f32;
|
||||||
|
@ -94,8 +90,8 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
|
||||||
auto* ident = create<ast::IdentifierExpression>("initializer");
|
auto* ident = create<ast::IdentifierExpression>("initializer");
|
||||||
|
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, false, ident,
|
||||||
v.set_constructor(ident);
|
ast::VariableDecorationList{});
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
||||||
EXPECT_EQ(gen.result(), R"(var a : f32 = initializer;
|
EXPECT_EQ(gen.result(), R"(var a : f32 = initializer;
|
||||||
|
@ -106,9 +102,8 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
|
||||||
auto* ident = create<ast::IdentifierExpression>("initializer");
|
auto* ident = create<ast::IdentifierExpression>("initializer");
|
||||||
|
|
||||||
ast::type::F32 f32;
|
ast::type::F32 f32;
|
||||||
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32);
|
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, true, ident,
|
||||||
v.set_constructor(ident);
|
ast::VariableDecorationList{});
|
||||||
v.set_is_const(true);
|
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
|
||||||
EXPECT_EQ(gen.result(), R"(const a : f32 = initializer;
|
EXPECT_EQ(gen.result(), R"(const a : f32 = initializer;
|
||||||
|
|
Loading…
Reference in New Issue