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:
Ben Clayton 2020-12-11 13:07:02 +00:00 committed by Commit Bot service account
parent ccc67252ff
commit a80511e021
79 changed files with 4259 additions and 2268 deletions

View File

@ -259,8 +259,6 @@ source_set("libtint_core_src") {
"src/ast/constructor_expression.h",
"src/ast/continue_statement.cc",
"src/ast/continue_statement.h",
"src/ast/decorated_variable.cc",
"src/ast/decorated_variable.h",
"src/ast/decoration.cc",
"src/ast/decoration.h",
"src/ast/discard_statement.cc",
@ -765,7 +763,6 @@ source_set("tint_unittests_core_src") {
"src/ast/clone_context_test.cc",
"src/ast/constant_id_decoration_test.cc",
"src/ast/continue_statement_test.cc",
"src/ast/decorated_variable_test.cc",
"src/ast/decoration_test.cc",
"src/ast/discard_statement_test.cc",
"src/ast/else_statement_test.cc",

View File

@ -80,8 +80,6 @@ set(TINT_LIB_SRCS
ast/constructor_expression.h
ast/continue_statement.cc
ast/continue_statement.h
ast/decorated_variable.cc
ast/decorated_variable.h
ast/decoration.cc
ast/decoration.h
ast/discard_statement.cc
@ -403,7 +401,6 @@ if(${TINT_BUILD_TESTS})
ast/continue_statement_test.cc
ast/discard_statement_test.cc
ast/decoration_test.cc
ast/decorated_variable_test.cc
ast/else_statement_test.cc
ast/expression_test.cc
ast/fallthrough_statement_test.cc

View File

@ -32,7 +32,16 @@ Builder::~Builder() = default;
Variable* Builder::Var(const std::string& name,
StorageClass storage,
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);
return var;
}
@ -40,8 +49,16 @@ Variable* Builder::Var(const std::string& name,
Variable* Builder::Const(const std::string& name,
StorageClass storage,
type::Type* type) {
auto* var = create<Variable>(Source{}, name, storage, type);
var->set_is_const(true);
return Const(name, storage, type, nullptr, {});
}
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);
return var;
}

View File

@ -428,7 +428,8 @@ class Builder {
/// @param name the variable name
/// @param storage the variable storage class
/// @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,
StorageClass storage,
type::Type* type);
@ -436,11 +437,36 @@ class Builder {
/// @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
/// @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,
StorageClass storage,
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 args the function call arguments
/// @returns a `CallExpression` to the function `func`, with the

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -17,12 +17,12 @@
#include <sstream>
#include "src/ast/clone_context.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/module.h"
#include "src/ast/stage_decoration.h"
#include "src/ast/type/multisampled_texture_type.h"
#include "src/ast/type/sampled_texture_type.h"
#include "src/ast/type/texture_type.h"
#include "src/ast/variable.h"
#include "src/ast/workgroup_decoration.h"
TINT_INSTANTIATE_CLASS_ID(tint::ast::Function);
@ -88,12 +88,10 @@ Function::referenced_location_variables() const {
std::vector<std::pair<Variable*, LocationDecoration*>> ret;
for (auto* var : referenced_module_variables()) {
if (auto* decos = var->As<DecoratedVariable>()) {
for (auto* deco : decos->decorations()) {
if (auto* location = deco->As<LocationDecoration>()) {
ret.push_back({var, location});
break;
}
for (auto* deco : var->decorations()) {
if (auto* location = deco->As<LocationDecoration>()) {
ret.push_back({var, location});
break;
}
}
}
@ -109,22 +107,20 @@ Function::referenced_uniform_variables() const {
continue;
}
if (auto* decorated = var->As<DecoratedVariable>()) {
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : decorated->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<SetDecoration>()) {
set = s;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<SetDecoration>()) {
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;
}
@ -138,22 +134,20 @@ Function::referenced_storagebuffer_variables() const {
continue;
}
if (auto* decorated = var->As<DecoratedVariable>()) {
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : decorated->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<SetDecoration>()) {
set = s;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<SetDecoration>()) {
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;
}
@ -163,12 +157,10 @@ Function::referenced_builtin_variables() const {
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
for (auto* var : referenced_module_variables()) {
if (auto* decorated = var->As<DecoratedVariable>()) {
for (auto* deco : decorated->decorations()) {
if (auto* builtin = deco->As<BuiltinDecoration>()) {
ret.push_back({var, builtin});
break;
}
for (auto* deco : var->decorations()) {
if (auto* builtin = deco->As<BuiltinDecoration>()) {
ret.push_back({var, builtin});
break;
}
}
}
@ -200,12 +192,10 @@ Function::local_referenced_builtin_variables() const {
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
for (auto* var : local_referenced_module_variables()) {
if (auto* decorated = var->As<DecoratedVariable>()) {
for (auto* deco : decorated->decorations()) {
if (auto* builtin = deco->As<BuiltinDecoration>()) {
ret.push_back({var, builtin});
break;
}
for (auto* deco : var->decorations()) {
if (auto* builtin = deco->As<BuiltinDecoration>()) {
ret.push_back({var, builtin});
break;
}
}
}
@ -314,23 +304,21 @@ Function::ReferencedSamplerVariablesImpl(type::SamplerKind kind) const {
continue;
}
if (auto* decorated = var->As<DecoratedVariable>()) {
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : decorated->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
}
if (auto* s = deco->As<SetDecoration>()) {
set = s;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
}
if (binding == nullptr || set == nullptr) {
continue;
if (auto* s = deco->As<SetDecoration>()) {
set = s;
}
ret.push_back({var, BindingInfo{binding, set}});
}
if (binding == nullptr || set == nullptr) {
continue;
}
ret.push_back({var, BindingInfo{binding, set}});
}
return ret;
}
@ -353,22 +341,20 @@ Function::ReferencedSampledTextureVariablesImpl(bool multisampled) const {
continue;
}
if (auto* decorated = var->As<DecoratedVariable>()) {
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : decorated->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<SetDecoration>()) {
set = s;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->decorations()) {
if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<SetDecoration>()) {
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;

View File

@ -15,7 +15,6 @@
#include "src/ast/function.h"
#include "src/ast/builtin_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/location_decoration.h"
#include "src/ast/pipeline_stage.h"
@ -37,8 +36,9 @@ TEST_F(FunctionTest, Creation) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
auto* var = params[0];
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
@ -54,8 +54,9 @@ TEST_F(FunctionTest, Creation_WithSource) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
Function f(Source{Source::Location{20, 2}}, "func", params, &void_type,
create<BlockStatement>(), FunctionDecorationList{});
@ -68,7 +69,8 @@ TEST_F(FunctionTest, AddDuplicateReferencedVariables) {
type::Void void_type;
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,
create<BlockStatement>(), FunctionDecorationList{});
@ -79,7 +81,8 @@ TEST_F(FunctionTest, AddDuplicateReferencedVariables) {
f.add_referenced_module_variable(&v);
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);
ASSERT_EQ(f.referenced_module_variables().size(), 2u);
EXPECT_EQ(f.referenced_module_variables()[1], &v2);
@ -89,38 +92,44 @@ TEST_F(FunctionTest, GetReferenceLocations) {
type::Void void_type;
type::I32 i32;
DecoratedVariable loc1(
create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32));
loc1.set_decorations({create<LocationDecoration>(0, Source{})});
auto* loc1 = create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32,
false, nullptr,
ast::VariableDecorationList{
create<LocationDecoration>(0, Source{}),
});
DecoratedVariable loc2(
create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32));
loc2.set_decorations({create<LocationDecoration>(1, Source{})});
auto* loc2 = create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32,
false, nullptr,
ast::VariableDecorationList{
create<LocationDecoration>(1, Source{}),
});
DecoratedVariable builtin1(
create<Variable>(Source{}, "builtin1", StorageClass::kInput, &i32));
builtin1.set_decorations(
{create<BuiltinDecoration>(Builtin::kPosition, Source{})});
auto* builtin1 = create<Variable>(
Source{}, "builtin1", StorageClass::kInput, &i32, false, nullptr,
ast::VariableDecorationList{
create<BuiltinDecoration>(Builtin::kPosition, Source{}),
});
DecoratedVariable builtin2(
create<Variable>(Source{}, "builtin2", StorageClass::kInput, &i32));
builtin2.set_decorations(
{create<BuiltinDecoration>(Builtin::kFragDepth, Source{})});
auto* builtin2 = create<Variable>(
Source{}, "builtin2", StorageClass::kInput, &i32, false, nullptr,
ast::VariableDecorationList{
create<BuiltinDecoration>(Builtin::kFragDepth, Source{}),
});
Function f(Source{}, "func", VariableList{}, &void_type,
create<BlockStatement>(), FunctionDecorationList{});
f.add_referenced_module_variable(&loc1);
f.add_referenced_module_variable(&builtin1);
f.add_referenced_module_variable(&loc2);
f.add_referenced_module_variable(&builtin2);
f.add_referenced_module_variable(loc1);
f.add_referenced_module_variable(builtin1);
f.add_referenced_module_variable(loc2);
f.add_referenced_module_variable(builtin2);
ASSERT_EQ(f.referenced_module_variables().size(), 4u);
auto ref_locs = f.referenced_location_variables();
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[1].first, &loc2);
EXPECT_EQ(ref_locs[1].first, loc2);
EXPECT_EQ(ref_locs[1].second->value(), 1u);
}
@ -128,38 +137,44 @@ TEST_F(FunctionTest, GetReferenceBuiltins) {
type::Void void_type;
type::I32 i32;
DecoratedVariable loc1(
create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32));
loc1.set_decorations({create<LocationDecoration>(0, Source{})});
auto* loc1 = create<Variable>(Source{}, "loc1", StorageClass::kInput, &i32,
false, nullptr,
ast::VariableDecorationList{
create<LocationDecoration>(0, Source{}),
});
DecoratedVariable loc2(
create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32));
loc2.set_decorations({create<LocationDecoration>(1, Source{})});
auto* loc2 = create<Variable>(Source{}, "loc2", StorageClass::kInput, &i32,
false, nullptr,
ast::VariableDecorationList{
create<LocationDecoration>(1, Source{}),
});
DecoratedVariable builtin1(
create<Variable>(Source{}, "builtin1", StorageClass::kInput, &i32));
builtin1.set_decorations(
{create<BuiltinDecoration>(Builtin::kPosition, Source{})});
auto* builtin1 = create<Variable>(
Source{}, "builtin1", StorageClass::kInput, &i32, false, nullptr,
ast::VariableDecorationList{
create<BuiltinDecoration>(Builtin::kPosition, Source{}),
});
DecoratedVariable builtin2(
create<Variable>(Source{}, "builtin2", StorageClass::kInput, &i32));
builtin2.set_decorations(
{create<BuiltinDecoration>(Builtin::kFragDepth, Source{})});
auto* builtin2 = create<Variable>(
Source{}, "builtin2", StorageClass::kInput, &i32, false, nullptr,
ast::VariableDecorationList{
create<BuiltinDecoration>(Builtin::kFragDepth, Source{}),
});
Function f(Source{}, "func", VariableList{}, &void_type,
create<BlockStatement>(), FunctionDecorationList{});
f.add_referenced_module_variable(&loc1);
f.add_referenced_module_variable(&builtin1);
f.add_referenced_module_variable(&loc2);
f.add_referenced_module_variable(&builtin2);
f.add_referenced_module_variable(loc1);
f.add_referenced_module_variable(builtin1);
f.add_referenced_module_variable(loc2);
f.add_referenced_module_variable(builtin2);
ASSERT_EQ(f.referenced_module_variables().size(), 4u);
auto ref_locs = f.referenced_builtin_variables();
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[1].first, &builtin2);
EXPECT_EQ(ref_locs[1].first, builtin2);
EXPECT_EQ(ref_locs[1].second->value(), Builtin::kFragDepth);
}
@ -182,8 +197,9 @@ TEST_F(FunctionTest, IsValid) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>());
@ -198,8 +214,9 @@ TEST_F(FunctionTest, IsValid_EmptyName) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
Function f(Source{}, "", params, &void_type, create<BlockStatement>(),
FunctionDecorationList{});
@ -210,8 +227,9 @@ TEST_F(FunctionTest, IsValid_MissingReturnType) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
Function f(Source{}, "func", params, nullptr, create<BlockStatement>(),
FunctionDecorationList{});
@ -223,8 +241,9 @@ TEST_F(FunctionTest, IsValid_NullParam) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
params.push_back(nullptr);
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
@ -236,8 +255,9 @@ TEST_F(FunctionTest, IsValid_InvalidParam) {
type::Void void_type;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, nullptr));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone,
nullptr, false, nullptr,
ast::VariableDecorationList{}));
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
FunctionDecorationList{});
@ -249,8 +269,9 @@ TEST_F(FunctionTest, IsValid_NullBodyStatement) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>());
@ -267,8 +288,9 @@ TEST_F(FunctionTest, IsValid_InvalidBodyStatement) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>());
@ -325,8 +347,9 @@ TEST_F(FunctionTest, ToStr_WithParams) {
type::I32 i32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
params.push_back(create<Variable>(Source{}, "var", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>());
@ -364,10 +387,12 @@ TEST_F(FunctionTest, TypeName_WithParams) {
type::F32 f32;
VariableList params;
params.push_back(
create<Variable>(Source{}, "var1", StorageClass::kNone, &i32));
params.push_back(
create<Variable>(Source{}, "var2", StorageClass::kNone, &f32));
params.push_back(create<Variable>(Source{}, "var1", StorageClass::kNone, &i32,
false, nullptr,
ast::VariableDecorationList{}));
params.push_back(create<Variable>(Source{}, "var2", StorageClass::kNone, &f32,
false, nullptr,
ast::VariableDecorationList{}));
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(),
FunctionDecorationList{});

View File

@ -67,7 +67,8 @@ TEST_F(ModuleTest, IsValid_Empty) {
TEST_F(ModuleTest, IsValid_GlobalVariable) {
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;
m.AddGlobalVariable(var);
@ -81,7 +82,8 @@ TEST_F(ModuleTest, IsValid_Null_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;
m.AddGlobalVariable(var);

View File

@ -17,7 +17,7 @@
#include <assert.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"
TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
@ -25,24 +25,66 @@ TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
namespace tint {
namespace ast {
Variable::Variable() = default;
Variable::Variable(const Source& source,
const std::string& name,
StorageClass sc,
type::Type* type)
: Base(source), name_(name), storage_class_(sc), type_(type) {}
type::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() = 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 {
auto* cloned = ctx->mod->create<Variable>(
ctx->Clone(source()), name(), storage_class(), ctx->Clone(type()));
cloned->set_constructor(ctx->Clone(constructor()));
cloned->set_is_const(is_const());
return cloned;
return ctx->mod->create<Variable>(
ctx->Clone(source()), name(), storage_class(), ctx->Clone(type()),
is_const_, ctx->Clone(constructor()), ctx->Clone(decorations_));
}
bool Variable::IsValid() const {
@ -87,6 +129,17 @@ void Variable::to_str(std::ostream& out, size_t indent) const {
out << "Const";
}
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);
constructor_to_str(out, indent + 2);
make_indent(out, indent);

View File

@ -25,6 +25,7 @@
#include "src/ast/node.h"
#include "src/ast/storage_class.h"
#include "src/ast/type/type.h"
#include "src/ast/variable_decoration.h"
namespace tint {
namespace ast {
@ -83,25 +84,24 @@ class Variable : public Castable<Variable, Node> {
/// @param name the variables name
/// @param sc the variable storage class
/// @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,
const std::string& name,
StorageClass sc,
type::Type* type);
type::Type* type,
bool is_const,
Expression* constructor,
VariableDecorationList decorations);
/// Move constructor
Variable(Variable&&);
~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
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.
type::Type* type() const { return type_; }
@ -111,20 +111,28 @@ class Variable : public Castable<Variable, Node> {
/// @returns the 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
Expression* constructor() const { return constructor_; }
/// @returns true if the variable has an constructor
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
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`
/// `ctx`.
/// @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;
protected:
/// Constructor
/// Used by the DecoratedVariable constructor.
Variable();
/// Output information for this variable.
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
@ -158,12 +162,13 @@ class Variable : public Castable<Variable, Node> {
private:
Variable(const Variable&) = delete;
bool is_const_ = false;
std::string name_;
StorageClass storage_class_ = StorageClass::kNone;
// The value type if a const or formal paramter, and the store type if a var
type::Type* type_ = nullptr;
bool is_const_ = false;
Expression* constructor_ = nullptr;
VariableDecorationList decorations_;
};
/// A list of variables

View File

@ -26,7 +26,8 @@ using VariableDeclStatementTest = TestHelper;
TEST_F(VariableDeclStatementTest, Creation) {
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);
EXPECT_EQ(stmt.variable(), var);
@ -34,7 +35,8 @@ TEST_F(VariableDeclStatementTest, Creation) {
TEST_F(VariableDeclStatementTest, Creation_WithSource) {
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);
auto src = stmt.source();
@ -44,7 +46,8 @@ TEST_F(VariableDeclStatementTest, Creation_WithSource) {
TEST_F(VariableDeclStatementTest, IsVariableDecl) {
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);
EXPECT_TRUE(s.Is<VariableDeclStatement>());
@ -52,14 +55,16 @@ TEST_F(VariableDeclStatementTest, IsVariableDecl) {
TEST_F(VariableDeclStatementTest, IsValid) {
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);
EXPECT_TRUE(stmt.IsValid());
}
TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
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);
EXPECT_FALSE(stmt.IsValid());
}
@ -71,7 +76,8 @@ TEST_F(VariableDeclStatementTest, IsValid_NullVariable) {
TEST_F(VariableDeclStatementTest, ToStr) {
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);
std::ostringstream out;

View File

@ -14,6 +14,7 @@
#include "src/ast/variable.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/test_helper.h"
#include "src/ast/type/f32_type.h"
@ -27,7 +28,8 @@ using VariableTest = TestHelper;
TEST_F(VariableTest, Creation) {
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.storage_class(), StorageClass::kFunction);
@ -41,7 +43,8 @@ TEST_F(VariableTest, Creation) {
TEST_F(VariableTest, CreationWithSource) {
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
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.storage_class(), StorageClass::kPrivate);
@ -55,7 +58,8 @@ TEST_F(VariableTest, CreationWithSource) {
TEST_F(VariableTest, CreationEmpty) {
type::I32 t;
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.storage_class(), StorageClass::kWorkgroup);
@ -68,43 +72,58 @@ TEST_F(VariableTest, CreationEmpty) {
TEST_F(VariableTest, IsValid) {
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());
}
TEST_F(VariableTest, IsValid_WithConstructor) {
type::I32 t;
Variable v{Source{}, "my_var", StorageClass::kNone, &t};
v.set_constructor(create<IdentifierExpression>("ident"));
Variable v{Source{},
"my_var",
StorageClass::kNone,
&t,
false,
create<IdentifierExpression>("ident"),
ast::VariableDecorationList{}};
EXPECT_TRUE(v.IsValid());
}
TEST_F(VariableTest, IsValid_MissinName) {
type::I32 t;
Variable v{Source{}, "", StorageClass::kNone, &t};
Variable v{Source{}, "", StorageClass::kNone, &t,
false, nullptr, ast::VariableDecorationList{}};
EXPECT_FALSE(v.IsValid());
}
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());
}
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());
}
TEST_F(VariableTest, IsValid_InvalidConstructor) {
type::I32 t;
Variable v{Source{}, "my_var", StorageClass::kNone, &t};
v.set_constructor(create<IdentifierExpression>(""));
Variable v{Source{},
"my_var",
StorageClass::kNone,
&t,
false,
create<IdentifierExpression>(""),
ast::VariableDecorationList{}};
EXPECT_FALSE(v.IsValid());
}
TEST_F(VariableTest, to_str) {
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;
v.to_str(out, 2);
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 ast
} // namespace tint

View File

@ -20,7 +20,6 @@
#include "src/ast/bool_literal.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/function.h"
#include "src/ast/null_literal.h"
@ -39,6 +38,7 @@
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/uint_literal.h"
#include "src/ast/variable.h"
namespace tint {
namespace inspector {
@ -91,12 +91,7 @@ std::string Inspector::GetRemappedNameForEntryPoint(
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
std::map<uint32_t, Scalar> result;
for (auto* var : module_.global_variables()) {
auto* decorated = var->As<ast::DecoratedVariable>();
if (decorated == nullptr) {
continue;
}
if (!decorated->HasConstantIdDecoration()) {
if (!var->HasConstantIdDecoration()) {
continue;
}
@ -104,7 +99,7 @@ std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
// 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
// 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()) {
continue;
}

View File

@ -22,7 +22,6 @@
#include "src/ast/call_expression.h"
#include "src/ast/call_statement.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
@ -56,6 +55,7 @@
#include "src/ast/type/vector_type.h"
#include "src/ast/type/void_type.h"
#include "src/ast/uint_literal.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
#include "src/ast/variable_decoration.h"
#include "src/ast/workgroup_decoration.h"
@ -114,10 +114,22 @@ class InspectorHelper {
for (auto inout : inout_vars) {
std::string in, out;
std::tie(in, out) = inout;
auto* in_var = create<ast::Variable>(
Source{}, in, ast::StorageClass::kInput, u32_type());
auto* out_var = create<ast::Variable>(
Source{}, out, ast::StorageClass::kOutput, u32_type());
auto* in_var =
create<ast::Variable>(Source{}, // source
in, // name
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(out_var);
}
@ -187,17 +199,23 @@ class InspectorHelper {
uint32_t id,
ast::type::Type* type,
T* val) {
auto* dvar = create<ast::DecoratedVariable>(
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);
ast::Expression* constructor = nullptr;
if (val) {
dvar->set_constructor(
create<ast::ScalarConstructorExpression>(MakeLiteral(type, val)));
constructor =
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
@ -348,13 +366,18 @@ class InspectorHelper {
ast::StorageClass storage_class,
uint32_t set,
uint32_t binding) {
auto* var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, name, storage_class, type));
ast::VariableDecorationList decorations;
decorations.push_back(create<ast::BindingDecoration>(binding, Source{}));
decorations.push_back(create<ast::SetDecoration>(set, Source{}));
var->set_decorations(decorations);
auto* var = create<ast::Variable>(
Source{}, // source
name, // name
storage_class, // storage_class
type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(binding, Source{}),
create<ast::SetDecoration>(set, Source{}),
});
mod()->AddGlobalVariable(var);
}
@ -399,9 +422,14 @@ class InspectorHelper {
ast::type::Type* member_type;
std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type);
body->append(create<ast::VariableDeclStatement>(
create<ast::Variable>(Source{}, "local" + member_name,
ast::StorageClass::kNone, member_type)));
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
Source{}, // source
"local" + member_name, // name
ast::StorageClass::kNone, // storage_class
member_type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}))); // decorations
}
for (auto member : members) {
@ -496,7 +524,13 @@ class InspectorHelper {
void AddGlobalVariable(const std::string& name, ast::type::Type* type) {
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
@ -504,7 +538,13 @@ class InspectorHelper {
/// @param type the type to use
void AddDepthTexture(const std::string& name, ast::type::Type* type) {
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
@ -526,9 +566,14 @@ class InspectorHelper {
auto* body = create<ast::BlockStatement>();
auto* call_result = create<ast::Variable>(Source{}, "sampler_result",
ast::StorageClass::kFunction,
vec_type(base_type, 4));
auto* call_result =
create<ast::Variable>(Source{}, // source
"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));
ast::ExpressionList call_params;
@ -567,9 +612,14 @@ class InspectorHelper {
auto* body = create<ast::BlockStatement>();
auto* call_result = create<ast::Variable>(Source{}, "sampler_result",
ast::StorageClass::kFunction,
vec_type(base_type, 4));
auto* call_result =
create<ast::Variable>(Source{}, // source
"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));
ast::ExpressionList call_params;
@ -610,8 +660,14 @@ class InspectorHelper {
auto* body = create<ast::BlockStatement>();
auto* call_result = create<ast::Variable>(
Source{}, "sampler_result", ast::StorageClass::kFunction, base_type);
auto* call_result =
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));
ast::ExpressionList call_params;

View File

@ -803,9 +803,9 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
auto* ast_type = parser_impl_.ConvertType(param->type_id());
if (ast_type != nullptr) {
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.
ast_param->set_is_const(true);
ast_params.emplace_back(ast_param);
// The value is accessible by name.
identifier_values_.insert(param->result_id());
@ -1864,16 +1864,18 @@ bool FunctionEmitter::EmitFunctionVariables() {
if (failed()) {
return false;
}
auto* var = parser_impl_.MakeVariable(
inst.result_id(), ast::StorageClass::kFunction, var_store_type);
ast::Expression* constructor = nullptr;
if (inst.NumInOperands() > 1) {
// SPIR-V initializers are always constants.
// (OpenCL also allows the ID of an OpVariable, but we don't handle that
// here.)
var->set_constructor(
constructor =
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);
AddStatementForInstruction(var_decl_stmt, inst);
// 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;
if (!guard_name.empty()) {
// Declare the guard variable just before the "if", initialized to true.
auto* guard_var = create<ast::Variable>(Source{}, guard_name,
ast::StorageClass::kFunction,
parser_impl_.Bool());
guard_var->set_constructor(MakeTrue());
auto* guard_var =
create<ast::Variable>(Source{}, // source
guard_name, // name
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);
AddStatement(guard_decl);
}
@ -2674,8 +2680,9 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
assert(def_inst);
auto* ast_type =
RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
AddStatement(create<ast::VariableDeclStatement>(
parser_impl_.MakeVariable(id, ast::StorageClass::kFunction, ast_type)));
AddStatement(create<ast::VariableDeclStatement>(parser_impl_.MakeVariable(
id, ast::StorageClass::kFunction, ast_type, false, nullptr,
ast::VariableDecorationList{})));
// Save this as an already-named value.
identifier_values_.insert(id);
}
@ -2686,8 +2693,13 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
const auto phi_var_name = GetDefInfo(id)->phi_var;
assert(!phi_var_name.empty());
auto* var = create<ast::Variable>(
Source{}, phi_var_name, ast::StorageClass::kFunction,
parser_impl_.ConvertType(def_inst->type_id()));
Source{}, // source
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));
}
@ -2734,12 +2746,11 @@ bool FunctionEmitter::EmitConstDefinition(
return false;
}
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) {
return false;
}
ast_const->set_constructor(ast_expr.expr);
ast_const->set_is_const(true);
AddStatementForInstruction(create<ast::VariableDeclStatement>(ast_const),
inst);
// Save this as an already-named value.

View File

@ -41,7 +41,6 @@
#include "src/ast/builtin.h"
#include "src/ast/builtin_decoration.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/set_decoration.h"
@ -1064,8 +1063,6 @@ bool ParserImpl::EmitScalarSpecConstants() {
break;
}
if (ast_type && ast_expr) {
auto* ast_var =
MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type);
ast::VariableDecorationList spec_id_decos;
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
@ -1074,18 +1071,10 @@ bool ParserImpl::EmitScalarSpecConstants() {
break;
}
}
if (spec_id_decos.empty()) {
// Register it as a named constant, without specialization id.
ast_var->set_is_const(true);
ast_var->set_constructor(ast_expr);
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);
}
auto* ast_var =
MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type,
true, ast_expr, std::move(spec_id_decos));
ast_module_.AddGlobalVariable(ast_var);
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_storage_class =
ast_type->As<ast::type::Pointer>()->storage_class();
auto* ast_var =
MakeVariable(var.result_id(), ast_storage_class, ast_store_type);
ast::Expression* ast_constructor = nullptr;
if (var.NumInOperands() > 1) {
// SPIR-V initializers are always constants.
// (OpenCL also allows the ID of an OpVariable, but we don't handle that
// here.)
ast_var->set_constructor(
MakeConstantExpression(var.GetSingleWordInOperand(1)).expr);
ast_constructor =
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)
ast_module_.AddGlobalVariable(ast_var);
}
@ -1208,23 +1199,26 @@ bool ParserImpl::EmitModuleScopeVariables() {
// Make sure the variable has a name.
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
"gl_Position");
auto* var = create<ast::DecoratedVariable>(MakeVariable(
auto* var = MakeVariable(
builtin_position_.per_vertex_var_id,
enum_converter_.ToStorageClass(builtin_position_.storage_class),
ConvertType(builtin_position_.member_type_id)));
ast::VariableDecorationList decos;
decos.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
var->set_decorations(std::move(decos));
ConvertType(builtin_position_.member_type_id), false, nullptr,
ast::VariableDecorationList{
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}),
});
ast_module_.AddGlobalVariable(var);
}
return success_;
}
ast::Variable* ParserImpl::MakeVariable(uint32_t id,
ast::StorageClass sc,
ast::type::Type* type) {
ast::Variable* ParserImpl::MakeVariable(
uint32_t id,
ast::StorageClass sc,
ast::type::Type* type,
bool is_const,
ast::Expression* constructor,
ast::VariableDecorationList decorations) {
if (type == nullptr) {
Fail() << "internal error: can't make ast::Variable for null type";
return nullptr;
@ -1238,9 +1232,6 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
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)) {
if (deco.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) {
return nullptr;
}
ast_decorations.emplace_back(
decorations.emplace_back(
create<ast::BuiltinDecoration>(ast_builtin, Source{}));
}
if (deco[0] == SpvDecorationLocation) {
@ -1266,7 +1257,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
<< ": requires one literal operand";
return nullptr;
}
ast_decorations.emplace_back(
decorations.emplace_back(
create<ast::LocationDecoration>(deco[1], Source{}));
}
if (deco[0] == SpvDecorationDescriptorSet) {
@ -1275,8 +1266,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
<< ": has no operand";
return nullptr;
}
ast_decorations.emplace_back(
create<ast::SetDecoration>(deco[1], Source{}));
decorations.emplace_back(create<ast::SetDecoration>(deco[1], Source{}));
}
if (deco[0] == SpvDecorationBinding) {
if (deco.size() == 1) {
@ -1284,16 +1274,18 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
<< ": has no operand";
return nullptr;
}
ast_decorations.emplace_back(
decorations.emplace_back(
create<ast::BindingDecoration>(deco[1], Source{}));
}
}
if (!ast_decorations.empty()) {
auto* decorated_var = create<ast::DecoratedVariable>(ast_var);
decorated_var->set_decorations(std::move(ast_decorations));
ast_var = std::move(decorated_var);
}
return ast_var;
return create<ast::Variable>(Source{}, // source
namer_.Name(id), // name
sc, // storage_class
type, // type
is_const, // is_const
constructor, // constructor
decorations); // decorations
}
TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {

View File

@ -291,10 +291,16 @@ class ParserImpl : Reader {
/// @param id the SPIR-V result ID
/// @param sc the storage class, which cannot be ast::StorageClass::kNone
/// @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
ast::Variable* MakeVariable(uint32_t id,
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.
/// @param id the SPIR-V ID of the constant

View File

@ -1141,7 +1141,7 @@ INSTANTIATE_TEST_SUITE_P(Samplers,
%10 = OpVariable %ptr UniformConstant
)",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1159,7 +1159,7 @@ INSTANTIATE_TEST_SUITE_P(Images,
%10 = OpVariable %ptr_f_texture_1d UniformConstant
)",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1175,7 +1175,7 @@ INSTANTIATE_TEST_SUITE_P(Images,
%10 = OpVariable %ptr_f_storage_1d UniformConstant
)",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1191,7 +1191,7 @@ INSTANTIATE_TEST_SUITE_P(Images,
%10 = OpVariable %ptr_f_storage_1d UniformConstant
)",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1343,7 +1343,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleImplicitLod "
"%v4float %sampled_image %coords12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1352,7 +1352,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1376,7 +1376,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleImplicitLod "
"%v4float %sampled_image %coords123",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1385,7 +1385,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1420,7 +1420,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleImplicitLod "
"%v4float %sampled_image %coords12 ConstOffset %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1429,7 +1429,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1455,7 +1455,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleImplicitLod "
"%v4float %sampled_image %coords123 ConstOffset %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1464,7 +1464,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1499,7 +1499,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleImplicitLod "
"%v4float %sampled_image %coords12 Bias %float_7",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1508,7 +1508,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1533,7 +1533,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleImplicitLod "
"%v4float %sampled_image %coords123 Bias %float_7",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1542,7 +1542,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1580,7 +1580,7 @@ INSTANTIATE_TEST_SUITE_P(
"%v4float %sampled_image %coords12 Bias|ConstOffset "
"%float_7 %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1589,7 +1589,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1615,7 +1615,7 @@ INSTANTIATE_TEST_SUITE_P(
"%v4float %sampled_image %coords123 Bias|ConstOffset "
"%float_7 %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1624,7 +1624,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1672,7 +1672,7 @@ INSTANTIATE_TEST_SUITE_P(
%210 = OpImageSampleDrefImplicitLod %v4float %sampled_dref_image %coords12 %depth
)",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1681,7 +1681,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1690,7 +1690,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__depth_texture_2d
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{1}
@ -1745,7 +1745,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleDrefImplicitLod "
"%v4float %sampled_image %coords12 %depth",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1754,7 +1754,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_comparison
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1778,7 +1778,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleDrefImplicitLod "
"%v4float %sampled_image %coords123 %depth",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1787,7 +1787,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_comparison
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1822,7 +1822,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleDrefImplicitLod %v4float "
"%sampled_image %coords12 %depth ConstOffset %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1831,7 +1831,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_comparison
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1857,7 +1857,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleDrefImplicitLod %v4float "
"%sampled_image %coords123 %depth ConstOffset %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1866,7 +1866,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_comparison
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1907,7 +1907,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleExplicitLod "
"%v4float %sampled_image %coords12 Lod %float_null",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1916,7 +1916,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1941,7 +1941,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleExplicitLod "
"%v4float %sampled_image %coords123 Lod %float_null",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1950,7 +1950,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -1988,7 +1988,7 @@ INSTANTIATE_TEST_SUITE_P(
"%v4float %sampled_image %coords12 Lod|ConstOffset "
"%float_null %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -1997,7 +1997,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2024,7 +2024,7 @@ INSTANTIATE_TEST_SUITE_P(
"%v4float %sampled_image %coords123 Lod|ConstOffset "
"%float_null %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2033,7 +2033,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2070,7 +2070,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleExplicitLod "
"%v4float %sampled_image %coords12 Grad %float_7 %float_null",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2079,7 +2079,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2106,7 +2106,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleExplicitLod "
"%v4float %sampled_image %coords123 Grad %float_7 %float_null",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2115,7 +2115,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2154,7 +2154,7 @@ INSTANTIATE_TEST_SUITE_P(
"%v4float %sampled_image %coords12 Grad|ConstOffset "
"%float_7 %float_null %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2163,7 +2163,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2192,7 +2192,7 @@ INSTANTIATE_TEST_SUITE_P(
"%v4float %sampled_image %coords123 Grad|ConstOffset "
"%float_7 %float_null %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2201,7 +2201,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2248,7 +2248,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleExplicitLod %v4float "
"%sampled_image %vf12 Lod %f1",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2257,7 +2257,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2281,7 +2281,7 @@ INSTANTIATE_TEST_SUITE_P(
"%result = OpImageSampleExplicitLod %v4float "
"%sampled_image %vf12 Lod %f1",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -2290,7 +2290,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2387,7 +2387,7 @@ INSTANTIATE_TEST_SUITE_P(
// OpImageWrite with no extra params
{"%float 2D 0 0 0 2 Rgba32f", "OpImageWrite %im %vu12 %vf1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2408,7 +2408,7 @@ INSTANTIATE_TEST_SUITE_P(
{"%float 2D 0 0 0 2 Rgba32f",
"OpImageWrite %im %vu12 %vf1234 ConstOffset %offsets2d",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2437,7 +2437,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 1 component, dest 1 component
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %f1",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2457,7 +2457,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 2 component, dest 1 component
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2480,7 +2480,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 3 component, dest 1 component
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf123",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2503,7 +2503,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 4 component, dest 1 component
{"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vu12 %vf1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2526,7 +2526,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 2 component, dest 2 component
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2546,7 +2546,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 3 component, dest 2 component
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf123",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2569,7 +2569,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 4 component, dest 2 component
{"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vu12 %vf1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2593,7 +2593,7 @@ INSTANTIATE_TEST_SUITE_P(
// Source 4 component, dest 4 component
{"%float 2D 0 0 0 2 Rgba32f", "OpImageWrite %im %vu12 %vf1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2759,7 +2759,7 @@ INSTANTIATE_TEST_SUITE_P(
// Sampled type is unsigned int, texel is unsigned int
{"%uint 2D 0 0 0 2 Rgba32ui", "OpImageWrite %im %vu12 %vu1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2779,7 +2779,7 @@ INSTANTIATE_TEST_SUITE_P(
// Sampled type is unsigned int, texel is signed int
{"%uint 2D 0 0 0 2 Rgba32ui", "OpImageWrite %im %vu12 %vi1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2801,7 +2801,7 @@ INSTANTIATE_TEST_SUITE_P(
// Sampled type is signed int, texel is unsigned int
{"%int 2D 0 0 0 2 Rgba32i", "OpImageWrite %im %vu12 %vu1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2823,7 +2823,7 @@ INSTANTIATE_TEST_SUITE_P(
// Sampled type is signed int, texel is signed int
{"%int 2D 0 0 0 2 Rgba32i", "OpImageWrite %im %vu12 %vi1234",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2847,7 +2847,7 @@ INSTANTIATE_TEST_SUITE_P(
::testing::ValuesIn(std::vector<ImageAccessCase>{
// OpImageRead with no extra params
{"%float 2D 0 0 0 2 Rgba32f", "%99 = OpImageRead %v4float %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2875,7 +2875,7 @@ INSTANTIATE_TEST_SUITE_P(
// OpImageRead with ConstOffset
{"%float 2D 0 0 0 2 Rgba32f",
"%99 = OpImageRead %v4float %im %vu12 ConstOffset %offsets2d",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2908,7 +2908,7 @@ INSTANTIATE_TEST_SUITE_P(
::testing::ValuesIn(std::vector<ImageAccessCase>{
// OpImageFetch with no extra params
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2936,7 +2936,7 @@ INSTANTIATE_TEST_SUITE_P(
// OpImageFetch with ConstOffset
{"%float 2D 0 0 0 1 Unknown",
"%99 = OpImageFetch %v4float %im %vu12 ConstOffset %offsets2d",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -2983,7 +2983,7 @@ INSTANTIATE_TEST_SUITE_P(
// OpImageFetch requires no conversion, float -> v4float
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3010,7 +3010,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageFetch requires no conversion, uint -> v4uint
{"%uint 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4uint %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3037,7 +3037,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageFetch requires conversion, uint -> v4int
{"%uint 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4int %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3066,7 +3066,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageFetch requires no conversion, int -> v4int
{"%int 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4int %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3093,7 +3093,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageFetch requires conversion, int -> v4uint
{"%int 2D 0 0 0 1 Unknown", "%99 = OpImageFetch %v4uint %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3127,7 +3127,7 @@ INSTANTIATE_TEST_SUITE_P(
// OpImageRead requires no conversion, float -> v4float
{"%float 2D 0 0 0 1 Rgba32f", "%99 = OpImageRead %v4float %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3154,7 +3154,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageRead requires no conversion, uint -> v4uint
{"%uint 2D 0 0 0 1 Rgba32ui", "%99 = OpImageRead %v4uint %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3181,7 +3181,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageRead requires conversion, uint -> v4int
{"%uint 2D 0 0 0 1 Rgba32ui", "%99 = OpImageRead %v4int %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3210,7 +3210,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageRead requires no conversion, int -> v4int
{"%int 2D 0 0 0 1 Rgba32i", "%99 = OpImageRead %v4int %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3237,7 +3237,7 @@ INSTANTIATE_TEST_SUITE_P(
})"},
// OpImageRead requires conversion, int -> v4uint
{"%int 2D 0 0 0 1 Rgba32i", "%99 = OpImageRead %v4uint %im %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3273,7 +3273,7 @@ INSTANTIATE_TEST_SUITE_P(
{"%float 2D 0 0 0 1 Unknown",
"%99 = OpImageSampleImplicitLod %v4float %sampled_image %vu12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -3282,7 +3282,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3312,7 +3312,7 @@ INSTANTIATE_TEST_SUITE_P(
{"%uint 2D 0 0 0 1 Unknown",
"%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vu12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -3321,7 +3321,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3351,7 +3351,7 @@ INSTANTIATE_TEST_SUITE_P(
{"%uint 2D 0 0 0 1 Unknown",
"%99 = OpImageSampleImplicitLod %v4int %sampled_image %vu12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -3360,7 +3360,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3392,7 +3392,7 @@ INSTANTIATE_TEST_SUITE_P(
{"%int 2D 0 0 0 1 Unknown",
"%99 = OpImageSampleImplicitLod %v4int %sampled_image %vu12",
R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{0}
BindingDecoration{0}
@ -3401,7 +3401,7 @@ INSTANTIATE_TEST_SUITE_P(
uniform_constant
__sampler_sampler
}
DecoratedVariable{
Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}
@ -3430,7 +3430,7 @@ INSTANTIATE_TEST_SUITE_P(
// OpImageSampleImplicitLod requires conversion, int -> v4uint
{"%int 2D 0 0 0 1 Unknown",
"%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vu12",
R"(DecoratedVariable{
R"(Variable{
Decorations{
SetDecoration{2}
BindingDecoration{1}

View File

@ -199,7 +199,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BuiltinVertexIndex) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -249,7 +249,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BuiltinPosition_MapsToModuleScopeVec4Var) {
EXPECT_EQ(position_info.per_vertex_var_id, 1u);
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{position}
}
@ -1146,7 +1146,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_LocationDecoration_Valid) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariable{
Variable{
Decorations{
LocationDecoration{3}
}
@ -1198,7 +1198,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_DescriptorSetDecoration_Valid) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariable{
Variable{
Decorations{
SetDecoration{3}
}
@ -1252,7 +1252,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BindingDecoration_Valid) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{3}
}
@ -1501,7 +1501,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_True) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariableConst{
VariableConst{
Decorations{
ConstantIdDecoration{12}
}
@ -1526,7 +1526,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_False) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariableConst{
VariableConst{
Decorations{
ConstantIdDecoration{12}
}
@ -1551,7 +1551,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_U32) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariableConst{
VariableConst{
Decorations{
ConstantIdDecoration{12}
}
@ -1576,7 +1576,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_I32) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariableConst{
VariableConst{
Decorations{
ConstantIdDecoration{12}
}
@ -1601,7 +1601,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_ScalarSpecConstant_DeclareConst_F32) {
EXPECT_TRUE(p->error().empty());
const auto module_str = p->module().to_str();
EXPECT_THAT(module_str, HasSubstr(R"(
DecoratedVariableConst{
VariableConst{
Decorations{
ConstantIdDecoration{12}
}

View File

@ -28,7 +28,6 @@
#include "src/ast/call_expression.h"
#include "src/ast/case_statement.h"
#include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h"
@ -67,6 +66,7 @@
#include "src/ast/uint_literal.h"
#include "src/ast/unary_op.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
#include "src/ast/workgroup_decoration.h"
#include "src/reader/wgsl/lexer.h"
@ -419,25 +419,25 @@ Maybe<ast::Variable*> ParserImpl::global_variable_decl(
if (!decl.matched)
return Failure::kNoMatch;
auto* var = decl.value;
auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
if (var_decos.errored)
return Failure::kErrored;
if (var_decos.value.size() > 0) {
auto* dv = create<ast::DecoratedVariable>(var);
dv->set_decorations(var_decos.value);
var = dv;
}
ast::Expression* constructor = nullptr;
if (match(Token::Type::kEqual)) {
auto expr = expect_const_expr();
if (expr.errored)
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
@ -452,10 +452,6 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
if (decl.errored)
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))
return Failure::kErrored;
@ -463,14 +459,18 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
if (init.errored)
return Failure::kErrored;
var->set_constructor(init.value);
return var;
return create<ast::Variable>(decl->source, // source
decl->name, // name
ast::StorageClass::kNone, // storage_class
decl->type, // type
true, // is_const
init.value, // constructor
ast::VariableDecorationList{}); // decorations
}
// variable_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))
return Failure::kNoMatch;
@ -482,9 +482,9 @@ Maybe<ast::Variable*> ParserImpl::variable_decl() {
if (decl.errored)
return Failure::kErrored;
return create<ast::Variable>(decl->source, decl->name,
sc.matched ? sc.value : ast::StorageClass::kNone,
decl->type);
return VarDeclInfo{decl->source, decl->name,
sc.matched ? sc.value : ast::StorageClass::kNone,
decl->type};
}
// texture_sampler_types
@ -1349,13 +1349,18 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
ast::VariableList ret;
for (;;) {
auto* var = create<ast::Variable>(decl->source, decl->name,
ast::StorageClass::kNone, decl->type);
auto* var =
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
// 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
// which treat formal parameters like local variables that can be updated.
var->set_is_const(true);
ret.push_back(var);
if (!match(Token::Type::kComma))
@ -1610,31 +1615,45 @@ Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
if (!constructor.matched)
return add_error(peek(), "missing constructor for const declaration");
auto* var = create<ast::Variable>(decl->source, decl->name,
ast::StorageClass::kNone, decl->type);
var->set_is_const(true);
var->set_constructor(constructor.value);
auto* var =
create<ast::Variable>(decl->source, // source
decl->name, // name
ast::StorageClass::kNone, // storage_class
decl->type, // type
true, // is_const
constructor.value, // constructor
ast::VariableDecorationList{}); // decorations
return create<ast::VariableDeclStatement>(decl->source, var);
}
auto var = variable_decl();
if (var.errored)
auto decl = variable_decl();
if (decl.errored)
return Failure::kErrored;
if (!var.matched)
if (!decl.matched)
return Failure::kNoMatch;
ast::Expression* constructor = nullptr;
if (match(Token::Type::kEqual)) {
auto constructor = logical_or_expression();
if (constructor.errored)
auto constructor_expr = logical_or_expression();
if (constructor_expr.errored)
return Failure::kErrored;
if (!constructor.matched)
if (!constructor_expr.matched)
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

View File

@ -262,6 +262,18 @@ class ParserImpl {
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
/// @param file the input source file to parse
explicit ParserImpl(Source::File const* file);
@ -356,8 +368,8 @@ class ParserImpl {
/// @returns the const object or nullptr
Maybe<ast::Variable*> global_constant_decl();
/// Parses a `variable_decl` grammar element
/// @returns the parsed variable or nullptr otherwise
Maybe<ast::Variable*> variable_decl();
/// @returns the parsed variable declaration info
Maybe<VarDeclInfo> variable_decl();
/// Parses a `variable_ident_decl` grammar element, erroring on parse
/// failure.
/// @param use a description of what was being parsed if an error was raised.

View File

@ -13,8 +13,8 @@
// limitations under the License.
#include "gtest/gtest.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decoration.h"
#include "src/reader/wgsl/parser_impl.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"

View File

@ -13,9 +13,9 @@
// limitations under the License.
#include "gtest/gtest.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decoration.h"
#include "src/reader/wgsl/parser_impl.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);
ASSERT_EQ(e->constructor(), nullptr);
ASSERT_FALSE(e->Is<ast::DecoratedVariable>());
}
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
@ -72,8 +71,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
ASSERT_NE(e->constructor(), nullptr);
ASSERT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->constructor()->Is<ast::ScalarConstructorExpression>());
ASSERT_FALSE(e->Is<ast::DecoratedVariable>());
}
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
@ -86,7 +83,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
EXPECT_EQ(e->name(), "a");
ASSERT_NE(e->type(), nullptr);
@ -100,10 +96,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
ASSERT_EQ(e->constructor(), nullptr);
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
auto* v = e->As<ast::DecoratedVariable>();
auto& decorations = v->decorations();
auto& decorations = e->decorations();
ASSERT_EQ(decorations.size(), 2u);
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
ASSERT_TRUE(decorations[1]->Is<ast::SetDecoration>());
@ -120,7 +113,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
EXPECT_EQ(e->name(), "a");
ASSERT_NE(e->type(), nullptr);
@ -134,10 +126,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
ASSERT_EQ(e->constructor(), nullptr);
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
auto* v = e->As<ast::DecoratedVariable>();
auto& decorations = v->decorations();
auto& decorations = e->decorations();
ASSERT_EQ(decorations.size(), 2u);
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
ASSERT_TRUE(decorations[1]->Is<ast::SetDecoration>());

View File

@ -25,25 +25,23 @@ namespace {
TEST_F(ParserImplTest, VariableDecl_Parses) {
auto p = parser("var my_var : f32");
auto var = p->variable_decl();
auto v = p->variable_decl();
EXPECT_FALSE(p->has_error());
EXPECT_TRUE(var.matched);
EXPECT_FALSE(var.errored);
ASSERT_NE(var.value, nullptr);
EXPECT_EQ(var->name(), "my_var");
EXPECT_NE(var->type(), nullptr);
EXPECT_TRUE(var->type()->Is<ast::type::F32>());
EXPECT_TRUE(v.matched);
EXPECT_FALSE(v.errored);
EXPECT_EQ(v->name, "my_var");
EXPECT_NE(v->type, nullptr);
EXPECT_TRUE(v->type->Is<ast::type::F32>());
EXPECT_EQ(var->source().range.begin.line, 1u);
EXPECT_EQ(var->source().range.begin.column, 5u);
EXPECT_EQ(var->source().range.end.line, 1u);
EXPECT_EQ(var->source().range.end.column, 11u);
EXPECT_EQ(v->source.range.begin.line, 1u);
EXPECT_EQ(v->source.range.begin.column, 5u);
EXPECT_EQ(v->source.range.end.line, 1u);
EXPECT_EQ(v->source.range.end.column, 11u);
}
TEST_F(ParserImplTest, VariableDecl_MissingVar) {
auto p = parser("my_var : f32");
auto v = p->variable_decl();
EXPECT_EQ(v.value, nullptr);
EXPECT_FALSE(v.matched);
EXPECT_FALSE(v.errored);
EXPECT_FALSE(p->has_error());
@ -58,7 +56,6 @@ TEST_F(ParserImplTest, VariableDecl_InvalidIdentDecl) {
EXPECT_FALSE(v.matched);
EXPECT_TRUE(v.errored);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(v.value, nullptr);
EXPECT_EQ(p->error(), "1:12: expected ':' for variable declaration");
}
@ -68,15 +65,14 @@ TEST_F(ParserImplTest, VariableDecl_WithStorageClass) {
EXPECT_TRUE(v.matched);
EXPECT_FALSE(v.errored);
EXPECT_FALSE(p->has_error());
ASSERT_NE(v.value, nullptr);
EXPECT_EQ(v->name(), "my_var");
EXPECT_TRUE(v->type()->Is<ast::type::F32>());
EXPECT_EQ(v->storage_class(), ast::StorageClass::kPrivate);
EXPECT_EQ(v->name, "my_var");
EXPECT_TRUE(v->type->Is<ast::type::F32>());
EXPECT_EQ(v->storage_class, ast::StorageClass::kPrivate);
EXPECT_EQ(v->source().range.begin.line, 1u);
EXPECT_EQ(v->source().range.begin.column, 14u);
EXPECT_EQ(v->source().range.end.line, 1u);
EXPECT_EQ(v->source().range.end.column, 20u);
EXPECT_EQ(v->source.range.begin.line, 1u);
EXPECT_EQ(v->source.range.begin.column, 14u);
EXPECT_EQ(v->source.range.end.line, 1u);
EXPECT_EQ(v->source.range.end.column, 20u);
}
TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
@ -85,7 +81,6 @@ TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
EXPECT_FALSE(v.matched);
EXPECT_TRUE(v.errored);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(v.value, nullptr);
EXPECT_EQ(p->error(), "1:5: invalid storage class for variable decoration");
}

View File

@ -33,8 +33,8 @@ TEST_F(ScopeStackTest, Global) {
TEST_F(ScopeStackTest, Global_SetWithPointer) {
ast::type::F32 f32;
ast::Variable v(Source{}, "test", ast::StorageClass::kNone, &f32);
v.set_name("my_var");
ast::Variable v(Source{}, "my_var", ast::StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
ScopeStack<ast::Variable*> s;
s.set_global("var", &v);

View File

@ -122,8 +122,7 @@ TEST_F(BoundArrayAccessorsTest, Ptrs_Clamp) {
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
Const("c", ast::StorageClass::kFunction, ty.u32);
Const("b", ast::StorageClass::kFunction,
ty.pointer<f32>(ast::StorageClass::kFunction))
->set_constructor(Index("a", "c"));
ty.pointer<f32>(ast::StorageClass::kFunction), Index("a", "c"), {});
}
};
@ -171,8 +170,8 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Nested_Scalar) {
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
Var("b", ast::StorageClass::kFunction, ty.array<f32, 5>());
Var("i", ast::StorageClass::kFunction, ty.u32);
Const("c", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", Index("b", "i")));
Const("c", ast::StorageClass::kFunction, ty.f32,
Index("a", Index("b", "i")), {});
}
};
@ -241,8 +240,7 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Scalar) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.array(ty.f32, 3));
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", 1u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 1u), {});
}
};
@ -274,8 +272,8 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Expr) {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
Var("c", ast::StorageClass::kFunction, ty.u32);
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", Add("c", Sub(2u, 3u))));
Var("b", ast::StorageClass::kFunction, ty.f32,
Index("a", Add("c", Sub(2u, 3u))), {});
}
};
@ -340,8 +338,7 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_Negative) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", -1));
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", -1), {});
}
};
@ -371,8 +368,7 @@ TEST_F(BoundArrayAccessorsTest, Array_Idx_OutOfBounds) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.array<f32, 3>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", 3u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 3u), {});
}
};
@ -402,8 +398,7 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_Scalar) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", 1u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 1u), {});
}
};
@ -435,8 +430,8 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_Expr) {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
Var("c", ast::StorageClass::kFunction, ty.u32);
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", Add("c", Sub(2u, 3u))));
Var("b", ast::StorageClass::kFunction, ty.f32,
Index("a", Add("c", Sub(2u, 3u))), {});
}
};
@ -499,8 +494,7 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_Negative) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", -1));
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", -1), {});
}
};
@ -530,8 +524,7 @@ TEST_F(BoundArrayAccessorsTest, Vector_Idx_OutOfBounds) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.vec3<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index("a", 3u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index("a", 3u), {});
}
};
@ -561,8 +554,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Scalar) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", 2u), 1u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 2u), 1u),
{});
}
};
@ -607,8 +600,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Expr_Column) {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("c", ast::StorageClass::kFunction, ty.u32);
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", Add("c", Sub(2u, 3u))), 1u));
Var("b", ast::StorageClass::kFunction, ty.f32,
Index(Index("a", Add("c", Sub(2u, 3u))), 1u), {});
}
};
@ -687,8 +680,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Expr_Row) {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("c", ast::StorageClass::kFunction, ty.u32);
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", 1u), Add("c", Sub(2u, 3u))));
Var("b", ast::StorageClass::kFunction, ty.f32,
Index(Index("a", 1u), Add("c", Sub(2u, 3u))), {});
}
};
@ -765,8 +758,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Negative_Column) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", -1), 1));
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", -1), 1),
{});
}
};
@ -809,8 +802,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_Negative_Row) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", 2), -1));
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 2), -1),
{});
}
};
@ -853,8 +846,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_OutOfBounds_Column) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", 5u), 1u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 5u), 1u),
{});
}
};
@ -897,8 +890,8 @@ TEST_F(BoundArrayAccessorsTest, Matrix_Idx_OutOfBounds_Row) {
struct Builder : ModuleBuilder {
void Build() override {
Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
Var("b", ast::StorageClass::kFunction, ty.f32)
->set_constructor(Index(Index("a", 2u), 5u));
Var("b", ast::StorageClass::kFunction, ty.f32, Index(Index("a", 2u), 5u),
{});
}
};

View File

@ -19,12 +19,12 @@
#include "src/ast/assignment_statement.h"
#include "src/ast/block_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type_manager.h"
#include "src/ast/variable.h"
namespace tint {
namespace transform {
@ -51,11 +51,17 @@ Transform::Output EmitVertexPointSize::Run(ast::Module* in) {
// Declare the pointsize builtin output variable.
auto* pointsize_var =
mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
Source{}, kPointSizeVar, ast::StorageClass::kOutput, f32));
pointsize_var->set_decorations({
mod->create<ast::BuiltinDecoration>(ast::Builtin::kPointSize, Source{}),
});
mod->create<ast::Variable>(Source{}, // source
kPointSizeVar, // name
ast::StorageClass::kOutput, // storage_class
f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
mod->create<ast::BuiltinDecoration>(
ast::Builtin::kPointSize, Source{}),
});
mod->AddGlobalVariable(pointsize_var);
// Build the AST expression & statement for assigning pointsize one.

View File

@ -83,7 +83,7 @@ TEST_F(EmitVertexPointSizeTest, VertexStageBasic) {
<< diag::Formatter().format(result.diagnostics);
auto* expected = R"(Module{
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{pointsize}
}
@ -148,7 +148,7 @@ TEST_F(EmitVertexPointSizeTest, VertexStageEmpty) {
<< diag::Formatter().format(result.diagnostics);
auto* expected = R"(Module{
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{pointsize}
}

View File

@ -27,7 +27,6 @@
#include "src/ast/case_statement.h"
#include "src/ast/clone_context.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/else_statement.h"
#include "src/ast/expression.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 kIndexOffsetPrefix[] = "tint_first_index_offset_";
ast::DecoratedVariable* clone_variable_with_new_name(ast::CloneContext* ctx,
ast::DecoratedVariable* in,
std::string new_name) {
auto* var = ctx->mod->create<ast::Variable>(ctx->Clone(in->source()),
new_name, in->storage_class(),
ctx->Clone(in->type()));
var->set_is_const(in->is_const());
var->set_constructor(ctx->Clone(in->constructor()));
auto* out = ctx->mod->create<ast::DecoratedVariable>(var);
out->set_decorations(ctx->Clone(in->decorations()));
return out;
ast::Variable* clone_variable_with_new_name(ast::CloneContext* ctx,
ast::Variable* in,
std::string new_name) {
return ctx->mod->create<ast::Variable>(
ctx->Clone(in->source()), // source
new_name, // name
in->storage_class(), // storage_class
ctx->Clone(in->type()), // type
in->is_const(), // is_const
ctx->Clone(in->constructor()), // constructor
ctx->Clone(in->decorations())); // decorations
}
} // namespace
@ -86,7 +84,7 @@ FirstIndexOffset::~FirstIndexOffset() = default;
Transform::Output FirstIndexOffset::Run(ast::Module* in) {
// First do a quick check to see if the transform has already been applied.
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) {
diag::Diagnostic err;
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
// these builtins.
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()) {
if (auto* blt_dec = dec->As<ast::BuiltinDecoration>()) {
ast::Builtin blt_type = blt_dec->value();
@ -229,13 +227,17 @@ ast::Variable* FirstIndexOffset::AddUniformBuffer(ast::Module* mod) {
kStructName,
mod->create<ast::Struct>(std::move(decos), std::move(members)));
auto* idx_var =
mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
Source{}, kBufferName, ast::StorageClass::kUniform, struct_type));
idx_var->set_decorations({
mod->create<ast::BindingDecoration>(binding_, Source{}),
mod->create<ast::SetDecoration>(set_, Source{}),
});
auto* idx_var = mod->create<ast::Variable>(
Source{}, // source
kBufferName, // name
ast::StorageClass::kUniform, // storage_class
struct_type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
mod->create<ast::BindingDecoration>(binding_, Source{}),
mod->create<ast::SetDecoration>(set_, Source{}),
}); // decorations
mod->AddGlobalVariable(idx_var);
@ -250,16 +252,20 @@ ast::VariableDeclStatement* FirstIndexOffset::CreateFirstIndexOffset(
ast::Variable* buffer_var,
ast::Module* mod) {
auto* buffer = mod->create<ast::IdentifierExpression>(buffer_var->name());
auto* var = mod->create<ast::Variable>(Source{}, original_name,
ast::StorageClass::kNone,
mod->create<ast::type::U32>());
var->set_is_const(true);
var->set_constructor(mod->create<ast::BinaryExpression>(
auto* constructor = mod->create<ast::BinaryExpression>(
ast::BinaryOp::kAdd,
mod->create<ast::IdentifierExpression>(kIndexOffsetPrefix + var->name()),
mod->create<ast::IdentifierExpression>(kIndexOffsetPrefix +
original_name),
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);
}

View File

@ -25,7 +25,6 @@
#include "src/ast/builtin_decoration.h"
#include "src/ast/call_expression.h"
#include "src/ast/call_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/module.h"
@ -52,12 +51,9 @@ struct ModuleBuilder : public ast::BuilderWithModule {
protected:
void AddBuiltinInput(const std::string& name, ast::Builtin builtin) {
auto* var = Var(name, ast::StorageClass::kInput, ty.u32);
auto* dec_var = create<ast::DecoratedVariable>(var);
ast::VariableDecorationList decs;
decs.push_back(create<ast::BuiltinDecoration>(builtin, Source{}));
dec_var->set_decorations(std::move(decs));
mod->AddGlobalVariable(dec_var);
mod->AddGlobalVariable(
Var(name, ast::StorageClass::kInput, ty.u32, nullptr,
{create<ast::BuiltinDecoration>(builtin, Source{})}));
}
ast::Function* AddFunction(const std::string& name,
@ -141,7 +137,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
[[block]]
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -149,7 +145,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
in
__u32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{1}
SetDecoration{2}
@ -216,7 +212,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
[[block]]
StructMember{[[ offset 0 ]] tint_first_instance_index: __u32}
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{instance_idx}
}
@ -224,7 +220,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
in
__u32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{1}
SetDecoration{7}
@ -296,7 +292,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
StructMember{[[ offset 4 ]] tint_first_instance_index: __u32}
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{instance_idx}
}
@ -304,7 +300,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
in
__u32
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -312,7 +308,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
in
__u32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{1}
SetDecoration{7}
@ -376,7 +372,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) {
[[block]]
StructMember{[[ offset 0 ]] tint_first_vertex_index: __u32}
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -384,7 +380,7 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) {
in
__u32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{2}
SetDecoration{2}

View File

@ -20,7 +20,6 @@
#include "src/ast/assignment_statement.h"
#include "src/ast/binary_expression.h"
#include "src/ast/bitcast_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/member_accessor_expression.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/stride_decoration.h"
@ -37,6 +36,7 @@
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/uint_literal.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
namespace tint {
@ -143,13 +143,11 @@ void VertexPulling::State::FindOrInsertVertexIndexIfUsed() {
continue;
}
if (auto* decorated = v->As<ast::DecoratedVariable>()) {
for (auto* d : decorated->decorations()) {
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
if (builtin->value() == ast::Builtin::kVertexIdx) {
vertex_index_name = v->name();
return;
}
for (auto* d : v->decorations()) {
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
if (builtin->value() == ast::Builtin::kVertexIdx) {
vertex_index_name = v->name();
return;
}
}
}
@ -158,14 +156,19 @@ void VertexPulling::State::FindOrInsertVertexIndexIfUsed() {
// We didn't find a vertex index builtin, so create one
vertex_index_name = kDefaultVertexIndexName;
auto* var = mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
Source{}, vertex_index_name, ast::StorageClass::kInput, GetI32Type()));
auto* var =
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);
}
@ -187,13 +190,11 @@ void VertexPulling::State::FindOrInsertInstanceIndexIfUsed() {
continue;
}
if (auto* decorated = v->As<ast::DecoratedVariable>()) {
for (auto* d : decorated->decorations()) {
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
if (builtin->value() == ast::Builtin::kInstanceIdx) {
instance_index_name = v->name();
return;
}
for (auto* d : v->decorations()) {
if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
if (builtin->value() == ast::Builtin::kInstanceIdx) {
instance_index_name = v->name();
return;
}
}
}
@ -202,14 +203,18 @@ void VertexPulling::State::FindOrInsertInstanceIndexIfUsed() {
// We didn't find an instance index builtin, so create one
instance_index_name = kDefaultInstanceIndexName;
auto* var = mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
Source{}, instance_index_name, ast::StorageClass::kInput, GetI32Type()));
ast::VariableDecorationList decorations;
decorations.push_back(mod->create<ast::BuiltinDecoration>(
ast::Builtin::kInstanceIdx, Source{}));
var->set_decorations(std::move(decorations));
auto* var =
mod->create<ast::Variable>(Source{}, // source
instance_index_name, // name
ast::StorageClass::kInput, // storage_class
GetI32Type(), // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
mod->create<ast::BuiltinDecoration>(
ast::Builtin::kInstanceIdx, Source{}),
});
mod->AddGlobalVariable(var);
}
@ -219,18 +224,22 @@ void VertexPulling::State::ConvertVertexInputVariablesToPrivate() {
continue;
}
if (auto* decorated = v->As<ast::DecoratedVariable>()) {
for (auto* d : decorated->decorations()) {
if (auto* l = d->As<ast::LocationDecoration>()) {
uint32_t location = l->value();
// This is where the replacement happens. Expressions use identifier
// strings instead of pointers, so we don't need to update any other
// place in the AST.
v = mod->create<ast::Variable>(
Source{}, v->name(), ast::StorageClass::kPrivate, v->type());
location_to_var[location] = v;
break;
}
for (auto* d : v->decorations()) {
if (auto* l = d->As<ast::LocationDecoration>()) {
uint32_t location = l->value();
// This is where the replacement happens. Expressions use identifier
// strings instead of pointers, so we don't need to update any other
// place in the AST.
v = mod->create<ast::Variable>(
Source{}, // source
v->name(), // name
ast::StorageClass::kPrivate, // storage_class
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) {
// The decorated variable with struct type
auto* var = mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>(
Source{}, GetVertexBufferName(i), ast::StorageClass::kStorageBuffer,
struct_type));
// Add decorations
ast::VariableDecorationList decorations;
decorations.push_back(mod->create<ast::BindingDecoration>(i, Source{}));
decorations.push_back(
mod->create<ast::SetDecoration>(cfg.pulling_set, Source{}));
var->set_decorations(std::move(decorations));
auto* var = mod->create<ast::Variable>(
Source{}, // source
GetVertexBufferName(i), // name
ast::StorageClass::kStorageBuffer, // storage_class
struct_type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
mod->create<ast::BindingDecoration>(i, Source{}),
mod->create<ast::SetDecoration>(cfg.pulling_set, Source{}),
});
mod->AddGlobalVariable(var);
}
mod->AddConstructedType(struct_type);
@ -288,9 +298,15 @@ void VertexPulling::State::AddVertexPullingPreamble(
auto* block = mod->create<ast::BlockStatement>();
// Declare the |kPullingPosVarName| variable in the shader
auto* pos_declaration = mod->create<ast::VariableDeclStatement>(
mod->create<ast::Variable>(Source{}, kPullingPosVarName,
ast::StorageClass::kFunction, GetI32Type()));
auto* pos_declaration =
mod->create<ast::VariableDeclStatement>(mod->create<ast::Variable>(
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
// declare a variable in the shader to avoid having to reuse Expression

View File

@ -17,7 +17,6 @@
#include <utility>
#include "gtest/gtest.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/function.h"
#include "src/ast/pipeline_stage.h"
#include "src/ast/stage_decoration.h"
@ -25,6 +24,7 @@
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/void_type.h"
#include "src/ast/variable.h"
#include "src/diagnostic/formatter.h"
#include "src/transform/manager.h"
#include "src/type_determiner.h"
@ -69,13 +69,18 @@ class VertexPullingHelper {
void AddVertexInputVariable(uint32_t location,
std::string name,
ast::type::Type* type) {
auto* var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, name, ast::StorageClass::kInput, type));
auto* var = create<ast::Variable>(
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);
}
@ -171,7 +176,7 @@ TEST_F(VertexPullingTest, OneAttribute) {
private
__f32
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -179,7 +184,7 @@ TEST_F(VertexPullingTest, OneAttribute) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{0}
SetDecoration{4}
@ -257,7 +262,7 @@ TEST_F(VertexPullingTest, OneInstancedAttribute) {
private
__f32
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{instance_idx}
}
@ -265,7 +270,7 @@ TEST_F(VertexPullingTest, OneInstancedAttribute) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{0}
SetDecoration{4}
@ -343,7 +348,7 @@ TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet) {
private
__f32
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -351,7 +356,7 @@ TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{0}
SetDecoration{5}
@ -416,31 +421,30 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
AddVertexInputVariable(1, "var_b", &f32);
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;
decorations.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kVertexIdx, Source{}));
mod()->AddGlobalVariable(create<ast::Variable>(
Source{}, // 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(vertex_index_var);
}
{
auto* instance_index_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "custom_instance_index",
ast::StorageClass::kInput, &i32));
ast::VariableDecorationList decorations;
decorations.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kInstanceIdx, Source{}));
instance_index_var->set_decorations(decorations);
mod()->AddGlobalVariable(instance_index_var);
}
mod()->AddGlobalVariable(create<ast::Variable>(
Source{}, // source
"custom_instance_index", // name
ast::StorageClass::kInput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BuiltinDecoration>(ast::Builtin::kInstanceIdx, Source{}),
}));
InitTransform(
{{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}},
@ -464,7 +468,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
private
__f32
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -472,7 +476,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{instance_idx}
}
@ -480,7 +484,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{0}
SetDecoration{4}
@ -489,7 +493,7 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
storage_buffer
__struct_TintVertexData
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{1}
SetDecoration{4}
@ -605,7 +609,7 @@ TEST_F(VertexPullingTest, TwoAttributesSameBuffer) {
private
__array__f32_4
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -613,7 +617,7 @@ TEST_F(VertexPullingTest, TwoAttributesSameBuffer) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{0}
SetDecoration{4}
@ -796,7 +800,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
private
__array__f32_4
}
DecoratedVariable{
Variable{
Decorations{
BuiltinDecoration{vertex_idx}
}
@ -804,7 +808,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
in
__i32
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{0}
SetDecoration{4}
@ -813,7 +817,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
storage_buffer
__struct_TintVertexData
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{1}
SetDecoration{4}
@ -822,7 +826,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) {
storage_buffer
__struct_TintVertexData
}
DecoratedVariable{
Variable{
Decorations{
BindingDecoration{2}
SetDecoration{4}

File diff suppressed because it is too large Load Diff

View File

@ -43,10 +43,15 @@ TEST_F(ValidateControlBlockTest, SwitchSelectorExpressionNoneIntegerType_Fail) {
// default: {}
// }
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&f32, 3.14f)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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 =
create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
@ -72,10 +77,15 @@ TEST_F(ValidateControlBlockTest, SwitchWithoutDefault_Fail) {
// case 1: {}
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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");
ast::CaseSelectorList csl;
@ -104,10 +114,15 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) {
// default: {}
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::IdentifierExpression>("a");
@ -148,10 +163,15 @@ TEST_F(ValidateControlBlockTest,
// }
ast::type::U32 u32;
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::IdentifierExpression>("a");
@ -185,10 +205,15 @@ TEST_F(ValidateControlBlockTest,
// }
ast::type::U32 u32;
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &u32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::UintLiteral>(&u32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::IdentifierExpression>("a");
@ -221,10 +246,15 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) {
// default: {}
// }
ast::type::U32 u32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &u32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::UintLiteral>(&u32, 3)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::IdentifierExpression>("a");
@ -263,10 +293,15 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) {
// default: {}
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::IdentifierExpression>("a");
@ -305,10 +340,15 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) {
// default: { fallthrough; }
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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");
ast::CaseSelectorList default_csl;
@ -336,10 +376,15 @@ TEST_F(ValidateControlBlockTest, SwitchCase_Pass) {
// case 5: {}
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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");
ast::CaseSelectorList default_csl;
@ -370,10 +415,15 @@ TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
ast::type::U32 u32;
ast::type::Alias my_int{"MyInt", &u32};
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &my_int);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&u32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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");
ast::CaseSelectorList default_csl;

View File

@ -39,10 +39,15 @@ TEST_F(ValidateFunctionTest, VoidFunctionEndWithoutReturnStatement_Pass) {
// [[stage(vertex)]]
// fn func -> void { var a:i32 = 2; }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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::type::Void void_type;
@ -81,10 +86,15 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
// fn func -> int { var a:i32 = 2; }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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::type::Void void_type;
@ -239,13 +249,18 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
// fn func() -> i32 {var a: i32 = func(); return 2; }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
ast::ExpressionList call_params;
auto* call_expr = create<ast::CallExpression>(
Source{Source::Location{12, 34}},
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;
auto* body0 = create<ast::BlockStatement>();
body0->append(create<ast::VariableDeclStatement>(var));
@ -292,7 +307,13 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
ast::type::Void void_type;
ast::VariableList params;
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>();
body->append(create<ast::ReturnStatement>(Source{}));
auto* func = create<ast::Function>(

View File

@ -115,10 +115,15 @@ TEST_F(ValidatorTest, AssignCompatibleTypes_Pass) {
// var a :i32 = 2;
// a = 2
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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* rhs = create<ast::ScalarConstructorExpression>(
@ -140,10 +145,16 @@ TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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* rhs = create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.3f));
@ -167,10 +178,15 @@ TEST_F(ValidatorTest, AssignCompatibleTypesInBlockStatement_Pass) {
// a = 2
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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* rhs = create<ast::ScalarConstructorExpression>(
@ -196,10 +212,15 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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* rhs = create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.3f));
@ -223,10 +244,14 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
// var<in> gloabl_var: f32;
ast::type::F32 f32;
auto* global_var =
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kInput, &f32);
mod()->AddGlobalVariable(global_var);
mod()->AddGlobalVariable(
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
"global_var", // name
ast::StorageClass::kInput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables()))
<< v()->error();
}
@ -234,24 +259,31 @@ TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
// var gloabl_var: f32;
ast::type::F32 f32;
auto* global_var =
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kNone, &f32);
mod()->AddGlobalVariable(global_var);
mod()->AddGlobalVariable(
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
"global_var", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod()));
EXPECT_EQ(v()->error(),
"12:34 v-0022: global variables must have a storage class");
}
TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
// const<in> gloabl_var: f32;
ast::type::F32 f32;
auto* global_var =
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kInput, &f32);
global_var->set_is_const(true);
mod()->AddGlobalVariable(global_var);
mod()->AddGlobalVariable(
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
"global_var", // name
ast::StorageClass::kInput, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod()));
EXPECT_EQ(
@ -262,12 +294,14 @@ TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
// const gloabl_var: f32;
ast::type::F32 f32;
auto* global_var =
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kNone, &f32);
global_var->set_is_const(true);
mod()->AddGlobalVariable(global_var);
mod()->AddGlobalVariable(
create<ast::Variable>(Source{Source::Location{12, 34}}, // source
"global_var", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod())) << v()->error();
}
@ -278,11 +312,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
// not_global_var = 3.14f;
// }
ast::type::F32 f32;
auto* global_var = create<ast::Variable>(Source{}, "global_var",
ast::StorageClass::kPrivate, &f32);
global_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.1)));
mod()->AddGlobalVariable(global_var);
mod()->AddGlobalVariable(create<ast::Variable>(
Source{}, // source
"global_var", // name
ast::StorageClass::kPrivate, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.1)), // constructor
ast::VariableDecorationList{})); // decorations
auto* lhs = create<ast::IdentifierExpression>(
Source{Source::Location{12, 34}}, "not_global_var");
@ -311,11 +349,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
ast::type::F32 f32;
ast::type::Void void_type;
auto* global_var = create<ast::Variable>(Source{}, "global_var",
ast::StorageClass::kPrivate, &f32);
global_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.1)));
mod()->AddGlobalVariable(global_var);
mod()->AddGlobalVariable(create<ast::Variable>(
Source{}, // source
"global_var", // name
ast::StorageClass::kPrivate, // storage_class
&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* rhs = create<ast::ScalarConstructorExpression>(
@ -344,10 +386,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) {
// a = 3.14;
// }
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.0)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::ScalarConstructorExpression>(
@ -379,10 +426,15 @@ TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) {
// if (true) { a = 3.14; }
// }
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.0)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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 =
create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
@ -411,17 +463,26 @@ TEST_F(ValidatorTest, GlobalVariableUnique_Pass) {
// var global_var1 : i32 = 0;
ast::type::F32 f32;
ast::type::I32 i32;
auto* var0 = create<ast::Variable>(Source{}, "global_var0",
ast::StorageClass::kPrivate, &f32);
var0->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 0.1)));
auto* var0 = create<ast::Variable>(
Source{}, // source
"global_var0", // name
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);
auto* var1 =
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var1",
ast::StorageClass::kPrivate, &f32);
var1->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 0)));
auto* var1 = create<ast::Variable>(
Source{Source::Location{12, 34}}, // source
"global_var1", // name
ast::StorageClass::kPrivate, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 0)), // constructor
ast::VariableDecorationList{}); // decorations
mod()->AddGlobalVariable(var1);
EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables()))
@ -433,17 +494,26 @@ TEST_F(ValidatorTest, GlobalVariableNotUnique_Fail) {
// var global_var : i32 = 0;
ast::type::F32 f32;
ast::type::I32 i32;
auto* var0 = create<ast::Variable>(Source{}, "global_var",
ast::StorageClass::kPrivate, &f32);
var0->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 0.1)));
auto* var0 = create<ast::Variable>(
Source{}, // source
"global_var", // name
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);
auto* var1 =
create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kPrivate, &f32);
var1->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 0)));
auto* var1 = create<ast::Variable>(
Source{Source::Location{12, 34}}, // source
"global_var", // name
ast::StorageClass::kPrivate, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 0)), // constructor
ast::VariableDecorationList{}); // decorations
mod()->AddGlobalVariable(var1);
EXPECT_FALSE(v()->ValidateGlobalVariables(mod()->global_variables()));
@ -457,11 +527,15 @@ TEST_F(ValidatorTest, AssignToConstant_Fail) {
// a = 2
// }
ast::type::I32 i32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
var->set_is_const(true);
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&i32, // type
true, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)), // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::IdentifierExpression>("a");
auto* rhs = create<ast::ScalarConstructorExpression>(
@ -489,16 +563,26 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
ast::type::Void void_type;
ast::type::F32 f32;
auto* global_var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32);
global_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.1)));
auto* global_var = create<ast::Variable>(
Source{}, // source
"a", // name
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);
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.0)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* body = create<ast::BlockStatement>();
body->append(create<ast::VariableDeclStatement>(
@ -522,15 +606,25 @@ TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
ast::type::Void void_type;
ast::type::I32 i32;
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &i32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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 =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 0.1)));
auto* var_a_float = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* body = create<ast::BlockStatement>();
@ -554,10 +648,15 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
// var a : f32 = 3.14;
// }
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.0)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::ScalarConstructorExpression>(
@ -565,10 +664,15 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
auto* body = create<ast::BlockStatement>();
body->append(create<ast::VariableDeclStatement>(var));
auto* var_a_float =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.14)));
auto* var_a_float = create<ast::Variable>(
Source{}, // source
"a", // name
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>();
outer_body->append(
@ -588,15 +692,25 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
// if (true) { var a : f32 = 2.0; }
// }
ast::type::F32 f32;
auto* var_a_float =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.14)));
auto* var_a_float = create<ast::Variable>(
Source{}, // source
"a", // name
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 =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.0)));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* cond = create<ast::ScalarConstructorExpression>(
@ -620,15 +734,25 @@ TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
// func1 { var a : f32 = 3.0; return; }
ast::type::F32 f32;
ast::type::Void void_type;
auto* var0 =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var0->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.0)));
auto* var0 = create<ast::Variable>(
Source{}, // source
"a", // name
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,
&void_type);
var1->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0)));
auto* var1 = create<ast::Variable>(
Source{}, // source
"a", // name
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;
auto* body0 = create<ast::BlockStatement>();
@ -663,7 +787,13 @@ TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {
// }
ast::type::I32 i32;
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);
auto* lhs = create<ast::IdentifierExpression>("a");

View File

@ -194,7 +194,13 @@ TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
ast::type::Array array(&i32, 0, ast::ArrayDecorationList{});
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::type::Void void_type;
auto* body = create<ast::BlockStatement>();

View File

@ -27,7 +27,7 @@
#include "src/ast/call_expression.h"
#include "src/ast/call_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/fallthrough_statement.h"
#include "src/ast/float_literal.h"
@ -56,6 +56,7 @@
#include "src/ast/type/void_type.h"
#include "src/ast/uint_literal.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
#include "src/writer/append_vector.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 {
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
if (decorated->HasLocationDecoration() ||
decorated->HasBuiltinDecoration()) {
return var->storage_class() == ast::StorageClass::kInput ||
var->storage_class() == ast::StorageClass::kOutput;
}
if (var->HasLocationDecoration() || var->HasBuiltinDecoration()) {
return var->storage_class() == ast::StorageClass::kInput ||
var->storage_class() == ast::StorageClass::kOutput;
}
return false;
}
@ -2237,7 +2235,7 @@ bool GeneratorImpl::EmitVariable(std::ostream& out,
make_indent(out);
// TODO(dsinclair): Handle variable decorations
if (var->Is<ast::DecoratedVariable>()) {
if (!var->decorations().empty()) {
error_ = "Variable decorations are not handled yet";
return false;
}
@ -2271,10 +2269,11 @@ bool GeneratorImpl::EmitProgramConstVariable(std::ostream& out,
const ast::Variable* var) {
make_indent(out);
auto* decorated = var->As<ast::DecoratedVariable>();
if (decorated != nullptr && !decorated->HasConstantIdDecoration()) {
error_ = "Decorated const values not valid";
return false;
for (auto* d : var->decorations()) {
if (!d->Is<ast::ConstantIdDecoration>()) {
error_ = "Decorated const values not valid";
return false;
}
}
if (!var->is_const()) {
error_ = "Expected a const value";
@ -2290,8 +2289,8 @@ bool GeneratorImpl::EmitProgramConstVariable(std::ostream& out,
out << pre.str();
}
if (decorated != nullptr && decorated->HasConstantIdDecoration()) {
auto const_id = decorated->constant_id();
if (var->HasConstantIdDecoration()) {
auto const_id = var->constant_id();
out << "#ifndef WGSL_SPEC_CONSTANT_" << const_id << std::endl;

View File

@ -62,10 +62,22 @@ TEST_P(HlslBinaryTest, Emit_f32) {
auto params = GetParam();
auto* left_var = create<ast::Variable>(Source{}, "left",
ast::StorageClass::kFunction, &f32);
auto* right_var = create<ast::Variable>(Source{}, "right",
ast::StorageClass::kFunction, &f32);
auto* left_var =
create<ast::Variable>(Source{}, // source
"left", // name
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* right = create<ast::IdentifierExpression>("right");
@ -84,10 +96,22 @@ TEST_P(HlslBinaryTest, Emit_u32) {
auto params = GetParam();
auto* left_var = create<ast::Variable>(Source{}, "left",
ast::StorageClass::kFunction, &u32);
auto* right_var = create<ast::Variable>(Source{}, "right",
ast::StorageClass::kFunction, &u32);
auto* left_var =
create<ast::Variable>(Source{}, // source
"left", // name
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* right = create<ast::IdentifierExpression>("right");
@ -106,10 +130,22 @@ TEST_P(HlslBinaryTest, Emit_i32) {
auto params = GetParam();
auto* left_var = create<ast::Variable>(Source{}, "left",
ast::StorageClass::kFunction, &i32);
auto* right_var = create<ast::Variable>(Source{}, "right",
ast::StorageClass::kFunction, &i32);
auto* left_var =
create<ast::Variable>(Source{}, // source
"left", // name
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* right = create<ast::IdentifierExpression>("right");
@ -199,8 +235,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar) {
ast::type::F32 f32;
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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* rhs = create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.f));
@ -218,8 +260,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix) {
ast::type::F32 f32;
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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>(
create<ast::FloatLiteral>(&f32, 1.f));
auto* rhs = create<ast::IdentifierExpression>("mat");
@ -238,8 +286,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector) {
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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");
ast::ExpressionList vals;
@ -265,8 +319,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix) {
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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;
vals.push_back(create<ast::ScalarConstructorExpression>(
@ -293,8 +353,14 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix) {
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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* rhs = create<ast::IdentifierExpression>("mat");
@ -489,11 +555,17 @@ TEST_F(HlslGeneratorImplTest_Binary, Decl_WithLogical) {
auto* c = create<ast::IdentifierExpression>("c");
auto* d = create<ast::IdentifierExpression>("d");
auto* var = create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction,
&bool_type);
var->set_constructor(create<ast::BinaryExpression>(
ast::BinaryOp::kLogicalOr,
create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, b, c), d));
auto* var = create<ast::Variable>(
Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&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);

View File

@ -16,7 +16,6 @@
#include <unordered_set>
#include "src/ast/assignment_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/location_decoration.h"
#include "src/ast/member_accessor_expression.h"
@ -52,13 +51,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -108,13 +123,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -165,13 +196,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -222,13 +269,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -275,17 +338,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
auto* foo_var =
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;
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
foo_var->set_decorations(decos);
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
bar_var->set_decorations(decos);
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -327,17 +402,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
auto* foo_var =
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;
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
foo_var->set_decorations(decos);
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
bar_var->set_decorations(decos);
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -386,15 +473,29 @@ TEST_F(HlslGeneratorImplTest_EntryPoint,
ast::type::Void void_type;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kInput, &vec4));
coord_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
auto* coord_var = create<ast::Variable>(
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{}),
});
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
depth_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
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(depth_var);

View File

@ -16,7 +16,6 @@
#include "src/ast/binary_expression.h"
#include "src/ast/binding_decoration.h"
#include "src/ast/call_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
@ -99,9 +98,21 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithParams) {
ast::VariableList params;
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(
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;
@ -126,13 +137,29 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::Void void_type;
ast::type::F32 f32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -179,16 +206,29 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kInput, &vec4));
auto* coord_var = create<ast::Variable>(
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(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
depth_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
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(depth_var);
@ -237,23 +277,33 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kUniform, // storage_class
&vec4, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("coord"),
create<ast::IdentifierExpression>("x")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -294,27 +344,37 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::Struct s("Uniforms", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "uniforms", ast::StorageClass::kUniform, &s));
auto* coord_var =
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);
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);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("uniforms"),
create<ast::IdentifierExpression>("coord")),
create<ast::IdentifierExpression>("x")));
create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("uniforms"),
create<ast::IdentifierExpression>("coord")),
create<ast::IdentifierExpression>("x")), // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>();
body->append(create<ast::VariableDeclStatement>(var));
@ -363,23 +423,33 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::Struct s("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("coord"),
create<ast::IdentifierExpression>("b")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -424,23 +494,33 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::Struct s("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadOnly, &s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("coord"),
create<ast::IdentifierExpression>("b")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -485,13 +565,18 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::Struct s("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
@ -534,17 +619,41 @@ TEST_F(
ast::type::Void void_type;
ast::type::F32 f32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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>(
create<ast::Variable>(Source{}, "val", ast::StorageClass::kOutput, &f32));
val_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* val_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -555,8 +664,14 @@ TEST_F(
mod.AddGlobalVariable(val_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::AssignmentStatement>(
@ -622,21 +737,31 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
ast::VariableDecorationList decos;
decos.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
depth_var->set_decorations(decos);
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
});
td.RegisterVariableForTesting(depth_var);
mod.AddGlobalVariable(depth_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -690,15 +815,29 @@ TEST_F(
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kInput, &vec4));
coord_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
auto* coord_var = create<ast::Variable>(
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{}),
});
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
depth_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
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(depth_var);
@ -707,8 +846,14 @@ TEST_F(
mod.AddGlobalVariable(depth_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::AssignmentStatement>(
@ -771,21 +916,32 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kUniform, // storage_class
&vec4, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -801,10 +957,15 @@ TEST_F(HlslGeneratorImplTest_Function,
expr.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f)));
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::CallExpression>(
create<ast::IdentifierExpression>("sub_func"), expr));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
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->append(create<ast::VariableDeclStatement>(var));
@ -841,21 +1002,32 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &vec4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -871,10 +1043,15 @@ TEST_F(HlslGeneratorImplTest_Function,
expr.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f)));
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::CallExpression>(
create<ast::IdentifierExpression>("sub_func"), expr));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
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->append(create<ast::VariableDeclStatement>(var));
@ -909,11 +1086,17 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::F32 f32;
ast::type::I32 i32;
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
ast::VariableDecorationList decos;
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
bar_var->set_decorations(decos);
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
mod.AddGlobalVariable(bar_var);
@ -1041,7 +1224,13 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
ast::VariableList params;
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;
@ -1095,13 +1284,18 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::type::Struct s("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(0, Source{}));
data_var->set_decorations(decos);
auto* data_var =
create<ast::Variable>(Source{}, // source
"data", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(0, Source{}),
});
mod.AddConstructedType(&s);
td.RegisterVariableForTesting(data_var);
@ -1109,11 +1303,16 @@ TEST_F(HlslGeneratorImplTest_Function,
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -1130,11 +1329,16 @@ TEST_F(HlslGeneratorImplTest_Function,
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));

View File

@ -268,8 +268,14 @@ TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
ast::type::F32 f32;
ast::type::Matrix mat(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "var",
ast::StorageClass::kFunction, &mat);
auto* var =
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;
params.push_back(create<ast::IdentifierExpression>("var"));

View File

@ -76,9 +76,21 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, DISABLED_Intrinsic_OuterProduct) {
ast::type::Vector vec3(&f32, 3);
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 =
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;
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::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec);
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec);
ast::Variable v1(Source{}, "param1", 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(&v2);

View File

@ -144,15 +144,26 @@ TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopWithVarUsedInContinuing) {
ast::type::F32 f32;
auto* var = create<ast::Variable>(Source{}, "lhs",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.4)));
auto* var = create<ast::Variable>(
Source{}, // source
"lhs", // name
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>();
body->append(create<ast::VariableDeclStatement>(var));
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
Source{}, "other", ast::StorageClass::kFunction, &f32)));
body->append(create<ast::VariableDeclStatement>(
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* rhs = create<ast::IdentifierExpression>("rhs");

View File

@ -17,7 +17,6 @@
#include "src/ast/array_accessor_expression.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/binary_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/member_accessor_expression.h"
@ -35,6 +34,7 @@
#include "src/ast/type/struct_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/variable.h"
#include "src/type_determiner.h"
#include "src/writer/hlsl/test_helper.h"
@ -57,8 +57,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
ast::type::Struct s("Str", strct);
auto* str_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "str", ast::StorageClass::kPrivate, &s));
auto* str_var =
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* mem = create<ast::IdentifierExpression>("mem");
@ -100,8 +106,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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"),
create<ast::IdentifierExpression>("b"));
@ -143,8 +155,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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"),
create<ast::IdentifierExpression>("a"));
@ -190,10 +208,22 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
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>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s);
auto* coord_var =
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>(
create<ast::IdentifierExpression>("data"),
@ -249,8 +279,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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>(
create<ast::IdentifierExpression>("data"),
@ -304,8 +340,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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"),
create<ast::IdentifierExpression>("a"));
@ -354,8 +396,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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"),
create<ast::IdentifierExpression>("a"));
@ -396,8 +444,14 @@ TEST_F(
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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"),
create<ast::IdentifierExpression>("a"));
@ -442,8 +496,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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(
create<ast::ArrayAccessorExpression>(
@ -491,8 +551,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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(
create<ast::MemberAccessorExpression>(
@ -537,8 +603,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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(
create<ast::MemberAccessorExpression>(
@ -593,8 +665,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -641,8 +719,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -693,8 +777,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -744,8 +834,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -790,8 +886,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct s("Data", str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &s));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -868,8 +970,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct pre_struct("Pre", pre_str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -939,8 +1047,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct pre_struct("Pre", pre_str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -1011,8 +1125,14 @@ TEST_F(
ast::type::Struct pre_struct("Pre", pre_str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -1082,8 +1202,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct pre_struct("Pre", pre_str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -1154,8 +1280,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct pre_struct("Pre", pre_str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
auto* coord_var =
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);
gen.register_global(coord_var);
@ -1237,8 +1369,14 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::type::Struct pre_struct("Pre", pre_str);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &pre_struct));
auto* coord_var =
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);
gen.register_global(coord_var);

View File

@ -16,7 +16,6 @@
#include <vector>
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h"
@ -45,10 +44,14 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
exprs.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f)));
auto* var =
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &ary);
var->set_is_const(true);
var->set_constructor(create<ast::TypeConstructorExpression>(&ary, exprs));
auto* var = create<ast::Variable>(
Source{}, // source
"pos", // name
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();
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) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
auto* var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32));
var->set_decorations(decos);
var->set_is_const(true);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f)));
auto* var = create<ast::Variable>(
Source{}, // source
"pos", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f)), // constructor
ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(23, Source{}),
});
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
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) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
auto* var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32));
var->set_decorations(decos);
var->set_is_const(true);
auto* var =
create<ast::Variable>(Source{}, // source
"pos", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(23, Source{}),
});
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23

View File

@ -35,7 +35,13 @@ using HlslGeneratorImplTest_VariableDecl = TestHelper;
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
ast::type::F32 f32;
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);
gen.increment_indent();
@ -47,8 +53,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_is_const(true);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);
gen.increment_indent();
@ -62,7 +73,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
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);
gen.increment_indent();
@ -75,7 +92,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
Emit_VariableDeclStatement_Function) {
ast::type::F32 f32;
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);
gen.increment_indent();
@ -87,7 +110,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
ast::type::F32 f32;
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);
gen.increment_indent();
@ -102,8 +131,13 @@ TEST_F(HlslGeneratorImplTest_VariableDecl,
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(ident);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
ident, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);
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* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec);
var->set_constructor(zero_vec);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&vec, // type
false, // is_const
zero_vec, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);
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* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &mat);
var->set_constructor(zero_mat);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&mat, // type
false, // is_const
zero_mat, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);
ASSERT_TRUE(gen.EmitStatement(out, &stmt)) << gen.error();

View File

@ -29,8 +29,8 @@
#include "src/ast/call_expression.h"
#include "src/ast/call_statement.h"
#include "src/ast/case_statement.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/float_literal.h"
@ -63,6 +63,7 @@
#include "src/ast/type/void_type.h"
#include "src/ast/uint_literal.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.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 {
auto* decorated = var->As<ast::DecoratedVariable>();
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::kOutput);
bool in_struct_has_builtin =
decorated != nullptr && decorated->HasBuiltinDecoration() &&
var != nullptr && var->HasBuiltinDecoration() &&
var->storage_class() == ast::StorageClass::kOutput;
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();
// TODO(dsinclair): Handle variable decorations
if (var->Is<ast::DecoratedVariable>()) {
if (!var->decorations().empty()) {
error_ = "Variable decorations are not handled yet";
return false;
}
if (var->is_const()) {
out_ << "const ";
}
@ -2051,10 +2050,11 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var, bool skip_constructor) {
bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
make_indent();
auto* decorated = var->As<ast::DecoratedVariable>();
if (decorated != nullptr && !decorated->HasConstantIdDecoration()) {
error_ = "Decorated const values not valid";
return false;
for (auto* d : var->decorations()) {
if (!d->Is<ast::ConstantIdDecoration>()) {
error_ = "Decorated const values not valid";
return false;
}
}
if (!var->is_const()) {
error_ = "Expected a const value";
@ -2069,8 +2069,8 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
out_ << " " << var->name();
}
if (decorated != nullptr && decorated->HasConstantIdDecoration()) {
out_ << " [[function_constant(" << decorated->constant_id() << ")]]";
if (var->HasConstantIdDecoration()) {
out_ << " [[function_constant(" << var->constant_id() << ")]]";
} else if (var->constructor() != nullptr) {
out_ << " = ";
if (!EmitExpression(var->constructor())) {

View File

@ -16,7 +16,6 @@
#include "gtest/gtest.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/location_decoration.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::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -105,13 +120,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Output) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -159,13 +190,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Input) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -212,13 +259,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Output) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -263,17 +326,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Input) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
auto* foo_var =
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;
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
foo_var->set_decorations(decos);
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kInput, &i32));
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
bar_var->set_decorations(decos);
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -313,17 +388,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Output) {
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kOutput, &f32));
auto* foo_var =
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;
decos.push_back(create<ast::LocationDecoration>(0, Source{}));
foo_var->set_decorations(decos);
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &i32));
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
bar_var->set_decorations(decos);
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -369,15 +456,29 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Builtins) {
ast::type::Void void_type;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kInput, &vec4));
coord_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
auto* coord_var = create<ast::Variable>(
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{}),
});
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
depth_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
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(depth_var);

View File

@ -17,7 +17,6 @@
#include "src/ast/binary_expression.h"
#include "src/ast/binding_decoration.h"
#include "src/ast/call_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
@ -106,9 +105,21 @@ TEST_F(MslGeneratorImplTest, Emit_Function_WithParams) {
ast::VariableList params;
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(
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;
@ -134,13 +145,29 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_WithInOutVars) {
ast::type::Void void_type;
ast::type::F32 f32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -190,15 +217,29 @@ TEST_F(MslGeneratorImplTest,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kInput, &vec4));
coord_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
auto* coord_var = create<ast::Variable>(
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{}),
});
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
depth_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
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(depth_var);
@ -246,24 +287,34 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_With_Uniform) {
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kUniform, // storage_class
&vec4, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("coord"),
create<ast::IdentifierExpression>("x")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -312,24 +363,34 @@ TEST_F(MslGeneratorImplTest,
mod.AddConstructedType(&s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("coord"),
create<ast::IdentifierExpression>("b")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -382,13 +443,18 @@ TEST_F(MslGeneratorImplTest,
mod.AddConstructedType(&s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
@ -396,11 +462,16 @@ TEST_F(MslGeneratorImplTest,
ast::VariableList params;
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("coord"),
create<ast::IdentifierExpression>("b")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -438,17 +509,41 @@ TEST_F(
ast::type::Void void_type;
ast::type::F32 f32;
auto* foo_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "foo", ast::StorageClass::kInput, &f32));
foo_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* foo_var =
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{}),
});
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
bar_var->set_decorations({create<ast::LocationDecoration>(1, Source{})});
auto* bar_var =
create<ast::Variable>(Source{}, // 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>(
create<ast::Variable>(Source{}, "val", ast::StorageClass::kOutput, &f32));
val_var->set_decorations({create<ast::LocationDecoration>(0, Source{})});
auto* val_var =
create<ast::Variable>(Source{}, // 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(bar_var);
@ -459,8 +554,14 @@ TEST_F(
mod.AddGlobalVariable(val_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::AssignmentStatement>(
@ -529,21 +630,31 @@ TEST_F(MslGeneratorImplTest,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
ast::VariableDecorationList decos;
decos.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
depth_var->set_decorations(decos);
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}),
});
td.RegisterVariableForTesting(depth_var);
mod.AddGlobalVariable(depth_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -601,15 +712,29 @@ TEST_F(
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kInput, &vec4));
coord_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{})});
auto* coord_var = create<ast::Variable>(
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{}),
});
auto* depth_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "depth", ast::StorageClass::kOutput, &f32));
depth_var->set_decorations(
{create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{})});
auto* depth_var = create<ast::Variable>(
Source{}, // source
"depth", // name
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(depth_var);
@ -618,8 +743,14 @@ TEST_F(
mod.AddGlobalVariable(depth_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::AssignmentStatement>(
@ -680,21 +811,32 @@ TEST_F(MslGeneratorImplTest,
ast::type::F32 f32;
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kUniform, &vec4));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kUniform, // storage_class
&vec4, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -710,10 +852,15 @@ TEST_F(MslGeneratorImplTest,
expr.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f)));
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::CallExpression>(
create<ast::IdentifierExpression>("sub_func"), expr));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
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->append(create<ast::VariableDeclStatement>(var));
@ -765,20 +912,31 @@ TEST_F(MslGeneratorImplTest,
mod.AddConstructedType(&s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -794,10 +952,15 @@ TEST_F(MslGeneratorImplTest,
expr.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f)));
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::CallExpression>(
create<ast::IdentifierExpression>("sub_func"), expr));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
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->append(create<ast::VariableDeclStatement>(var));
@ -855,20 +1018,31 @@ TEST_F(MslGeneratorImplTest,
mod.AddConstructedType(&s);
auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "coord", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
coord_var->set_decorations(decos);
auto* coord_var =
create<ast::Variable>(Source{}, // source
"coord", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
});
td.RegisterVariableForTesting(coord_var);
mod.AddGlobalVariable(coord_var);
ast::VariableList params;
params.push_back(create<ast::Variable>(Source{}, "param",
ast::StorageClass::kFunction, &f32));
params.push_back(
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>();
body->append(create<ast::ReturnStatement>(
@ -884,10 +1058,15 @@ TEST_F(MslGeneratorImplTest,
expr.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f)));
auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::CallExpression>(
create<ast::IdentifierExpression>("sub_func"), expr));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
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->append(create<ast::VariableDeclStatement>(var));
@ -929,11 +1108,17 @@ TEST_F(MslGeneratorImplTest,
ast::type::F32 f32;
ast::type::I32 i32;
auto* bar_var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "bar", ast::StorageClass::kOutput, &f32));
ast::VariableDecorationList decos;
decos.push_back(create<ast::LocationDecoration>(1, Source{}));
bar_var->set_decorations(decos);
auto* bar_var =
create<ast::Variable>(Source{}, // 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(bar_var);
mod.AddGlobalVariable(bar_var);
@ -1015,7 +1200,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
ast::VariableList params;
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;
@ -1072,13 +1263,18 @@ TEST_F(MslGeneratorImplTest,
ast::type::Struct s("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(0, Source{}));
data_var->set_decorations(decos);
auto* data_var =
create<ast::Variable>(Source{}, // source
"data", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(0, Source{}),
});
mod.AddConstructedType(&s);
@ -1087,11 +1283,16 @@ TEST_F(MslGeneratorImplTest,
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -1109,11 +1310,16 @@ TEST_F(MslGeneratorImplTest,
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));

View File

@ -267,8 +267,14 @@ TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
ast::type::F32 f32;
ast::type::Matrix mat(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "var",
ast::StorageClass::kFunction, &mat);
auto* var =
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;
params.push_back(create<ast::IdentifierExpression>("var"));

View File

@ -71,9 +71,21 @@ TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) {
ast::type::Vector vec3(&f32, 3);
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 =
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;
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::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec);
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec);
ast::Variable v1(Source{}, "param1", 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(&v2);

View File

@ -149,15 +149,26 @@ TEST_F(MslGeneratorImplTest, Emit_LoopWithVarUsedInContinuing) {
ast::type::F32 f32;
auto* var = create<ast::Variable>(Source{}, "lhs",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.4)));
auto* var = create<ast::Variable>(
Source{}, // source
"lhs", // name
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>();
body->append(create<ast::VariableDeclStatement>(var));
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
Source{}, "other", ast::StorageClass::kFunction, &f32)));
body->append(create<ast::VariableDeclStatement>(
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* rhs = create<ast::IdentifierExpression>("rhs");

View File

@ -17,7 +17,6 @@
#include "gtest/gtest.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h"
@ -47,10 +46,14 @@ TEST_F(MslGeneratorImplTest, Emit_ModuleConstant) {
exprs.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f)));
auto* var =
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &ary);
var->set_is_const(true);
var->set_constructor(create<ast::TypeConstructorExpression>(&ary, exprs));
auto* var = create<ast::Variable>(
Source{}, // source
"pos", // name
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();
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) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
auto* var = create<ast::DecoratedVariable>(
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32));
var->set_decorations(decos);
var->set_is_const(true);
var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f)));
auto* var = create<ast::Variable>(
Source{}, // source
"pos", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f)), // constructor
ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(23, Source{}),
});
ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");

View File

@ -43,7 +43,13 @@ using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
ast::type::F32 f32;
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);
@ -56,8 +62,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_is_const(true);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);
@ -72,7 +83,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) {
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
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);
@ -98,7 +115,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
ast::type::Struct s("S", str);
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);
@ -114,7 +137,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) {
ast::type::Vector vec(&f32, 2);
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);
@ -128,7 +157,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
ast::type::F32 f32;
ast::type::Matrix mat(&f32, 2, 3);
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);
@ -141,7 +176,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
ast::type::F32 f32;
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);
@ -156,8 +197,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32);
var->set_constructor(ident);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
ident, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);
@ -174,8 +220,13 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_ZeroVec) {
auto* zero_vec = create<ast::TypeConstructorExpression>(&vec, values);
auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec);
var->set_constructor(zero_vec);
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&vec, // type
false, // is_const
zero_vec, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var);

View File

@ -34,7 +34,6 @@
#include "src/ast/case_statement.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/float_literal.h"
@ -72,6 +71,7 @@
#include "src/ast/type_constructor_expression.h"
#include "src/ast/uint_literal.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
#include "src/writer/append_vector.h"
@ -739,8 +739,7 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
// one
// 2- If we don't have a constructor and we're an Output or Private variable
// then WGSL requires an initializer.
auto* decorated = var->As<ast::DecoratedVariable>();
if (decorated != nullptr && decorated->HasConstantIdDecoration()) {
if (var->HasConstantIdDecoration()) {
if (type->Is<ast::type::F32>()) {
ast::FloatLiteral l(type, 0.0f);
init_id = GenerateLiteralIfNeeded(var, &l);
@ -775,33 +774,31 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
push_type(spv::Op::OpVariable, std::move(ops));
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
for (auto* deco : decorated->decorations()) {
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
Operand::Int(ConvertBuiltin(builtin->value()))});
} else if (auto* location = deco->As<ast::LocationDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationLocation),
Operand::Int(location->value())});
} else if (auto* binding = deco->As<ast::BindingDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBinding),
Operand::Int(binding->value())});
} else if (auto* set = deco->As<ast::SetDecoration>()) {
push_annot(
spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationDescriptorSet),
Operand::Int(set->value())});
} else if (deco->Is<ast::ConstantIdDecoration>()) {
// Spec constants are handled elsewhere
} else {
error_ = "unknown decoration";
return false;
}
for (auto* deco : var->decorations()) {
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
Operand::Int(ConvertBuiltin(builtin->value()))});
} else if (auto* location = deco->As<ast::LocationDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationLocation),
Operand::Int(location->value())});
} else if (auto* binding = deco->As<ast::BindingDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBinding),
Operand::Int(binding->value())});
} else if (auto* set = deco->As<ast::SetDecoration>()) {
push_annot(spv::Op::OpDecorate, {Operand::Int(var_id),
Operand::Int(SpvDecorationDescriptorSet),
Operand::Int(set->value())});
} else if (deco->Is<ast::ConstantIdDecoration>()) {
// Spec constants are handled elsewhere
} else {
error_ = "unknown decoration";
return false;
}
}
scope_stack_.set_global(var->name(), var_id);
spirv_id_to_variable_[var_id] = var;
return true;
@ -1455,8 +1452,7 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Variable* var,
auto name = lit->name();
bool is_spec_constant = false;
if (var && var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
if (var && var->HasConstantIdDecoration()) {
name = "__spec" + name;
is_spec_constant = true;
}
@ -1470,10 +1466,9 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Variable* var,
auto result_id = result.to_i();
if (is_spec_constant) {
push_annot(
spv::Op::OpDecorate,
{Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
Operand::Int(var->As<ast::DecoratedVariable>()->constant_id())});
push_annot(spv::Op::OpDecorate,
{Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
Operand::Int(var->constant_id())});
}
if (auto* l = lit->As<ast::BoolLiteral>()) {

View File

@ -53,7 +53,8 @@ TEST_F(BuilderTest, ArrayAccessor) {
// vec3<f32> ary;
// 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* idx_expr = create<ast::ScalarConstructorExpression>(
@ -94,8 +95,10 @@ TEST_F(BuilderTest, Accessor_Array_LoadIndex) {
// idx : i32;
// ary[idx] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3);
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32);
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
nullptr, ast::VariableDecorationList{});
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32, false,
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>("ary");
auto* idx_expr = create<ast::IdentifierExpression>("idx");
@ -139,7 +142,8 @@ TEST_F(BuilderTest, ArrayAccessor_Dynamic) {
// vec3<f32> ary;
// 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");
@ -186,7 +190,8 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
// ary = array<vec3<f32>, 4>
// 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(
create<ast::ArrayAccessorExpression>(
@ -233,7 +238,8 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
// var a : array<vec3<f32>, 4>;
// 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(
create<ast::ArrayAccessorExpression>(
@ -289,7 +295,8 @@ TEST_F(BuilderTest, MemberAccessor) {
auto* s = create<ast::Struct>(members);
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"),
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::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::MemberAccessorExpression>(
@ -403,7 +411,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
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(
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::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>(
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::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type);
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32);
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
false, nullptr, ast::VariableDecorationList{});
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32,
false, nullptr, ast::VariableDecorationList{});
auto* lhs = create<ast::IdentifierExpression>("store");
@ -578,7 +590,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
// 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"),
create<ast::IdentifierExpression>("y"));
@ -613,7 +626,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
// 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"),
create<ast::IdentifierExpression>("yx"));
@ -647,7 +661,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
// 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(
create<ast::MemberAccessorExpression>(
@ -685,7 +700,8 @@ TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
// 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(
create<ast::MemberAccessorExpression>(
@ -723,7 +739,8 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
// 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(
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::Variable var(Source{}, "index", ast::StorageClass::kFunction,
&a_ary_type);
&a_ary_type, false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr(
create<ast::MemberAccessorExpression>(
@ -885,9 +902,9 @@ TEST_F(BuilderTest, Accessor_Array_Of_Vec) {
create<ast::FloatLiteral>(&f32, -0.5)),
}));
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &arr);
var.set_is_const(true);
var.set_constructor(create<ast::TypeConstructorExpression>(&arr, ary_params));
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &arr, true,
create<ast::TypeConstructorExpression>(&arr, ary_params),
ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
create<ast::ScalarConstructorExpression>(
@ -941,10 +958,10 @@ TEST_F(BuilderTest, Accessor_Const_Vec) {
vec_params.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 0.5)));
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &vec);
var.set_is_const(true);
var.set_constructor(
create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
ast::Variable var(
Source{}, "pos", ast::StorageClass::kPrivate, &vec, true,
create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)),
ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
create<ast::ScalarConstructorExpression>(

View File

@ -44,7 +44,8 @@ using BuilderTest = TestHelper;
TEST_F(BuilderTest, Assign_Var) {
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* val = create<ast::ScalarConstructorExpression>(
@ -78,7 +79,8 @@ TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
ast::type::F32 f32;
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");
ast::ExpressionList vals;
@ -128,7 +130,8 @@ TEST_F(BuilderTest, Assign_Var_Complex_ConstructorWithExtract) {
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"),
init);
@ -176,7 +179,8 @@ TEST_F(BuilderTest, Assign_Var_Complex_Constructor) {
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"),
init);
@ -223,7 +227,8 @@ TEST_F(BuilderTest, Assign_StructMember) {
auto* s = create<ast::Struct>(members);
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>(
create<ast::IdentifierExpression>("ident"),
@ -265,7 +270,8 @@ TEST_F(BuilderTest, Assign_Vector) {
ast::type::F32 f32;
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");
@ -312,7 +318,8 @@ TEST_F(BuilderTest, Assign_Vector_MemberByName) {
// 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>(
create<ast::IdentifierExpression>("var"),
@ -357,7 +364,8 @@ TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
// 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>(
create<ast::IdentifierExpression>("var"),

View File

@ -121,7 +121,8 @@ TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) {
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* rhs = create<ast::IdentifierExpression>("param");
@ -633,8 +634,14 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixScalar) {
ast::type::F32 f32;
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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* rhs = create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.f));
@ -666,8 +673,14 @@ TEST_F(BuilderTest, Binary_Multiply_ScalarMatrix) {
ast::type::F32 f32;
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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>(
create<ast::FloatLiteral>(&f32, 1.f));
auto* rhs = create<ast::IdentifierExpression>("mat");
@ -700,8 +713,14 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixVector) {
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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");
ast::ExpressionList vals;
@ -742,8 +761,14 @@ TEST_F(BuilderTest, Binary_Multiply_VectorMatrix) {
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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;
vals.push_back(create<ast::ScalarConstructorExpression>(
@ -785,8 +810,14 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixMatrix) {
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "mat",
ast::StorageClass::kFunction, &mat3);
auto* var =
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* rhs = create<ast::IdentifierExpression>("mat");
@ -861,14 +892,24 @@ OpBranch %7
TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
ast::type::Bool bool_type;
auto* a_var = create<ast::Variable>(Source{}, "a",
ast::StorageClass::kFunction, &bool_type);
a_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(&bool_type, true)));
auto* b_var = create<ast::Variable>(Source{}, "b",
ast::StorageClass::kFunction, &bool_type);
b_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(&bool_type, false)));
auto* a_var = create<ast::Variable>(
Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
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* rhs = create<ast::IdentifierExpression>("b");
@ -1047,14 +1088,24 @@ OpBranch %7
TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
ast::type::Bool bool_type;
auto* a_var = create<ast::Variable>(Source{}, "a",
ast::StorageClass::kFunction, &bool_type);
a_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(&bool_type, true)));
auto* b_var = create<ast::Variable>(Source{}, "b",
ast::StorageClass::kFunction, &bool_type);
b_var->set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(&bool_type, false)));
auto* a_var = create<ast::Variable>(
Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
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* rhs = create<ast::IdentifierExpression>("b");

View File

@ -41,16 +41,28 @@ TEST_F(BuilderTest, Block) {
// serves to prove the block code is pushing new scopes as needed.
ast::BlockStatement outer;
outer.append(create<ast::VariableDeclStatement>(create<ast::Variable>(
Source{}, "var", ast::StorageClass::kFunction, &f32)));
outer.append(create<ast::VariableDeclStatement>(
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>(
create<ast::IdentifierExpression>("var"),
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f))));
auto* inner = create<ast::BlockStatement>();
inner->append(create<ast::VariableDeclStatement>(create<ast::Variable>(
Source{}, "var", ast::StorageClass::kFunction, &f32)));
inner->append(create<ast::VariableDeclStatement>(
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>(
create<ast::IdentifierExpression>("var"),
create<ast::ScalarConstructorExpression>(

View File

@ -44,9 +44,21 @@ TEST_F(BuilderTest, Expression_Call) {
ast::VariableList func_params;
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(
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>();
body->append(create<ast::ReturnStatement>(
@ -109,9 +121,21 @@ TEST_F(BuilderTest, Statement_Call) {
ast::VariableList func_params;
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(
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>();
body->append(create<ast::ReturnStatement>(

View File

@ -103,11 +103,29 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUnusedInterfaceIds) {
});
auto* v_in =
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32);
auto* v_out = create<ast::Variable>(Source{}, "my_out",
ast::StorageClass::kOutput, &f32);
auto* v_wg = create<ast::Variable>(Source{}, "my_wg",
ast::StorageClass::kWorkgroup, &f32);
create<ast::Variable>(Source{}, // source
"my_in", // name
ast::StorageClass::kInput, // storage_class
&f32, // type
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_out)) << b.error();
@ -162,11 +180,29 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
});
auto* v_in =
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32);
auto* v_out = create<ast::Variable>(Source{}, "my_out",
ast::StorageClass::kOutput, &f32);
auto* v_wg = create<ast::Variable>(Source{}, "my_wg",
ast::StorageClass::kWorkgroup, &f32);
create<ast::Variable>(Source{}, // source
"my_in", // name
ast::StorageClass::kInput, // storage_class
&f32, // type
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_out);

View File

@ -17,7 +17,6 @@
#include "gtest/gtest.h"
#include "spirv/unified1/spirv.h"
#include "spirv/unified1/spirv.hpp11"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
@ -88,7 +87,13 @@ TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
ast::type::F32 f32;
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);
auto* body = create<ast::BlockStatement>();
@ -142,15 +147,23 @@ TEST_F(BuilderTest, Function_WithParams) {
ast::type::F32 f32;
ast::type::I32 i32;
ast::VariableList params;
auto* var_a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32);
var_a->set_is_const(true);
params.push_back(var_a);
auto* var_b =
create<ast::Variable>(Source{}, "b", ast::StorageClass::kFunction, &i32);
var_b->set_is_const(true);
params.push_back(var_b);
ast::VariableList params = {
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}), // decorations
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>();
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::AccessControl ac(ast::AccessControl::kReadWrite, &s);
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(0, Source{}));
data_var->set_decorations(decos);
auto* data_var =
create<ast::Variable>(Source{}, // source
"data", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(0, Source{}),
});
mod->AddConstructedType(&s);
@ -274,11 +292,16 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -296,11 +319,16 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));

View File

@ -19,7 +19,6 @@
#include "src/ast/binding_decoration.h"
#include "src/ast/builtin.h"
#include "src/ast/builtin_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/location_decoration.h"
#include "src/ast/scalar_constructor_expression.h"
@ -47,7 +46,8 @@ using BuilderTest = TestHelper;
TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
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{});
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
@ -80,8 +80,8 @@ TEST_F(BuilderTest, FunctionVar_WithConstantConstructor) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
@ -126,8 +126,8 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructor) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kFunction, &vec);
v.set_constructor(init);
ast::Variable v(Source{}, "var", ast::StorageClass::kFunction, &vec, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
b.push_function(Function{});
@ -164,12 +164,13 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructorLoadedFromVar) {
ASSERT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32);
v.set_constructor(init);
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32);
v2.set_constructor(create<ast::IdentifierExpression>("v"));
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32, false,
create<ast::IdentifierExpression>("v"),
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v2);
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error();
@ -209,13 +210,13 @@ TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32);
v.set_constructor(init);
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32);
v2.set_is_const(true);
v2.set_constructor(create<ast::IdentifierExpression>("v"));
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32, true,
create<ast::IdentifierExpression>("v"),
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v2);
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error();
@ -257,9 +258,8 @@ TEST_F(BuilderTest, FunctionVar_Const) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
v.set_is_const(true);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);

View File

@ -20,7 +20,6 @@
#include "src/ast/builtin.h"
#include "src/ast/builtin_decoration.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/location_decoration.h"
#include "src/ast/module.h"
@ -52,7 +51,8 @@ using BuilderTest = TestHelper;
TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
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_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@ -66,7 +66,8 @@ TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
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_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@ -80,7 +81,8 @@ TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
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_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
@ -107,8 +109,9 @@ TEST_F(BuilderTest, GlobalVar_WithConstructor) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@ -142,9 +145,8 @@ TEST_F(BuilderTest, GlobalVar_Const) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
v.set_is_const(true);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@ -175,9 +177,8 @@ TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
v.set_is_const(true);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@ -214,9 +215,8 @@ TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
v.set_is_const(true);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@ -241,14 +241,18 @@ TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) {
TEST_F(BuilderTest, GlobalVar_WithLocation) {
ast::type::F32 f32;
auto* v =
create<ast::Variable>(Source{}, "var", ast::StorageClass::kOutput, &f32);
ast::VariableDecorationList decos;
decos.push_back(create<ast::LocationDecoration>(5, Source{}));
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(5, Source{}),
});
ast::DecoratedVariable dv(v);
dv.set_decorations(decos);
EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)");
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Location 5
@ -263,15 +267,19 @@ TEST_F(BuilderTest, GlobalVar_WithLocation) {
TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) {
ast::type::F32 f32;
auto* v =
create<ast::Variable>(Source{}, "var", ast::StorageClass::kOutput, &f32);
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(2, Source{}));
decos.push_back(create<ast::SetDecoration>(3, Source{}));
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(2, Source{}),
create<ast::SetDecoration>(3, Source{}),
});
ast::DecoratedVariable dv(v);
dv.set_decorations(decos);
EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)");
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Binding 2
@ -286,16 +294,19 @@ OpDecorate %1 DescriptorSet 3
TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
ast::type::F32 f32;
auto* v =
create<ast::Variable>(Source{}, "var", ast::StorageClass::kOutput, &f32);
ast::VariableDecorationList decos;
decos.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
auto* v = create<ast::Variable>(
Source{}, // source
"var", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}),
});
ast::DecoratedVariable dv(v);
dv.set_decorations(decos);
EXPECT_TRUE(b.GenerateGlobalVariable(&dv)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)");
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) {
ast::type::Bool bool_type;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(1200, Source{}));
auto* v = create<ast::Variable>(
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>(
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_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
)");
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) {
ast::type::Bool bool_type;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(1200, Source{}));
auto* v = create<ast::Variable>(
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>(
Source{}, "var", ast::StorageClass::kNone, &bool_type));
v.set_decorations(decos);
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.annots()), R"(OpDecorate %4 SpecId 1200
@ -356,16 +376,20 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
auto* v = create<ast::Variable>(
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(
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_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
)");
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) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
auto* v =
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(
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &f32));
v.set_decorations(decos);
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.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) {
ast::type::I32 i32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
auto* v =
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(
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &i32));
v.set_decorations(decos);
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.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) {
ast::type::U32 u32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
auto* v =
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(
create<ast::Variable>(Source{}, "var", ast::StorageClass::kNone, &u32));
v.set_decorations(decos);
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.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::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();
@ -529,7 +569,8 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) {
ast::type::Alias B("B", &A);
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();
@ -563,7 +604,8 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) {
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A};
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();
@ -597,8 +639,10 @@ TEST_F(BuilderTest, GlobalVar_TwoVarDeclReadOnly) {
ast::type::AccessControl read{ast::AccessControl::kReadOnly, &A};
ast::type::AccessControl rw{ast::AccessControl::kReadWrite, &A};
ast::Variable var_b(Source{}, "b", ast::StorageClass::kStorageBuffer, &read);
ast::Variable var_c(Source{}, "c", ast::StorageClass::kStorageBuffer, &rw);
ast::Variable var_b(Source{}, "b", ast::StorageClass::kStorageBuffer, &read,
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_c)) << b.error();
@ -629,8 +673,8 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) {
ast::type::ImageFormat::kR32Uint);
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant,
&type);
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant, &type,
false, nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
@ -650,8 +694,8 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) {
ast::type::ImageFormat::kR32Uint);
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant,
&type);
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant, &type,
false, nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();

View File

@ -53,9 +53,8 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
v.set_is_const(true);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
@ -77,7 +76,8 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
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);
@ -112,9 +112,8 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionConst) {
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32);
v.set_constructor(init);
v.set_is_const(true);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init,
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error();
@ -134,7 +133,8 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionConst) {
TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
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);
@ -160,7 +160,8 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
TEST_F(BuilderTest, IdentifierExpression_Load) {
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);
@ -190,10 +191,10 @@ TEST_F(BuilderTest, IdentifierExpression_Load) {
TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
ast::type::I32 i32;
ast::Variable var(Source{}, "var", ast::StorageClass::kNone, &i32);
var.set_constructor(create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)));
var.set_is_const(true);
ast::Variable var(Source{}, "var", ast::StorageClass::kNone, &i32, true,
create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(&i32, 2)),
ast::VariableDecorationList{});
td.RegisterVariableForTesting(&var);

View File

@ -76,7 +76,13 @@ TEST_F(BuilderTest, If_WithStatements) {
// v = 2;
// }
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>();
body->append(
@ -124,7 +130,13 @@ TEST_F(BuilderTest, If_WithElse) {
// v = 3;
// }
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>();
body->append(
@ -184,7 +196,13 @@ TEST_F(BuilderTest, If_WithElseIf) {
// v = 3;
// }
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>();
body->append(
@ -256,7 +274,13 @@ TEST_F(BuilderTest, If_WithMultiple) {
// v = 5;
// }
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>();
body->append(
@ -609,8 +633,14 @@ TEST_F(BuilderTest, If_WithLoad_Bug327) {
// }
ast::type::Bool bool_type;
auto* var = create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction,
&bool_type);
auto* var =
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);
ast::IfStatement expr(Source{}, create<ast::IdentifierExpression>("a"),

View File

@ -1399,9 +1399,8 @@ TEST_F(IntrinsicBuilderTest, DISABLED_Call_ArrayLength_Ptr) {
auto* var = Var("b", ast::StorageClass::kPrivate, &s_type);
auto* ptr_var = Var("ptr_var", ast::StorageClass::kPrivate, &ptr);
ptr_var->set_constructor(
create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")));
Var("ptr_var", ast::StorageClass::kPrivate, &ptr,
create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")), {});
auto expr = Call("arrayLength", "ptr_var");
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();

View File

@ -66,7 +66,13 @@ TEST_F(BuilderTest, Loop_WithoutContinuing) {
// v = 2;
// }
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>();
body->append(
@ -113,7 +119,13 @@ TEST_F(BuilderTest, Loop_WithContinuing) {
// }
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>();
body->append(

View File

@ -81,7 +81,8 @@ TEST_F(BuilderTest, Return_WithValue) {
TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) {
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{},
create<ast::IdentifierExpression>("param"));

View File

@ -77,9 +77,21 @@ TEST_F(BuilderTest, Switch_WithCase) {
// }
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 =
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>();
case_1_body->append(
@ -158,9 +170,21 @@ TEST_F(BuilderTest, Switch_WithDefault) {
// }
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 =
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>();
default_body->append(
@ -224,9 +248,21 @@ TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
// }
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 =
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>();
case_1_body->append(
@ -320,9 +356,21 @@ TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
// }
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 =
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>();
case_1_body->append(
@ -412,9 +460,21 @@ TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) {
// }
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 =
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>();
case_1_body->append(
@ -460,9 +520,21 @@ TEST_F(BuilderTest, Switch_WithNestedBreak) {
// }
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 =
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>();
if_body->append(create<ast::BreakStatement>());

View File

@ -98,7 +98,8 @@ TEST_F(BuilderTest, UnaryOp_LoadRequired) {
ast::type::F32 f32;
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,
create<ast::IdentifierExpression>("param"));

View File

@ -32,7 +32,6 @@
#include "src/ast/constant_id_decoration.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/else_statement.h"
#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
@ -70,6 +69,7 @@
#include "src/ast/type_constructor_expression.h"
#include "src/ast/uint_literal.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
#include "src/ast/workgroup_decoration.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) {
make_indent();
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
if (!EmitVariableDecorations(decorated)) {
return false;
}
if (!var->decorations().empty() && !EmitVariableDecorations(var)) {
return false;
}
if (var->is_const()) {
@ -614,7 +612,7 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
return true;
}
bool GeneratorImpl::EmitVariableDecorations(ast::DecoratedVariable* var) {
bool GeneratorImpl::EmitVariableDecorations(ast::Variable* var) {
out_ << "[[";
bool first = true;
for (auto* deco : var->decorations()) {

View File

@ -27,7 +27,6 @@
#include "src/ast/case_statement.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/identifier_expression.h"
@ -206,7 +205,7 @@ class GeneratorImpl : public TextGenerator {
/// Handles generating variable decorations
/// @param var the decorated variable
/// @returns true if the variable decoration was emitted
bool EmitVariableDecorations(ast::DecoratedVariable* var);
bool EmitVariableDecorations(ast::Variable* var);
};
} // namespace wgsl

View File

@ -13,7 +13,6 @@
// limitations under the License.
#include "gtest/gtest.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/function.h"
#include "src/ast/member_accessor_expression.h"
@ -69,9 +68,21 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
ast::type::I32 i32;
ast::VariableList params;
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(
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::Function func(Source{}, "my_func", params, &void_type, body,
@ -191,13 +202,18 @@ TEST_F(WgslGeneratorImplTest,
ast::type::Struct s("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s);
auto* data_var = create<ast::DecoratedVariable>(create<ast::Variable>(
Source{}, "data", ast::StorageClass::kStorageBuffer, &ac));
ast::VariableDecorationList decos;
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(0, Source{}));
data_var->set_decorations(decos);
auto* data_var =
create<ast::Variable>(Source{}, // source
"data", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(0, Source{}),
});
mod.AddConstructedType(&s);
@ -206,11 +222,16 @@ TEST_F(WgslGeneratorImplTest,
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));
@ -228,11 +249,16 @@ TEST_F(WgslGeneratorImplTest,
{
ast::VariableList params;
auto* var = create<ast::Variable>(Source{}, "v",
ast::StorageClass::kFunction, &f32);
var->set_constructor(create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("data"),
create<ast::IdentifierExpression>("d")));
auto* var = create<ast::Variable>(
Source{}, // source
"v", // name
ast::StorageClass::kFunction, // storage_class
&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>();
body->append(create<ast::VariableDeclStatement>(var));

View File

@ -33,7 +33,13 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
ast::type::F32 f32;
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);
@ -49,7 +55,13 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
// https://github.com/gpuweb/gpuweb/issues/654
ast::type::F32 f32;
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);
@ -62,7 +74,13 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
ast::type::F32 f32;
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);

View File

@ -18,10 +18,10 @@
#include "src/ast/binding_decoration.h"
#include "src/ast/builtin_decoration.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/location_decoration.h"
#include "src/ast/set_decoration.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decoration.h"
#include "src/writer/wgsl/generator_impl.h"
#include "src/writer/wgsl/test_helper.h"
@ -35,7 +35,8 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitVariable) {
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();
EXPECT_EQ(gen.result(), R"(var a : f32;
@ -44,7 +45,8 @@ TEST_F(WgslGeneratorImplTest, EmitVariable) {
TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
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();
EXPECT_EQ(gen.result(), R"(var<in> a : f32;
@ -54,15 +56,12 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(create<ast::LocationDecoration>(2, Source{}));
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, false, nullptr,
ast::VariableDecorationList{
create<ast::LocationDecoration>(2, Source{}),
});
ast::DecoratedVariable dv;
dv.set_name("a");
dv.set_type(&f32);
dv.set_decorations(decos);
ASSERT_TRUE(gen.EmitVariable(&dv)) << gen.error();
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
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) {
ast::type::F32 f32;
ast::VariableDecorationList decos;
decos.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
decos.push_back(create<ast::BindingDecoration>(0, Source{}));
decos.push_back(create<ast::SetDecoration>(1, Source{}));
decos.push_back(create<ast::LocationDecoration>(2, Source{}));
decos.push_back(create<ast::ConstantIdDecoration>(42, Source{}));
ast::Variable v(
Source{}, "a", ast::StorageClass::kNone, &f32, false, nullptr,
ast::VariableDecorationList{
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}),
create<ast::BindingDecoration>(0, Source{}),
create<ast::SetDecoration>(1, Source{}),
create<ast::LocationDecoration>(2, Source{}),
create<ast::ConstantIdDecoration>(42, Source{}),
});
ast::DecoratedVariable dv;
dv.set_name("a");
dv.set_type(&f32);
dv.set_decorations(decos);
ASSERT_TRUE(gen.EmitVariable(&dv)) << gen.error();
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
EXPECT_EQ(
gen.result(),
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");
ast::type::F32 f32;
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32);
v.set_constructor(ident);
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, false, ident,
ast::VariableDecorationList{});
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
EXPECT_EQ(gen.result(), R"(var a : f32 = initializer;
@ -106,9 +102,8 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
auto* ident = create<ast::IdentifierExpression>("initializer");
ast::type::F32 f32;
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32);
v.set_constructor(ident);
v.set_is_const(true);
ast::Variable v(Source{}, "a", ast::StorageClass::kNone, &f32, true, ident,
ast::VariableDecorationList{});
ASSERT_TRUE(gen.EmitVariable(&v)) << gen.error();
EXPECT_EQ(gen.result(), R"(const a : f32 = initializer;