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/constructor_expression.h",
"src/ast/continue_statement.cc", "src/ast/continue_statement.cc",
"src/ast/continue_statement.h", "src/ast/continue_statement.h",
"src/ast/decorated_variable.cc",
"src/ast/decorated_variable.h",
"src/ast/decoration.cc", "src/ast/decoration.cc",
"src/ast/decoration.h", "src/ast/decoration.h",
"src/ast/discard_statement.cc", "src/ast/discard_statement.cc",
@ -765,7 +763,6 @@ source_set("tint_unittests_core_src") {
"src/ast/clone_context_test.cc", "src/ast/clone_context_test.cc",
"src/ast/constant_id_decoration_test.cc", "src/ast/constant_id_decoration_test.cc",
"src/ast/continue_statement_test.cc", "src/ast/continue_statement_test.cc",
"src/ast/decorated_variable_test.cc",
"src/ast/decoration_test.cc", "src/ast/decoration_test.cc",
"src/ast/discard_statement_test.cc", "src/ast/discard_statement_test.cc",
"src/ast/else_statement_test.cc", "src/ast/else_statement_test.cc",

View File

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

View File

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

View File

@ -428,7 +428,8 @@ class Builder {
/// @param name the variable name /// @param name the variable name
/// @param storage the variable storage class /// @param storage the variable storage class
/// @param type the variable type /// @param type the variable type
/// @returns a `Variable` with the given name, storage and type /// @returns a `Variable` with the given name, storage and type. The variable
/// will be built with a nullptr constructor and no decorations.
Variable* Var(const std::string& name, Variable* Var(const std::string& name,
StorageClass storage, StorageClass storage,
type::Type* type); type::Type* type);
@ -436,11 +437,36 @@ class Builder {
/// @param name the variable name /// @param name the variable name
/// @param storage the variable storage class /// @param storage the variable storage class
/// @param type the variable type /// @param type the variable type
/// @returns a constant `Variable` with the given name, storage and type /// @param constructor constructor expression
/// @param decorations variable decorations
/// @returns a `Variable` with the given name, storage and type
Variable* Var(const std::string& name,
StorageClass storage,
type::Type* type,
Expression* constructor,
VariableDecorationList decorations);
/// @param name the variable name
/// @param storage the variable storage class
/// @param type the variable type
/// @returns a constant `Variable` with the given name, storage and type. The
/// variable will be built with a nullptr constructor and no decorations.
Variable* Const(const std::string& name, Variable* Const(const std::string& name,
StorageClass storage, StorageClass storage,
type::Type* type); type::Type* type);
/// @param name the variable name
/// @param storage the variable storage class
/// @param type the variable type
/// @param constructor optional constructor expression
/// @param decorations optional variable decorations
/// @returns a constant `Variable` with the given name, storage and type
Variable* Const(const std::string& name,
StorageClass storage,
type::Type* type,
Expression* constructor,
VariableDecorationList decorations);
/// @param func the function name /// @param func the function name
/// @param args the function call arguments /// @param args the function call arguments
/// @returns a `CallExpression` to the function `func`, with the /// @returns a `CallExpression` to the function `func`, with the

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

View File

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

View File

@ -67,7 +67,8 @@ TEST_F(ModuleTest, IsValid_Empty) {
TEST_F(ModuleTest, IsValid_GlobalVariable) { TEST_F(ModuleTest, IsValid_GlobalVariable) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, &f32); auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, &f32,
false, nullptr, ast::VariableDecorationList{});
Module m; Module m;
m.AddGlobalVariable(var); m.AddGlobalVariable(var);
@ -81,7 +82,8 @@ TEST_F(ModuleTest, IsValid_Null_GlobalVariable) {
} }
TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) { TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, nullptr); auto* var = create<Variable>(Source{}, "var", StorageClass::kInput, nullptr,
false, nullptr, ast::VariableDecorationList{});
Module m; Module m;
m.AddGlobalVariable(var); m.AddGlobalVariable(var);

View File

@ -17,7 +17,7 @@
#include <assert.h> #include <assert.h>
#include "src/ast/clone_context.h" #include "src/ast/clone_context.h"
#include "src/ast/decorated_variable.h" #include "src/ast/constant_id_decoration.h"
#include "src/ast/module.h" #include "src/ast/module.h"
TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable); TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
@ -25,24 +25,66 @@ TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
namespace tint { namespace tint {
namespace ast { namespace ast {
Variable::Variable() = default;
Variable::Variable(const Source& source, Variable::Variable(const Source& source,
const std::string& name, const std::string& name,
StorageClass sc, StorageClass sc,
type::Type* type) type::Type* type,
: Base(source), name_(name), storage_class_(sc), type_(type) {} bool is_const,
Expression* constructor,
VariableDecorationList decorations)
: Base(source),
name_(name),
storage_class_(sc),
type_(type),
is_const_(is_const),
constructor_(constructor),
decorations_(std::move(decorations)) {}
Variable::Variable(Variable&&) = default; Variable::Variable(Variable&&) = default;
Variable::~Variable() = default; Variable::~Variable() = default;
bool Variable::HasLocationDecoration() const {
for (auto* deco : decorations_) {
if (deco->Is<LocationDecoration>()) {
return true;
}
}
return false;
}
bool Variable::HasBuiltinDecoration() const {
for (auto* deco : decorations_) {
if (deco->Is<BuiltinDecoration>()) {
return true;
}
}
return false;
}
bool Variable::HasConstantIdDecoration() const {
for (auto* deco : decorations_) {
if (deco->Is<ConstantIdDecoration>()) {
return true;
}
}
return false;
}
uint32_t Variable::constant_id() const {
assert(HasConstantIdDecoration());
for (auto* deco : decorations_) {
if (auto* cid = deco->As<ConstantIdDecoration>()) {
return cid->value();
}
}
return 0;
}
Variable* Variable::Clone(CloneContext* ctx) const { Variable* Variable::Clone(CloneContext* ctx) const {
auto* cloned = ctx->mod->create<Variable>( return ctx->mod->create<Variable>(
ctx->Clone(source()), name(), storage_class(), ctx->Clone(type())); ctx->Clone(source()), name(), storage_class(), ctx->Clone(type()),
cloned->set_constructor(ctx->Clone(constructor())); is_const_, ctx->Clone(constructor()), ctx->Clone(decorations_));
cloned->set_is_const(is_const());
return cloned;
} }
bool Variable::IsValid() const { bool Variable::IsValid() const {
@ -87,6 +129,17 @@ void Variable::to_str(std::ostream& out, size_t indent) const {
out << "Const"; out << "Const";
} }
out << "{" << std::endl; out << "{" << std::endl;
if (!decorations_.empty()) {
make_indent(out, indent + 2);
out << "Decorations{" << std::endl;
for (auto* deco : decorations_) {
deco->to_str(out, indent + 4);
}
make_indent(out, indent + 2);
out << "}" << std::endl;
}
info_to_str(out, indent + 2); info_to_str(out, indent + 2);
constructor_to_str(out, indent + 2); constructor_to_str(out, indent + 2);
make_indent(out, indent); make_indent(out, indent);

View File

@ -25,6 +25,7 @@
#include "src/ast/node.h" #include "src/ast/node.h"
#include "src/ast/storage_class.h" #include "src/ast/storage_class.h"
#include "src/ast/type/type.h" #include "src/ast/type/type.h"
#include "src/ast/variable_decoration.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -83,25 +84,24 @@ class Variable : public Castable<Variable, Node> {
/// @param name the variables name /// @param name the variables name
/// @param sc the variable storage class /// @param sc the variable storage class
/// @param type the value type /// @param type the value type
/// @param is_const true if the variable is const
/// @param constructor the constructor expression
/// @param decorations the variable decorations
Variable(const Source& source, Variable(const Source& source,
const std::string& name, const std::string& name,
StorageClass sc, StorageClass sc,
type::Type* type); type::Type* type,
bool is_const,
Expression* constructor,
VariableDecorationList decorations);
/// Move constructor /// Move constructor
Variable(Variable&&); Variable(Variable&&);
~Variable() override; ~Variable() override;
/// Sets the variable name
/// @param name the name to set
void set_name(const std::string& name) { name_ = name; }
/// @returns the variable name /// @returns the variable name
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
/// Sets the value type if a const or formal parameter, or the
/// store type if a var.
/// @param type the type
void set_type(type::Type* type) { type_ = type; }
/// @returns the variable's type. /// @returns the variable's type.
type::Type* type() const { return type_; } type::Type* type() const { return type_; }
@ -111,20 +111,28 @@ class Variable : public Castable<Variable, Node> {
/// @returns the storage class /// @returns the storage class
StorageClass storage_class() const { return storage_class_; } StorageClass storage_class() const { return storage_class_; }
/// Sets the constructor
/// @param expr the constructor expression
void set_constructor(Expression* expr) { constructor_ = expr; }
/// @returns the constructor expression or nullptr if none set /// @returns the constructor expression or nullptr if none set
Expression* constructor() const { return constructor_; } Expression* constructor() const { return constructor_; }
/// @returns true if the variable has an constructor /// @returns true if the variable has an constructor
bool has_constructor() const { return constructor_ != nullptr; } bool has_constructor() const { return constructor_ != nullptr; }
/// Sets if the variable is constant
/// @param val the value to be set
void set_is_const(bool val) { is_const_ = val; }
/// @returns true if this is a constant, false otherwise /// @returns true if this is a constant, false otherwise
bool is_const() const { return is_const_; } bool is_const() const { return is_const_; }
/// @returns the decorations attached to this variable
const VariableDecorationList& decorations() const { return decorations_; }
/// @returns true if the decorations include a LocationDecoration
bool HasLocationDecoration() const;
/// @returns true if the deocrations include a BuiltinDecoration
bool HasBuiltinDecoration() const;
/// @returns true if the decorations include a ConstantIdDecoration
bool HasConstantIdDecoration() const;
/// @returns the constant_id value for the variable. Assumes that
/// HasConstantIdDecoration() has been called first.
uint32_t constant_id() const;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @note Semantic information such as resolved expression type and intrinsic /// @note Semantic information such as resolved expression type and intrinsic
@ -142,10 +150,6 @@ class Variable : public Castable<Variable, Node> {
void to_str(std::ostream& out, size_t indent) const override; void to_str(std::ostream& out, size_t indent) const override;
protected: protected:
/// Constructor
/// Used by the DecoratedVariable constructor.
Variable();
/// Output information for this variable. /// Output information for this variable.
/// @param out the stream to write to /// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing /// @param indent number of spaces to indent the node when writing
@ -158,12 +162,13 @@ class Variable : public Castable<Variable, Node> {
private: private:
Variable(const Variable&) = delete; Variable(const Variable&) = delete;
bool is_const_ = false;
std::string name_; std::string name_;
StorageClass storage_class_ = StorageClass::kNone; StorageClass storage_class_ = StorageClass::kNone;
// The value type if a const or formal paramter, and the store type if a var // The value type if a const or formal paramter, and the store type if a var
type::Type* type_ = nullptr; type::Type* type_ = nullptr;
bool is_const_ = false;
Expression* constructor_ = nullptr; Expression* constructor_ = nullptr;
VariableDecorationList decorations_;
}; };
/// A list of variables /// A list of variables

View File

@ -26,7 +26,8 @@ using VariableDeclStatementTest = TestHelper;
TEST_F(VariableDeclStatementTest, Creation) { TEST_F(VariableDeclStatementTest, Creation) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32); auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
VariableDeclStatement stmt(var); VariableDeclStatement stmt(var);
EXPECT_EQ(stmt.variable(), var); EXPECT_EQ(stmt.variable(), var);
@ -34,7 +35,8 @@ TEST_F(VariableDeclStatementTest, Creation) {
TEST_F(VariableDeclStatementTest, Creation_WithSource) { TEST_F(VariableDeclStatementTest, Creation_WithSource) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32); auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var); VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var);
auto src = stmt.source(); auto src = stmt.source();
@ -44,7 +46,8 @@ TEST_F(VariableDeclStatementTest, Creation_WithSource) {
TEST_F(VariableDeclStatementTest, IsVariableDecl) { TEST_F(VariableDeclStatementTest, IsVariableDecl) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32); auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
VariableDeclStatement s(var); VariableDeclStatement s(var);
EXPECT_TRUE(s.Is<VariableDeclStatement>()); EXPECT_TRUE(s.Is<VariableDeclStatement>());
@ -52,14 +55,16 @@ TEST_F(VariableDeclStatementTest, IsVariableDecl) {
TEST_F(VariableDeclStatementTest, IsValid) { TEST_F(VariableDeclStatementTest, IsValid) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32); auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
VariableDeclStatement stmt(var); VariableDeclStatement stmt(var);
EXPECT_TRUE(stmt.IsValid()); EXPECT_TRUE(stmt.IsValid());
} }
TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) { TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "", StorageClass::kNone, &f32); auto* var = create<Variable>(Source{}, "", StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
VariableDeclStatement stmt(var); VariableDeclStatement stmt(var);
EXPECT_FALSE(stmt.IsValid()); EXPECT_FALSE(stmt.IsValid());
} }
@ -71,7 +76,8 @@ TEST_F(VariableDeclStatementTest, IsValid_NullVariable) {
TEST_F(VariableDeclStatementTest, ToStr) { TEST_F(VariableDeclStatementTest, ToStr) {
type::F32 f32; type::F32 f32;
auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32); auto* var = create<Variable>(Source{}, "a", StorageClass::kNone, &f32, false,
nullptr, ast::VariableDecorationList{});
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var); VariableDeclStatement stmt(Source{Source::Location{20, 2}}, var);
std::ostringstream out; std::ostringstream out;

View File

@ -14,6 +14,7 @@
#include "src/ast/variable.h" #include "src/ast/variable.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/type/f32_type.h" #include "src/ast/type/f32_type.h"
@ -27,7 +28,8 @@ using VariableTest = TestHelper;
TEST_F(VariableTest, Creation) { TEST_F(VariableTest, Creation) {
type::I32 t; type::I32 t;
Variable v(Source{}, "my_var", StorageClass::kFunction, &t); Variable v(Source{}, "my_var", StorageClass::kFunction, &t, false, nullptr,
ast::VariableDecorationList{});
EXPECT_EQ(v.name(), "my_var"); EXPECT_EQ(v.name(), "my_var");
EXPECT_EQ(v.storage_class(), StorageClass::kFunction); EXPECT_EQ(v.storage_class(), StorageClass::kFunction);
@ -41,7 +43,8 @@ TEST_F(VariableTest, Creation) {
TEST_F(VariableTest, CreationWithSource) { TEST_F(VariableTest, CreationWithSource) {
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}; Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
type::F32 t; type::F32 t;
Variable v(s, "i", StorageClass::kPrivate, &t); Variable v(s, "i", StorageClass::kPrivate, &t, false, nullptr,
ast::VariableDecorationList{});
EXPECT_EQ(v.name(), "i"); EXPECT_EQ(v.name(), "i");
EXPECT_EQ(v.storage_class(), StorageClass::kPrivate); EXPECT_EQ(v.storage_class(), StorageClass::kPrivate);
@ -55,7 +58,8 @@ TEST_F(VariableTest, CreationWithSource) {
TEST_F(VariableTest, CreationEmpty) { TEST_F(VariableTest, CreationEmpty) {
type::I32 t; type::I32 t;
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}; Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}};
Variable v(s, "a_var", StorageClass::kWorkgroup, &t); Variable v(s, "a_var", StorageClass::kWorkgroup, &t, false, nullptr,
ast::VariableDecorationList{});
EXPECT_EQ(v.name(), "a_var"); EXPECT_EQ(v.name(), "a_var");
EXPECT_EQ(v.storage_class(), StorageClass::kWorkgroup); EXPECT_EQ(v.storage_class(), StorageClass::kWorkgroup);
@ -68,43 +72,58 @@ TEST_F(VariableTest, CreationEmpty) {
TEST_F(VariableTest, IsValid) { TEST_F(VariableTest, IsValid) {
type::I32 t; type::I32 t;
Variable v{Source{}, "my_var", StorageClass::kNone, &t}; Variable v{Source{}, "my_var", StorageClass::kNone, &t,
false, nullptr, ast::VariableDecorationList{}};
EXPECT_TRUE(v.IsValid()); EXPECT_TRUE(v.IsValid());
} }
TEST_F(VariableTest, IsValid_WithConstructor) { TEST_F(VariableTest, IsValid_WithConstructor) {
type::I32 t; type::I32 t;
Variable v{Source{}, "my_var", StorageClass::kNone, &t}; Variable v{Source{},
v.set_constructor(create<IdentifierExpression>("ident")); "my_var",
StorageClass::kNone,
&t,
false,
create<IdentifierExpression>("ident"),
ast::VariableDecorationList{}};
EXPECT_TRUE(v.IsValid()); EXPECT_TRUE(v.IsValid());
} }
TEST_F(VariableTest, IsValid_MissinName) { TEST_F(VariableTest, IsValid_MissinName) {
type::I32 t; type::I32 t;
Variable v{Source{}, "", StorageClass::kNone, &t}; Variable v{Source{}, "", StorageClass::kNone, &t,
false, nullptr, ast::VariableDecorationList{}};
EXPECT_FALSE(v.IsValid()); EXPECT_FALSE(v.IsValid());
} }
TEST_F(VariableTest, IsValid_MissingType) { TEST_F(VariableTest, IsValid_MissingType) {
Variable v{Source{}, "x", StorageClass::kNone, nullptr}; Variable v{Source{}, "x", StorageClass::kNone, nullptr,
false, nullptr, ast::VariableDecorationList{}};
EXPECT_FALSE(v.IsValid()); EXPECT_FALSE(v.IsValid());
} }
TEST_F(VariableTest, IsValid_MissingBoth) { TEST_F(VariableTest, IsValid_MissingBoth) {
Variable v{Source{}, "", StorageClass::kNone, nullptr}; Variable v{Source{}, "", StorageClass::kNone, nullptr,
false, nullptr, ast::VariableDecorationList{}};
EXPECT_FALSE(v.IsValid()); EXPECT_FALSE(v.IsValid());
} }
TEST_F(VariableTest, IsValid_InvalidConstructor) { TEST_F(VariableTest, IsValid_InvalidConstructor) {
type::I32 t; type::I32 t;
Variable v{Source{}, "my_var", StorageClass::kNone, &t}; Variable v{Source{},
v.set_constructor(create<IdentifierExpression>("")); "my_var",
StorageClass::kNone,
&t,
false,
create<IdentifierExpression>(""),
ast::VariableDecorationList{}};
EXPECT_FALSE(v.IsValid()); EXPECT_FALSE(v.IsValid());
} }
TEST_F(VariableTest, to_str) { TEST_F(VariableTest, to_str) {
type::F32 t; type::F32 t;
Variable v{Source{}, "my_var", StorageClass::kFunction, &t}; Variable v{Source{}, "my_var", StorageClass::kFunction, &t,
false, nullptr, ast::VariableDecorationList{}};
std::ostringstream out; std::ostringstream out;
v.to_str(out, 2); v.to_str(out, 2);
EXPECT_EQ(out.str(), R"( Variable{ EXPECT_EQ(out.str(), R"( Variable{
@ -115,6 +134,58 @@ TEST_F(VariableTest, to_str) {
)"); )");
} }
TEST_F(VariableTest, WithDecorations) {
type::F32 t;
auto* var = create<Variable>(
Source{}, "my_var", StorageClass::kFunction, &t, false, nullptr,
VariableDecorationList{
create<LocationDecoration>(1, Source{}),
create<BuiltinDecoration>(Builtin::kPosition, Source{}),
create<ConstantIdDecoration>(1200, Source{}),
});
EXPECT_TRUE(var->HasLocationDecoration());
EXPECT_TRUE(var->HasBuiltinDecoration());
EXPECT_TRUE(var->HasConstantIdDecoration());
}
TEST_F(VariableTest, ConstantId) {
type::F32 t;
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t,
false, nullptr,
VariableDecorationList{
create<ConstantIdDecoration>(1200, Source{}),
});
EXPECT_EQ(var->constant_id(), 1200u);
}
TEST_F(VariableTest, Decorated_to_str) {
type::F32 t;
auto* var = create<Variable>(Source{}, "my_var", StorageClass::kFunction, &t,
false, create<IdentifierExpression>("expr"),
VariableDecorationList{
create<BindingDecoration>(2, Source{}),
create<SetDecoration>(1, Source{}),
});
std::ostringstream out;
var->to_str(out, 2);
EXPECT_EQ(out.str(), R"( Variable{
Decorations{
BindingDecoration{2}
SetDecoration{1}
}
my_var
function
__f32
{
Identifier[not set]{expr}
}
}
)");
}
} // namespace } // namespace
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -20,7 +20,6 @@
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/constructor_expression.h" #include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/function.h" #include "src/ast/function.h"
#include "src/ast/null_literal.h" #include "src/ast/null_literal.h"
@ -39,6 +38,7 @@
#include "src/ast/type/u32_type.h" #include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h" #include "src/ast/type/vector_type.h"
#include "src/ast/uint_literal.h" #include "src/ast/uint_literal.h"
#include "src/ast/variable.h"
namespace tint { namespace tint {
namespace inspector { namespace inspector {
@ -91,12 +91,7 @@ std::string Inspector::GetRemappedNameForEntryPoint(
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() { std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
std::map<uint32_t, Scalar> result; std::map<uint32_t, Scalar> result;
for (auto* var : module_.global_variables()) { for (auto* var : module_.global_variables()) {
auto* decorated = var->As<ast::DecoratedVariable>(); if (!var->HasConstantIdDecoration()) {
if (decorated == nullptr) {
continue;
}
if (!decorated->HasConstantIdDecoration()) {
continue; continue;
} }
@ -104,7 +99,7 @@ std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
// WGSL, so the validator should catch it. Thus here the inspector just // WGSL, so the validator should catch it. Thus here the inspector just
// assumes all definitians of the constant id are the same, so only needs // assumes all definitians of the constant id are the same, so only needs
// to find the first reference to constant id. // to find the first reference to constant id.
uint32_t constant_id = decorated->constant_id(); uint32_t constant_id = var->constant_id();
if (result.find(constant_id) != result.end()) { if (result.find(constant_id) != result.end()) {
continue; continue;
} }

View File

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

View File

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

View File

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

View File

@ -291,10 +291,16 @@ class ParserImpl : Reader {
/// @param id the SPIR-V result ID /// @param id the SPIR-V result ID
/// @param sc the storage class, which cannot be ast::StorageClass::kNone /// @param sc the storage class, which cannot be ast::StorageClass::kNone
/// @param type the type /// @param type the type
/// @param is_const if true, the variable is const
/// @param constructor the variable constructor
/// @param decorations the variable decorations
/// @returns a new Variable node, or null in the error case /// @returns a new Variable node, or null in the error case
ast::Variable* MakeVariable(uint32_t id, ast::Variable* MakeVariable(uint32_t id,
ast::StorageClass sc, ast::StorageClass sc,
ast::type::Type* type); ast::type::Type* type,
bool is_const,
ast::Expression* constructor,
ast::VariableDecorationList decorations);
/// Creates an AST expression node for a SPIR-V constant. /// Creates an AST expression node for a SPIR-V constant.
/// @param id the SPIR-V ID of the constant /// @param id the SPIR-V ID of the constant

View File

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

View File

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

View File

@ -28,7 +28,6 @@
#include "src/ast/call_expression.h" #include "src/ast/call_expression.h"
#include "src/ast/case_statement.h" #include "src/ast/case_statement.h"
#include "src/ast/continue_statement.h" #include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h" #include "src/ast/discard_statement.h"
#include "src/ast/else_statement.h" #include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h" #include "src/ast/fallthrough_statement.h"
@ -67,6 +66,7 @@
#include "src/ast/uint_literal.h" #include "src/ast/uint_literal.h"
#include "src/ast/unary_op.h" #include "src/ast/unary_op.h"
#include "src/ast/unary_op_expression.h" #include "src/ast/unary_op_expression.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h" #include "src/ast/variable_decl_statement.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_decoration.h"
#include "src/reader/wgsl/lexer.h" #include "src/reader/wgsl/lexer.h"
@ -419,25 +419,25 @@ Maybe<ast::Variable*> ParserImpl::global_variable_decl(
if (!decl.matched) if (!decl.matched)
return Failure::kNoMatch; return Failure::kNoMatch;
auto* var = decl.value;
auto var_decos = cast_decorations<ast::VariableDecoration>(decos); auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
if (var_decos.errored) if (var_decos.errored)
return Failure::kErrored; return Failure::kErrored;
if (var_decos.value.size() > 0) { ast::Expression* constructor = nullptr;
auto* dv = create<ast::DecoratedVariable>(var);
dv->set_decorations(var_decos.value);
var = dv;
}
if (match(Token::Type::kEqual)) { if (match(Token::Type::kEqual)) {
auto expr = expect_const_expr(); auto expr = expect_const_expr();
if (expr.errored) if (expr.errored)
return Failure::kErrored; return Failure::kErrored;
var->set_constructor(expr.value); constructor = expr.value;
} }
return var;
return create<ast::Variable>(decl->source, // source
decl->name, // name
decl->storage_class, // storage_class
decl->type, // type
false, // is_const
constructor, // constructor
std::move(var_decos.value)); // decorations
} }
// global_constant_decl // global_constant_decl
@ -452,10 +452,6 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
auto* var = create<ast::Variable>(decl->source, decl->name,
ast::StorageClass::kNone, decl->type);
var->set_is_const(true);
if (!expect(use, Token::Type::kEqual)) if (!expect(use, Token::Type::kEqual))
return Failure::kErrored; return Failure::kErrored;
@ -463,14 +459,18 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
if (init.errored) if (init.errored)
return Failure::kErrored; return Failure::kErrored;
var->set_constructor(init.value); return create<ast::Variable>(decl->source, // source
decl->name, // name
return var; ast::StorageClass::kNone, // storage_class
decl->type, // type
true, // is_const
init.value, // constructor
ast::VariableDecorationList{}); // decorations
} }
// variable_decl // variable_decl
// : VAR variable_storage_decoration? variable_ident_decl // : VAR variable_storage_decoration? variable_ident_decl
Maybe<ast::Variable*> ParserImpl::variable_decl() { Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
if (!match(Token::Type::kVar)) if (!match(Token::Type::kVar))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -482,9 +482,9 @@ Maybe<ast::Variable*> ParserImpl::variable_decl() {
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::Variable>(decl->source, decl->name, return VarDeclInfo{decl->source, decl->name,
sc.matched ? sc.value : ast::StorageClass::kNone, sc.matched ? sc.value : ast::StorageClass::kNone,
decl->type); decl->type};
} }
// texture_sampler_types // texture_sampler_types
@ -1349,13 +1349,18 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
ast::VariableList ret; ast::VariableList ret;
for (;;) { for (;;) {
auto* var = create<ast::Variable>(decl->source, decl->name, auto* var =
ast::StorageClass::kNone, decl->type); create<ast::Variable>(decl->source, // source
decl->name, // name
ast::StorageClass::kNone, // storage_class
decl->type, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
// Formal parameters are treated like a const declaration where the // Formal parameters are treated like a const declaration where the
// initializer value is provided by the call's argument. The key point is // initializer value is provided by the call's argument. The key point is
// that it's not updatable after intially set. This is unlike C or GLSL // that it's not updatable after intially set. This is unlike C or GLSL
// which treat formal parameters like local variables that can be updated. // which treat formal parameters like local variables that can be updated.
var->set_is_const(true);
ret.push_back(var); ret.push_back(var);
if (!match(Token::Type::kComma)) if (!match(Token::Type::kComma))
@ -1610,31 +1615,45 @@ Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
if (!constructor.matched) if (!constructor.matched)
return add_error(peek(), "missing constructor for const declaration"); return add_error(peek(), "missing constructor for const declaration");
auto* var = create<ast::Variable>(decl->source, decl->name, auto* var =
ast::StorageClass::kNone, decl->type); create<ast::Variable>(decl->source, // source
var->set_is_const(true); decl->name, // name
var->set_constructor(constructor.value); ast::StorageClass::kNone, // storage_class
decl->type, // type
true, // is_const
constructor.value, // constructor
ast::VariableDecorationList{}); // decorations
return create<ast::VariableDeclStatement>(decl->source, var); return create<ast::VariableDeclStatement>(decl->source, var);
} }
auto var = variable_decl(); auto decl = variable_decl();
if (var.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
if (!var.matched) if (!decl.matched)
return Failure::kNoMatch; return Failure::kNoMatch;
ast::Expression* constructor = nullptr;
if (match(Token::Type::kEqual)) { if (match(Token::Type::kEqual)) {
auto constructor = logical_or_expression(); auto constructor_expr = logical_or_expression();
if (constructor.errored) if (constructor_expr.errored)
return Failure::kErrored; return Failure::kErrored;
if (!constructor.matched) if (!constructor_expr.matched)
return add_error(peek(), "missing constructor for variable declaration"); return add_error(peek(), "missing constructor for variable declaration");
var->set_constructor(constructor.value); constructor = constructor_expr.value;
} }
return create<ast::VariableDeclStatement>(var->source(), var.value); auto* var =
create<ast::Variable>(decl->source, // source
decl->name, // name
decl->storage_class, // storage_class
decl->type, // type
false, // is_const
constructor, // constructor
ast::VariableDecorationList{}); // decorations
return create<ast::VariableDeclStatement>(var->source(), var);
} }
// if_stmt // if_stmt

View File

@ -262,6 +262,18 @@ class ParserImpl {
ast::type::Type* return_type; ast::type::Type* return_type;
}; };
/// VarDeclInfo contains the parsed information for variable declaration.
struct VarDeclInfo {
/// Variable declaration source
Source source;
/// Variable name
std::string name;
/// Variable storage class
ast::StorageClass storage_class;
/// Variable type
ast::type::Type* type;
};
/// Creates a new parser using the given file /// Creates a new parser using the given file
/// @param file the input source file to parse /// @param file the input source file to parse
explicit ParserImpl(Source::File const* file); explicit ParserImpl(Source::File const* file);
@ -356,8 +368,8 @@ class ParserImpl {
/// @returns the const object or nullptr /// @returns the const object or nullptr
Maybe<ast::Variable*> global_constant_decl(); Maybe<ast::Variable*> global_constant_decl();
/// Parses a `variable_decl` grammar element /// Parses a `variable_decl` grammar element
/// @returns the parsed variable or nullptr otherwise /// @returns the parsed variable declaration info
Maybe<ast::Variable*> variable_decl(); Maybe<VarDeclInfo> variable_decl();
/// Parses a `variable_ident_decl` grammar element, erroring on parse /// Parses a `variable_ident_decl` grammar element, erroring on parse
/// failure. /// failure.
/// @param use a description of what was being parsed if an error was raised. /// @param use a description of what was being parsed if an error was raised.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,7 +27,6 @@
#include "src/ast/case_statement.h" #include "src/ast/case_statement.h"
#include "src/ast/clone_context.h" #include "src/ast/clone_context.h"
#include "src/ast/constructor_expression.h" #include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/else_statement.h" #include "src/ast/else_statement.h"
#include "src/ast/expression.h" #include "src/ast/expression.h"
#include "src/ast/fallthrough_statement.h" #include "src/ast/fallthrough_statement.h"
@ -62,18 +61,17 @@ constexpr char kFirstVertexName[] = "tint_first_vertex_index";
constexpr char kFirstInstanceName[] = "tint_first_instance_index"; constexpr char kFirstInstanceName[] = "tint_first_instance_index";
constexpr char kIndexOffsetPrefix[] = "tint_first_index_offset_"; constexpr char kIndexOffsetPrefix[] = "tint_first_index_offset_";
ast::DecoratedVariable* clone_variable_with_new_name(ast::CloneContext* ctx, ast::Variable* clone_variable_with_new_name(ast::CloneContext* ctx,
ast::DecoratedVariable* in, ast::Variable* in,
std::string new_name) { std::string new_name) {
auto* var = ctx->mod->create<ast::Variable>(ctx->Clone(in->source()), return ctx->mod->create<ast::Variable>(
new_name, in->storage_class(), ctx->Clone(in->source()), // source
ctx->Clone(in->type())); new_name, // name
var->set_is_const(in->is_const()); in->storage_class(), // storage_class
var->set_constructor(ctx->Clone(in->constructor())); ctx->Clone(in->type()), // type
in->is_const(), // is_const
auto* out = ctx->mod->create<ast::DecoratedVariable>(var); ctx->Clone(in->constructor()), // constructor
out->set_decorations(ctx->Clone(in->decorations())); ctx->Clone(in->decorations())); // decorations
return out;
} }
} // namespace } // namespace
@ -86,7 +84,7 @@ FirstIndexOffset::~FirstIndexOffset() = default;
Transform::Output FirstIndexOffset::Run(ast::Module* in) { Transform::Output FirstIndexOffset::Run(ast::Module* in) {
// First do a quick check to see if the transform has already been applied. // First do a quick check to see if the transform has already been applied.
for (ast::Variable* var : in->global_variables()) { for (ast::Variable* var : in->global_variables()) {
if (auto* dec_var = var->As<ast::DecoratedVariable>()) { if (auto* dec_var = var->As<ast::Variable>()) {
if (dec_var->name() == kBufferName) { if (dec_var->name() == kBufferName) {
diag::Diagnostic err; diag::Diagnostic err;
err.message = "First index offset transform has already been applied."; err.message = "First index offset transform has already been applied.";
@ -129,7 +127,7 @@ Transform::Output FirstIndexOffset::Run(ast::Module* in) {
// a CreateFirstIndexOffset() statement to each function that uses one of // a CreateFirstIndexOffset() statement to each function that uses one of
// these builtins. // these builtins.
ast::CloneContext ctx(&out.module); ast::CloneContext ctx(&out.module);
ctx.ReplaceAll([&](ast::DecoratedVariable* var) -> ast::DecoratedVariable* { ctx.ReplaceAll([&](ast::Variable* var) -> ast::Variable* {
for (ast::VariableDecoration* dec : var->decorations()) { for (ast::VariableDecoration* dec : var->decorations()) {
if (auto* blt_dec = dec->As<ast::BuiltinDecoration>()) { if (auto* blt_dec = dec->As<ast::BuiltinDecoration>()) {
ast::Builtin blt_type = blt_dec->value(); ast::Builtin blt_type = blt_dec->value();
@ -229,13 +227,17 @@ ast::Variable* FirstIndexOffset::AddUniformBuffer(ast::Module* mod) {
kStructName, kStructName,
mod->create<ast::Struct>(std::move(decos), std::move(members))); mod->create<ast::Struct>(std::move(decos), std::move(members)));
auto* idx_var = auto* idx_var = mod->create<ast::Variable>(
mod->create<ast::DecoratedVariable>(mod->create<ast::Variable>( Source{}, // source
Source{}, kBufferName, ast::StorageClass::kUniform, struct_type)); kBufferName, // name
idx_var->set_decorations({ ast::StorageClass::kUniform, // storage_class
mod->create<ast::BindingDecoration>(binding_, Source{}), struct_type, // type
mod->create<ast::SetDecoration>(set_, Source{}), false, // is_const
}); nullptr, // constructor
ast::VariableDecorationList{
mod->create<ast::BindingDecoration>(binding_, Source{}),
mod->create<ast::SetDecoration>(set_, Source{}),
}); // decorations
mod->AddGlobalVariable(idx_var); mod->AddGlobalVariable(idx_var);
@ -250,16 +252,20 @@ ast::VariableDeclStatement* FirstIndexOffset::CreateFirstIndexOffset(
ast::Variable* buffer_var, ast::Variable* buffer_var,
ast::Module* mod) { ast::Module* mod) {
auto* buffer = mod->create<ast::IdentifierExpression>(buffer_var->name()); auto* buffer = mod->create<ast::IdentifierExpression>(buffer_var->name());
auto* var = mod->create<ast::Variable>(Source{}, original_name, auto* constructor = mod->create<ast::BinaryExpression>(
ast::StorageClass::kNone,
mod->create<ast::type::U32>());
var->set_is_const(true);
var->set_constructor(mod->create<ast::BinaryExpression>(
ast::BinaryOp::kAdd, ast::BinaryOp::kAdd,
mod->create<ast::IdentifierExpression>(kIndexOffsetPrefix + var->name()), mod->create<ast::IdentifierExpression>(kIndexOffsetPrefix +
original_name),
mod->create<ast::MemberAccessorExpression>( mod->create<ast::MemberAccessorExpression>(
buffer, mod->create<ast::IdentifierExpression>(field_name)))); buffer, mod->create<ast::IdentifierExpression>(field_name)));
auto* var =
mod->create<ast::Variable>(Source{}, // source
original_name, // name
ast::StorageClass::kNone, // storage_class
mod->create<ast::type::U32>(), // type
true, // is_const
constructor, // constructor
ast::VariableDecorationList{}); // decorations
return mod->create<ast::VariableDeclStatement>(var); return mod->create<ast::VariableDeclStatement>(var);
} }

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -194,7 +194,13 @@ TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
ast::type::Array array(&i32, 0, ast::ArrayDecorationList{}); ast::type::Array array(&i32, 0, ast::ArrayDecorationList{});
auto* var = auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &array); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&array, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableList params; ast::VariableList params;
ast::type::Void void_type; ast::type::Void void_type;
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();

View File

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

View File

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

View File

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

View File

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

View File

@ -268,8 +268,14 @@ TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Matrix mat(&f32, 3, 3); ast::type::Matrix mat(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "var", auto* var =
ast::StorageClass::kFunction, &mat); create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kFunction, // storage_class
&mat, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>("var")); params.push_back(create<ast::IdentifierExpression>("var"));

View File

@ -76,9 +76,21 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, DISABLED_Intrinsic_OuterProduct) {
ast::type::Vector vec3(&f32, 3); ast::type::Vector vec3(&f32, 3);
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec2); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&vec2, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* b = auto* b =
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &vec3); create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kNone, // storage_class
&vec3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>("a")); params.push_back(create<ast::IdentifierExpression>("a"));
@ -115,8 +127,10 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params); ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params);
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec); ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec,
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec); false, nullptr, ast::VariableDecorationList{});
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec,
false, nullptr, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v1); td.RegisterVariableForTesting(&v1);
td.RegisterVariableForTesting(&v2); td.RegisterVariableForTesting(&v2);

View File

@ -144,15 +144,26 @@ TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopWithVarUsedInContinuing) {
ast::type::F32 f32; ast::type::F32 f32;
auto* var = create<ast::Variable>(Source{}, "lhs", auto* var = create<ast::Variable>(
ast::StorageClass::kFunction, &f32); Source{}, // source
var->set_constructor(create<ast::ScalarConstructorExpression>( "lhs", // name
create<ast::FloatLiteral>(&f32, 2.4))); ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.4)), // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append(create<ast::VariableDeclStatement>(var)); body->append(create<ast::VariableDeclStatement>(var));
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>( body->append(create<ast::VariableDeclStatement>(
Source{}, "other", ast::StorageClass::kFunction, &f32))); create<ast::Variable>(Source{}, // source
"other", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}))); // decorations
auto* lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto* rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");

View File

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

View File

@ -16,7 +16,6 @@
#include <vector> #include <vector>
#include "src/ast/constant_id_decoration.h" #include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h" #include "src/ast/scalar_constructor_expression.h"
@ -45,10 +44,14 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
exprs.push_back(create<ast::ScalarConstructorExpression>( exprs.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 3.0f))); create<ast::FloatLiteral>(&f32, 3.0f)));
auto* var = auto* var = create<ast::Variable>(
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &ary); Source{}, // source
var->set_is_const(true); "pos", // name
var->set_constructor(create<ast::TypeConstructorExpression>(&ary, exprs)); ast::StorageClass::kNone, // storage_class
&ary, // type
true, // is_const
create<ast::TypeConstructorExpression>(&ary, exprs), // constructor
ast::VariableDecorationList{}); // decorations
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error(); ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
EXPECT_EQ(result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n"); EXPECT_EQ(result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n");
@ -57,15 +60,18 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) { TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
ast::type::F32 f32; ast::type::F32 f32;
ast::VariableDecorationList decos; auto* var = create<ast::Variable>(
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{})); Source{}, // source
"pos", // name
auto* var = create<ast::DecoratedVariable>( ast::StorageClass::kNone, // storage_class
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32)); &f32, // type
var->set_decorations(decos); true, // is_const
var->set_is_const(true); create<ast::ScalarConstructorExpression>(
var->set_constructor(create<ast::ScalarConstructorExpression>( create<ast::FloatLiteral>(&f32, 3.0f)), // constructor
create<ast::FloatLiteral>(&f32, 3.0f))); ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(23, Source{}),
});
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error(); ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23 EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
@ -79,13 +85,17 @@ static const float pos = WGSL_SPEC_CONSTANT_23;
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) { TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
ast::type::F32 f32; ast::type::F32 f32;
ast::VariableDecorationList decos; auto* var =
decos.push_back(create<ast::ConstantIdDecoration>(23, Source{})); create<ast::Variable>(Source{}, // source
"pos", // name
auto* var = create<ast::DecoratedVariable>( ast::StorageClass::kNone, // storage_class
create<ast::Variable>(Source{}, "pos", ast::StorageClass::kNone, &f32)); &f32, // type
var->set_decorations(decos); true, // is_const
var->set_is_const(true); nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(23, Source{}),
});
ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error(); ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23 EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23

View File

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

View File

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

View File

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

View File

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

View File

@ -267,8 +267,14 @@ TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Matrix mat(&f32, 3, 3); ast::type::Matrix mat(&f32, 3, 3);
auto* var = create<ast::Variable>(Source{}, "var", auto* var =
ast::StorageClass::kFunction, &mat); create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kFunction, // storage_class
&mat, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>("var")); params.push_back(create<ast::IdentifierExpression>("var"));

View File

@ -71,9 +71,21 @@ TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) {
ast::type::Vector vec3(&f32, 3); ast::type::Vector vec3(&f32, 3);
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &vec2); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&vec2, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* b = auto* b =
create<ast::Variable>(Source{}, "b", ast::StorageClass::kNone, &vec3); create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kNone, // storage_class
&vec3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>("a")); params.push_back(create<ast::IdentifierExpression>("a"));
@ -110,8 +122,10 @@ TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params); ast::CallExpression call(create<ast::IdentifierExpression>("dot"), params);
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec); ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec,
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec); false, nullptr, ast::VariableDecorationList{});
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec,
false, nullptr, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v1); td.RegisterVariableForTesting(&v1);
td.RegisterVariableForTesting(&v2); td.RegisterVariableForTesting(&v2);

View File

@ -149,15 +149,26 @@ TEST_F(MslGeneratorImplTest, Emit_LoopWithVarUsedInContinuing) {
ast::type::F32 f32; ast::type::F32 f32;
auto* var = create<ast::Variable>(Source{}, "lhs", auto* var = create<ast::Variable>(
ast::StorageClass::kFunction, &f32); Source{}, // source
var->set_constructor(create<ast::ScalarConstructorExpression>( "lhs", // name
create<ast::FloatLiteral>(&f32, 2.4))); ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 2.4)), // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append(create<ast::VariableDeclStatement>(var)); body->append(create<ast::VariableDeclStatement>(var));
body->append(create<ast::VariableDeclStatement>(create<ast::Variable>( body->append(create<ast::VariableDeclStatement>(
Source{}, "other", ast::StorageClass::kFunction, &f32))); create<ast::Variable>(Source{}, // source
"other", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}))); // decorations
auto* lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto* rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");

View File

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

View File

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

View File

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

View File

@ -53,7 +53,8 @@ TEST_F(BuilderTest, ArrayAccessor) {
// vec3<f32> ary; // vec3<f32> ary;
// ary[1] -> ptr<f32> // ary[1] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>("ary"); auto* ary = create<ast::IdentifierExpression>("ary");
auto* idx_expr = create<ast::ScalarConstructorExpression>( auto* idx_expr = create<ast::ScalarConstructorExpression>(
@ -94,8 +95,10 @@ TEST_F(BuilderTest, Accessor_Array_LoadIndex) {
// idx : i32; // idx : i32;
// ary[idx] -> ptr<f32> // ary[idx] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32); nullptr, ast::VariableDecorationList{});
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32, false,
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>("ary"); auto* ary = create<ast::IdentifierExpression>("ary");
auto* idx_expr = create<ast::IdentifierExpression>("idx"); auto* idx_expr = create<ast::IdentifierExpression>("idx");
@ -139,7 +142,8 @@ TEST_F(BuilderTest, ArrayAccessor_Dynamic) {
// vec3<f32> ary; // vec3<f32> ary;
// ary[1 + 2] -> ptr<f32> // ary[1 + 2] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false,
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>("ary"); auto* ary = create<ast::IdentifierExpression>("ary");
@ -186,7 +190,8 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
// ary = array<vec3<f32>, 4> // ary = array<vec3<f32>, 4>
// ary[3][2]; // ary[3][2];
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4); ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4, false,
nullptr, ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr( ast::ArrayAccessorExpression expr(
create<ast::ArrayAccessorExpression>( create<ast::ArrayAccessorExpression>(
@ -233,7 +238,8 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
// var a : array<vec3<f32>, 4>; // var a : array<vec3<f32>, 4>;
// a[2].xy; // a[2].xy;
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4); ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4, false,
nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( ast::MemberAccessorExpression expr(
create<ast::ArrayAccessorExpression>( create<ast::ArrayAccessorExpression>(
@ -289,7 +295,8 @@ TEST_F(BuilderTest, MemberAccessor) {
auto* s = create<ast::Struct>(members); auto* s = create<ast::Struct>(members);
ast::type::Struct s_type("my_struct", s); ast::type::Struct s_type("my_struct", s);
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"), ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
create<ast::IdentifierExpression>("b")); create<ast::IdentifierExpression>("b"));
@ -343,7 +350,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members)); ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( ast::MemberAccessorExpression expr(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -403,7 +411,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
ast::type::Struct s_type("Outer", create<ast::Struct>(outer_members)); ast::type::Struct s_type("Outer", create<ast::Struct>(outer_members));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( ast::MemberAccessorExpression expr(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -462,7 +471,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members)); ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
false, nullptr, ast::VariableDecorationList{});
auto* lhs = create<ast::MemberAccessorExpression>( auto* lhs = create<ast::MemberAccessorExpression>(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -528,8 +538,10 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members)); ast::type::Struct s_type("my_struct", create<ast::Struct>(outer_members));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32); false, nullptr, ast::VariableDecorationList{});
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32,
false, nullptr, ast::VariableDecorationList{});
auto* lhs = create<ast::IdentifierExpression>("store"); auto* lhs = create<ast::IdentifierExpression>("store");
@ -578,7 +590,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
// ident.y // ident.y
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"), ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
create<ast::IdentifierExpression>("y")); create<ast::IdentifierExpression>("y"));
@ -613,7 +626,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
// ident.yx // ident.yx
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"), ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
create<ast::IdentifierExpression>("yx")); create<ast::IdentifierExpression>("yx"));
@ -647,7 +661,8 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
// ident.yxz.xz // ident.yxz.xz
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( ast::MemberAccessorExpression expr(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -685,7 +700,8 @@ TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
// ident.yxz.x // ident.yxz.x
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( ast::MemberAccessorExpression expr(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -723,7 +739,8 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
// index.yxz[1] // index.yxz[1]
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3); ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3,
false, nullptr, ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr( ast::ArrayAccessorExpression expr(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -793,7 +810,7 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{}); ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{});
ast::Variable var(Source{}, "index", ast::StorageClass::kFunction, ast::Variable var(Source{}, "index", ast::StorageClass::kFunction,
&a_ary_type); &a_ary_type, false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( ast::MemberAccessorExpression expr(
create<ast::MemberAccessorExpression>( create<ast::MemberAccessorExpression>(
@ -885,9 +902,9 @@ TEST_F(BuilderTest, Accessor_Array_Of_Vec) {
create<ast::FloatLiteral>(&f32, -0.5)), create<ast::FloatLiteral>(&f32, -0.5)),
})); }));
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &arr); ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &arr, true,
var.set_is_const(true); create<ast::TypeConstructorExpression>(&arr, ary_params),
var.set_constructor(create<ast::TypeConstructorExpression>(&arr, ary_params)); ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"), ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
create<ast::ScalarConstructorExpression>( create<ast::ScalarConstructorExpression>(
@ -941,10 +958,10 @@ TEST_F(BuilderTest, Accessor_Const_Vec) {
vec_params.push_back(create<ast::ScalarConstructorExpression>( vec_params.push_back(create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 0.5))); create<ast::FloatLiteral>(&f32, 0.5)));
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &vec); ast::Variable var(
var.set_is_const(true); Source{}, "pos", ast::StorageClass::kPrivate, &vec, true,
var.set_constructor( create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)),
create<ast::TypeConstructorExpression>(&vec, std::move(vec_params))); ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"), ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
create<ast::ScalarConstructorExpression>( create<ast::ScalarConstructorExpression>(

View File

@ -44,7 +44,8 @@ using BuilderTest = TestHelper;
TEST_F(BuilderTest, Assign_Var) { TEST_F(BuilderTest, Assign_Var) {
ast::type::F32 f32; ast::type::F32 f32;
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false,
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::IdentifierExpression>("var"); auto* ident = create<ast::IdentifierExpression>("var");
auto* val = create<ast::ScalarConstructorExpression>( auto* val = create<ast::ScalarConstructorExpression>(
@ -78,7 +79,8 @@ TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Vector vec(&f32, 3); ast::type::Vector vec(&f32, 3);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec, false,
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::IdentifierExpression>("var"); auto* ident = create<ast::IdentifierExpression>("var");
ast::ExpressionList vals; ast::ExpressionList vals;
@ -128,7 +130,8 @@ TEST_F(BuilderTest, Assign_Var_Complex_ConstructorWithExtract) {
create<ast::FloatLiteral>(&f32, 3.0f)), create<ast::FloatLiteral>(&f32, 3.0f)),
}); });
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
nullptr, ast::VariableDecorationList{});
ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"), ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
init); init);
@ -176,7 +179,8 @@ TEST_F(BuilderTest, Assign_Var_Complex_Constructor) {
auto* init = create<ast::TypeConstructorExpression>(&vec3, vals); auto* init = create<ast::TypeConstructorExpression>(&vec3, vals);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
nullptr, ast::VariableDecorationList{});
ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"), ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
init); init);
@ -223,7 +227,8 @@ TEST_F(BuilderTest, Assign_StructMember) {
auto* s = create<ast::Struct>(members); auto* s = create<ast::Struct>(members);
ast::type::Struct s_type("my_struct", s); ast::type::Struct s_type("my_struct", s);
ast::Variable v(Source{}, "ident", ast::StorageClass::kFunction, &s_type); ast::Variable v(Source{}, "ident", ast::StorageClass::kFunction, &s_type,
false, nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::MemberAccessorExpression>( auto* ident = create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("ident"), create<ast::IdentifierExpression>("ident"),
@ -265,7 +270,8 @@ TEST_F(BuilderTest, Assign_Vector) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3); ast::type::Vector vec3(&f32, 3);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::IdentifierExpression>("var"); auto* ident = create<ast::IdentifierExpression>("var");
@ -312,7 +318,8 @@ TEST_F(BuilderTest, Assign_Vector_MemberByName) {
// var.y = 1 // var.y = 1
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::MemberAccessorExpression>( auto* ident = create<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>("var"), create<ast::IdentifierExpression>("var"),
@ -357,7 +364,8 @@ TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
// var[1] = 1 // var[1] = 1
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3); ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::ArrayAccessorExpression>( auto* ident = create<ast::ArrayAccessorExpression>(
create<ast::IdentifierExpression>("var"), create<ast::IdentifierExpression>("var"),

View File

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

View File

@ -41,16 +41,28 @@ TEST_F(BuilderTest, Block) {
// serves to prove the block code is pushing new scopes as needed. // serves to prove the block code is pushing new scopes as needed.
ast::BlockStatement outer; ast::BlockStatement outer;
outer.append(create<ast::VariableDeclStatement>(create<ast::Variable>( outer.append(create<ast::VariableDeclStatement>(
Source{}, "var", ast::StorageClass::kFunction, &f32))); create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}))); // decorations
outer.append(create<ast::AssignmentStatement>( outer.append(create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>("var"), create<ast::IdentifierExpression>("var"),
create<ast::ScalarConstructorExpression>( create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f)))); create<ast::FloatLiteral>(&f32, 1.0f))));
auto* inner = create<ast::BlockStatement>(); auto* inner = create<ast::BlockStatement>();
inner->append(create<ast::VariableDeclStatement>(create<ast::Variable>( inner->append(create<ast::VariableDeclStatement>(
Source{}, "var", ast::StorageClass::kFunction, &f32))); create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}))); // decorations
inner->append(create<ast::AssignmentStatement>( inner->append(create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>("var"), create<ast::IdentifierExpression>("var"),
create<ast::ScalarConstructorExpression>( create<ast::ScalarConstructorExpression>(

View File

@ -44,9 +44,21 @@ TEST_F(BuilderTest, Expression_Call) {
ast::VariableList func_params; ast::VariableList func_params;
func_params.push_back( func_params.push_back(
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32)); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
func_params.push_back( func_params.push_back(
create<ast::Variable>(Source{}, "b", ast::StorageClass::kFunction, &f32)); create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append(create<ast::ReturnStatement>( body->append(create<ast::ReturnStatement>(
@ -109,9 +121,21 @@ TEST_F(BuilderTest, Statement_Call) {
ast::VariableList func_params; ast::VariableList func_params;
func_params.push_back( func_params.push_back(
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32)); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
func_params.push_back( func_params.push_back(
create<ast::Variable>(Source{}, "b", ast::StorageClass::kFunction, &f32)); create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append(create<ast::ReturnStatement>( body->append(create<ast::ReturnStatement>(

View File

@ -103,11 +103,29 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUnusedInterfaceIds) {
}); });
auto* v_in = auto* v_in =
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32); create<ast::Variable>(Source{}, // source
auto* v_out = create<ast::Variable>(Source{}, "my_out", "my_in", // name
ast::StorageClass::kOutput, &f32); ast::StorageClass::kInput, // storage_class
auto* v_wg = create<ast::Variable>(Source{}, "my_wg", &f32, // type
ast::StorageClass::kWorkgroup, &f32); false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_out =
create<ast::Variable>(Source{}, // source
"my_out", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_wg =
create<ast::Variable>(Source{}, // source
"my_wg", // name
ast::StorageClass::kWorkgroup, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
@ -162,11 +180,29 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
}); });
auto* v_in = auto* v_in =
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32); create<ast::Variable>(Source{}, // source
auto* v_out = create<ast::Variable>(Source{}, "my_out", "my_in", // name
ast::StorageClass::kOutput, &f32); ast::StorageClass::kInput, // storage_class
auto* v_wg = create<ast::Variable>(Source{}, "my_wg", &f32, // type
ast::StorageClass::kWorkgroup, &f32); false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_out =
create<ast::Variable>(Source{}, // source
"my_out", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_wg =
create<ast::Variable>(Source{}, // source
"my_wg", // name
ast::StorageClass::kWorkgroup, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
td.RegisterVariableForTesting(v_in); td.RegisterVariableForTesting(v_in);
td.RegisterVariableForTesting(v_out); td.RegisterVariableForTesting(v_out);

View File

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

View File

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

View File

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

View File

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

View File

@ -76,7 +76,13 @@ TEST_F(BuilderTest, If_WithStatements) {
// v = 2; // v = 2;
// } // }
auto* var = auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append( body->append(
@ -124,7 +130,13 @@ TEST_F(BuilderTest, If_WithElse) {
// v = 3; // v = 3;
// } // }
auto* var = auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append( body->append(
@ -184,7 +196,13 @@ TEST_F(BuilderTest, If_WithElseIf) {
// v = 3; // v = 3;
// } // }
auto* var = auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append( body->append(
@ -256,7 +274,13 @@ TEST_F(BuilderTest, If_WithMultiple) {
// v = 5; // v = 5;
// } // }
auto* var = auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append( body->append(
@ -609,8 +633,14 @@ TEST_F(BuilderTest, If_WithLoad_Bug327) {
// } // }
ast::type::Bool bool_type; ast::type::Bool bool_type;
auto* var = create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, auto* var =
&bool_type); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&bool_type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::IfStatement expr(Source{}, create<ast::IdentifierExpression>("a"), ast::IfStatement expr(Source{}, create<ast::IdentifierExpression>("a"),

View File

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

View File

@ -66,7 +66,13 @@ TEST_F(BuilderTest, Loop_WithoutContinuing) {
// v = 2; // v = 2;
// } // }
auto* var = auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append( body->append(
@ -113,7 +119,13 @@ TEST_F(BuilderTest, Loop_WithContinuing) {
// } // }
auto* var = auto* var =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append( body->append(

View File

@ -81,7 +81,8 @@ TEST_F(BuilderTest, Return_WithValue) {
TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) { TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) {
ast::type::F32 f32; ast::type::F32 f32;
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &f32); ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &f32,
false, nullptr, ast::VariableDecorationList{});
ast::ReturnStatement ret(Source{}, ast::ReturnStatement ret(Source{},
create<ast::IdentifierExpression>("param")); create<ast::IdentifierExpression>("param"));

View File

@ -77,9 +77,21 @@ TEST_F(BuilderTest, Switch_WithCase) {
// } // }
auto* v = auto* v =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>(); auto* case_1_body = create<ast::BlockStatement>();
case_1_body->append( case_1_body->append(
@ -158,9 +170,21 @@ TEST_F(BuilderTest, Switch_WithDefault) {
// } // }
auto* v = auto* v =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* default_body = create<ast::BlockStatement>(); auto* default_body = create<ast::BlockStatement>();
default_body->append( default_body->append(
@ -224,9 +248,21 @@ TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
// } // }
auto* v = auto* v =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>(); auto* case_1_body = create<ast::BlockStatement>();
case_1_body->append( case_1_body->append(
@ -320,9 +356,21 @@ TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
// } // }
auto* v = auto* v =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>(); auto* case_1_body = create<ast::BlockStatement>();
case_1_body->append( case_1_body->append(
@ -412,9 +460,21 @@ TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) {
// } // }
auto* v = auto* v =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>(); auto* case_1_body = create<ast::BlockStatement>();
case_1_body->append( case_1_body->append(
@ -460,9 +520,21 @@ TEST_F(BuilderTest, Switch_WithNestedBreak) {
// } // }
auto* v = auto* v =
create<ast::Variable>(Source{}, "v", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a = auto* a =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &i32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* if_body = create<ast::BlockStatement>(); auto* if_body = create<ast::BlockStatement>();
if_body->append(create<ast::BreakStatement>()); if_body->append(create<ast::BreakStatement>());

View File

@ -98,7 +98,8 @@ TEST_F(BuilderTest, UnaryOp_LoadRequired) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Vector vec(&f32, 3); ast::type::Vector vec(&f32, 3);
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &vec); ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &vec,
false, nullptr, ast::VariableDecorationList{});
ast::UnaryOpExpression expr(ast::UnaryOp::kNegation, ast::UnaryOpExpression expr(ast::UnaryOp::kNegation,
create<ast::IdentifierExpression>("param")); create<ast::IdentifierExpression>("param"));

View File

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

View File

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

View File

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

View File

@ -33,7 +33,13 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) { TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
ast::type::F32 f32; ast::type::F32 f32;
auto* var = auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kNone, &f32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var); ast::VariableDeclStatement stmt(var);
@ -49,7 +55,13 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
// https://github.com/gpuweb/gpuweb/issues/654 // https://github.com/gpuweb/gpuweb/issues/654
ast::type::F32 f32; ast::type::F32 f32;
auto* var = auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kFunction, &f32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var); ast::VariableDeclStatement stmt(var);
@ -62,7 +74,13 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) { TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
ast::type::F32 f32; ast::type::F32 f32;
auto* var = auto* var =
create<ast::Variable>(Source{}, "a", ast::StorageClass::kPrivate, &f32); create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(var); ast::VariableDeclStatement stmt(var);

View File

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