[spirv-writer] Generate constants

This CL updates the SPIR-V writer to generate the OpConstantTrue,
OpConstantFalse and OpConstant instructions.

Bug: tint:5
Change-Id: I660554c491e4eb569e3902fce0973fae3f27e6c0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/17820
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-03-27 00:45:34 +00:00 committed by dan sinclair
parent bf46de42ad
commit 113fb07071
27 changed files with 423 additions and 72 deletions

View File

@ -264,6 +264,7 @@ set(TINT_TEST_SRCS
ast/else_statement_test.cc ast/else_statement_test.cc
ast/entry_point_test.cc ast/entry_point_test.cc
ast/fallthrough_statement_test.cc ast/fallthrough_statement_test.cc
ast/float_literal_test.cc
ast/function_test.cc ast/function_test.cc
ast/identifier_expression_test.cc ast/identifier_expression_test.cc
ast/if_statement_test.cc ast/if_statement_test.cc
@ -406,9 +407,10 @@ if(${TINT_BUILD_SPV_WRITER})
list(APPEND TINT_TEST_SRCS list(APPEND TINT_TEST_SRCS
writer/spirv/binary_writer_test.cc writer/spirv/binary_writer_test.cc
writer/spirv/builder_test.cc writer/spirv/builder_test.cc
writer/spirv/builder_type_test.cc
writer/spirv/builder_entry_point_test.cc writer/spirv/builder_entry_point_test.cc
writer/spirv/builder_function_test.cc writer/spirv/builder_function_test.cc
writer/spirv/builder_literal_test.cc
writer/spirv/builder_type_test.cc
writer/spirv/instruction_test.cc writer/spirv/instruction_test.cc
writer/spirv/operand_test.cc writer/spirv/operand_test.cc
writer/spirv/spv_dump.cc writer/spirv/spv_dump.cc

View File

@ -17,7 +17,8 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
BoolLiteral::BoolLiteral(bool value) : value_(value) {} BoolLiteral::BoolLiteral(ast::type::Type* type, bool value)
: Literal(type), value_(value) {}
BoolLiteral::~BoolLiteral() = default; BoolLiteral::~BoolLiteral() = default;
@ -25,5 +26,9 @@ std::string BoolLiteral::to_str() const {
return value_ ? "true" : "false"; return value_ ? "true" : "false";
} }
std::string BoolLiteral::name() const {
return value_ ? "__bool_true" : "__bool_false";
}
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -26,8 +26,9 @@ namespace ast {
class BoolLiteral : public Literal { class BoolLiteral : public Literal {
public: public:
/// Constructor /// Constructor
/// @param type the type of the literal
/// @param value the bool literals value /// @param value the bool literals value
explicit BoolLiteral(bool value); BoolLiteral(ast::type::Type* type, bool value);
~BoolLiteral() override; ~BoolLiteral() override;
/// @returns true if this is a bool literal /// @returns true if this is a bool literal
@ -38,6 +39,9 @@ class BoolLiteral : public Literal {
/// @returns true if the bool literal is false /// @returns true if the bool literal is false
bool IsFalse() const { return !value_; } bool IsFalse() const { return !value_; }
/// @returns the name for this literal. This name is unique to this value.
std::string name() const override;
/// @returns the literal as a string /// @returns the literal as a string
std::string to_str() const override; std::string to_str() const override;

View File

@ -15,6 +15,7 @@
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/type/bool_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -23,21 +24,24 @@ namespace {
using BoolLiteralTest = testing::Test; using BoolLiteralTest = testing::Test;
TEST_F(BoolLiteralTest, True) { TEST_F(BoolLiteralTest, True) {
BoolLiteral b{true}; ast::type::BoolType bool_type;
BoolLiteral b{&bool_type, true};
ASSERT_TRUE(b.IsBool()); ASSERT_TRUE(b.IsBool());
ASSERT_TRUE(b.IsTrue()); ASSERT_TRUE(b.IsTrue());
ASSERT_FALSE(b.IsFalse()); ASSERT_FALSE(b.IsFalse());
} }
TEST_F(BoolLiteralTest, False) { TEST_F(BoolLiteralTest, False) {
BoolLiteral b{false}; ast::type::BoolType bool_type;
BoolLiteral b{&bool_type, false};
ASSERT_TRUE(b.IsBool()); ASSERT_TRUE(b.IsBool());
ASSERT_FALSE(b.IsTrue()); ASSERT_FALSE(b.IsTrue());
ASSERT_TRUE(b.IsFalse()); ASSERT_TRUE(b.IsFalse());
} }
TEST_F(BoolLiteralTest, Is) { TEST_F(BoolLiteralTest, Is) {
BoolLiteral b{false}; ast::type::BoolType bool_type;
BoolLiteral b{&bool_type, false};
EXPECT_TRUE(b.IsBool()); EXPECT_TRUE(b.IsBool());
EXPECT_FALSE(b.IsInt()); EXPECT_FALSE(b.IsInt());
EXPECT_FALSE(b.IsFloat()); EXPECT_FALSE(b.IsFloat());
@ -45,8 +49,9 @@ TEST_F(BoolLiteralTest, Is) {
} }
TEST_F(BoolLiteralTest, ToStr) { TEST_F(BoolLiteralTest, ToStr) {
BoolLiteral t{true}; ast::type::BoolType bool_type;
BoolLiteral f{false}; BoolLiteral t{&bool_type, true};
BoolLiteral f{&bool_type, false};
EXPECT_EQ(t.to_str(), "true"); EXPECT_EQ(t.to_str(), "true");
EXPECT_EQ(f.to_str(), "false"); EXPECT_EQ(f.to_str(), "false");

View File

@ -18,6 +18,7 @@
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/if_statement.h" #include "src/ast/if_statement.h"
#include "src/ast/nop_statement.h" #include "src/ast/nop_statement.h"
#include "src/ast/type/bool_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -26,7 +27,8 @@ namespace {
using CaseStatementTest = testing::Test; using CaseStatementTest = testing::Test;
TEST_F(CaseStatementTest, Creation) { TEST_F(CaseStatementTest, Creation) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
std::vector<std::unique_ptr<Statement>> stmts; std::vector<std::unique_ptr<Statement>> stmts;
stmts.push_back(std::make_unique<NopStatement>()); stmts.push_back(std::make_unique<NopStatement>());
@ -40,7 +42,8 @@ TEST_F(CaseStatementTest, Creation) {
} }
TEST_F(CaseStatementTest, Creation_WithSource) { TEST_F(CaseStatementTest, Creation_WithSource) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
std::vector<std::unique_ptr<Statement>> stmts; std::vector<std::unique_ptr<Statement>> stmts;
stmts.push_back(std::make_unique<NopStatement>()); stmts.push_back(std::make_unique<NopStatement>());
@ -60,7 +63,8 @@ TEST_F(CaseStatementTest, IsDefault_WithoutCondition) {
} }
TEST_F(CaseStatementTest, IsDefault_WithCondition) { TEST_F(CaseStatementTest, IsDefault_WithCondition) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
CaseStatement c; CaseStatement c;
c.set_condition(std::move(b)); c.set_condition(std::move(b));
EXPECT_FALSE(c.IsDefault()); EXPECT_FALSE(c.IsDefault());
@ -77,7 +81,8 @@ TEST_F(CaseStatementTest, IsValid) {
} }
TEST_F(CaseStatementTest, IsValid_NullBodyStatement) { TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
std::vector<std::unique_ptr<Statement>> stmts; std::vector<std::unique_ptr<Statement>> stmts;
stmts.push_back(std::make_unique<NopStatement>()); stmts.push_back(std::make_unique<NopStatement>());
stmts.push_back(nullptr); stmts.push_back(nullptr);
@ -87,7 +92,8 @@ TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
} }
TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) { TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
std::vector<std::unique_ptr<Statement>> stmts; std::vector<std::unique_ptr<Statement>> stmts;
stmts.push_back(std::make_unique<IfStatement>()); stmts.push_back(std::make_unique<IfStatement>());
@ -96,7 +102,8 @@ TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
} }
TEST_F(CaseStatementTest, ToStr_WithCondition) { TEST_F(CaseStatementTest, ToStr_WithCondition) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
std::vector<std::unique_ptr<Statement>> stmts; std::vector<std::unique_ptr<Statement>> stmts;
stmts.push_back(std::make_unique<NopStatement>()); stmts.push_back(std::make_unique<NopStatement>());
CaseStatement c(std::move(b), std::move(stmts)); CaseStatement c(std::move(b), std::move(stmts));

View File

@ -16,6 +16,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/type/bool_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -24,14 +25,16 @@ namespace {
using ConstInitializerExpressionTest = testing::Test; using ConstInitializerExpressionTest = testing::Test;
TEST_F(ConstInitializerExpressionTest, Creation) { TEST_F(ConstInitializerExpressionTest, Creation) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
auto b_ptr = b.get(); auto b_ptr = b.get();
ConstInitializerExpression c(std::move(b)); ConstInitializerExpression c(std::move(b));
EXPECT_EQ(c.literal(), b_ptr); EXPECT_EQ(c.literal(), b_ptr);
} }
TEST_F(ConstInitializerExpressionTest, Creation_WithSource) { TEST_F(ConstInitializerExpressionTest, Creation_WithSource) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
ConstInitializerExpression c(Source{20, 2}, std::move(b)); ConstInitializerExpression c(Source{20, 2}, std::move(b));
auto src = c.source(); auto src = c.source();
EXPECT_EQ(src.line, 20); EXPECT_EQ(src.line, 20);
@ -39,7 +42,8 @@ TEST_F(ConstInitializerExpressionTest, Creation_WithSource) {
} }
TEST_F(ConstInitializerExpressionTest, IsValid) { TEST_F(ConstInitializerExpressionTest, IsValid) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
ConstInitializerExpression c(std::move(b)); ConstInitializerExpression c(std::move(b));
EXPECT_TRUE(c.IsValid()); EXPECT_TRUE(c.IsValid());
} }
@ -50,7 +54,8 @@ TEST_F(ConstInitializerExpressionTest, IsValid_MissingLiteral) {
} }
TEST_F(ConstInitializerExpressionTest, ToStr) { TEST_F(ConstInitializerExpressionTest, ToStr) {
auto b = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
ConstInitializerExpression c(std::move(b)); ConstInitializerExpression c(std::move(b));
std::ostringstream out; std::ostringstream out;
c.to_str(out, 2); c.to_str(out, 2);

View File

@ -19,6 +19,7 @@
#include "src/ast/const_initializer_expression.h" #include "src/ast/const_initializer_expression.h"
#include "src/ast/if_statement.h" #include "src/ast/if_statement.h"
#include "src/ast/nop_statement.h" #include "src/ast/nop_statement.h"
#include "src/ast/type/bool_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -27,8 +28,9 @@ namespace {
using ElseStatementTest = testing::Test; using ElseStatementTest = testing::Test;
TEST_F(ElseStatementTest, Creation) { TEST_F(ElseStatementTest, Creation) {
ast::type::BoolType bool_type;
auto cond = std::make_unique<ConstInitializerExpression>( auto cond = std::make_unique<ConstInitializerExpression>(
std::make_unique<BoolLiteral>(true)); std::make_unique<BoolLiteral>(&bool_type, true));
std::vector<std::unique_ptr<Statement>> body; std::vector<std::unique_ptr<Statement>> body;
body.push_back(std::make_unique<NopStatement>()); body.push_back(std::make_unique<NopStatement>());
@ -54,8 +56,9 @@ TEST_F(ElseStatementTest, IsElse) {
} }
TEST_F(ElseStatementTest, HasCondition) { TEST_F(ElseStatementTest, HasCondition) {
ast::type::BoolType bool_type;
auto cond = std::make_unique<ConstInitializerExpression>( auto cond = std::make_unique<ConstInitializerExpression>(
std::make_unique<BoolLiteral>(true)); std::make_unique<BoolLiteral>(&bool_type, true));
ElseStatement e(std::move(cond), {}); ElseStatement e(std::move(cond), {});
EXPECT_TRUE(e.HasCondition()); EXPECT_TRUE(e.HasCondition());
} }
@ -102,8 +105,9 @@ TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) {
} }
TEST_F(ElseStatementTest, ToStr) { TEST_F(ElseStatementTest, ToStr) {
ast::type::BoolType bool_type;
auto cond = std::make_unique<ConstInitializerExpression>( auto cond = std::make_unique<ConstInitializerExpression>(
std::make_unique<BoolLiteral>(true)); std::make_unique<BoolLiteral>(&bool_type, true));
std::vector<std::unique_ptr<Statement>> body; std::vector<std::unique_ptr<Statement>> body;
body.push_back(std::make_unique<NopStatement>()); body.push_back(std::make_unique<NopStatement>());

View File

@ -14,10 +14,13 @@
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include <sstream>
namespace tint { namespace tint {
namespace ast { namespace ast {
FloatLiteral::FloatLiteral(float value) : value_(value) {} FloatLiteral::FloatLiteral(ast::type::Type* type, float value)
: Literal(type), value_(value) {}
FloatLiteral::~FloatLiteral() = default; FloatLiteral::~FloatLiteral() = default;
@ -25,5 +28,13 @@ std::string FloatLiteral::to_str() const {
return std::to_string(value_); return std::to_string(value_);
} }
std::string FloatLiteral::name() const {
std::ostringstream out;
out.flags(out.flags() | std::ios_base::showpoint);
out.precision(std::numeric_limits<float>::max_digits10);
out << "__float" << value_;
return out.str();
}
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -26,8 +26,9 @@ namespace ast {
class FloatLiteral : public Literal { class FloatLiteral : public Literal {
public: public:
/// Constructor /// Constructor
/// @param type the type of the literal
/// @param value the float literals value /// @param value the float literals value
explicit FloatLiteral(float value); FloatLiteral(ast::type::Type* type, float value);
~FloatLiteral() override; ~FloatLiteral() override;
/// @returns true if this is a float literal /// @returns true if this is a float literal
@ -36,6 +37,9 @@ class FloatLiteral : public Literal {
/// @returns the float literal value /// @returns the float literal value
float value() const { return value_; } float value() const { return value_; }
/// @returns the name for this literal. This name is unique to this value.
std::string name() const override;
/// @returns the literal as a string /// @returns the literal as a string
std::string to_str() const override; std::string to_str() const override;

View File

@ -15,6 +15,7 @@
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/type/f32_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -23,13 +24,15 @@ namespace {
using FloatLiteralTest = testing::Test; using FloatLiteralTest = testing::Test;
TEST_F(FloatLiteralTest, Value) { TEST_F(FloatLiteralTest, Value) {
FloatLiteral f{47.2}; ast::type::F32Type f32;
FloatLiteral f{&f32, 47.2f};
ASSERT_TRUE(f.IsFloat()); ASSERT_TRUE(f.IsFloat());
EXPECT_EQ(f.value(), 47.2); EXPECT_EQ(f.value(), 47.2f);
} }
TEST_F(FloatLiteralTest, Is) { TEST_F(FloatLiteralTest, Is) {
FloatLiteral f{42}; ast::type::F32Type f32;
FloatLiteral f{&f32, 42.f};
EXPECT_FALSE(f.IsBool()); EXPECT_FALSE(f.IsBool());
EXPECT_FALSE(f.IsInt()); EXPECT_FALSE(f.IsInt());
EXPECT_TRUE(f.IsFloat()); EXPECT_TRUE(f.IsFloat());
@ -37,9 +40,16 @@ TEST_F(FloatLiteralTest, Is) {
} }
TEST_F(FloatLiteralTest, ToStr) { TEST_F(FloatLiteralTest, ToStr) {
FloatLiteral f{42.1}; ast::type::F32Type f32;
FloatLiteral f{&f32, 42.1f};
EXPECT_EQ(f.to_str(), "42.1"); EXPECT_EQ(f.to_str(), "42.099998");
}
TEST_F(FloatLiteralTest, ToName) {
ast::type::F32Type f32;
FloatLiteral f{&f32, 42.1f};
EXPECT_EQ(f.name(), "__float42.0999985");
} }
} // namespace } // namespace

View File

@ -17,7 +17,8 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
IntLiteral::IntLiteral(int32_t value) : value_(value) {} IntLiteral::IntLiteral(ast::type::Type* type, int32_t value)
: Literal(type), value_(value) {}
IntLiteral::~IntLiteral() = default; IntLiteral::~IntLiteral() = default;
@ -25,5 +26,9 @@ std::string IntLiteral::to_str() const {
return std::to_string(value_); return std::to_string(value_);
} }
std::string IntLiteral::name() const {
return "__int" + std::to_string(value_);
}
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -26,8 +26,9 @@ namespace ast {
class IntLiteral : public Literal { class IntLiteral : public Literal {
public: public:
/// Constructor /// Constructor
/// @param type the type
/// @param value the int literals value /// @param value the int literals value
explicit IntLiteral(int32_t value); IntLiteral(ast::type::Type* type, int32_t value);
~IntLiteral() override; ~IntLiteral() override;
/// @returns true if this is a int literal /// @returns true if this is a int literal
@ -36,6 +37,9 @@ class IntLiteral : public Literal {
/// @returns the int literal value /// @returns the int literal value
int32_t value() const { return value_; } int32_t value() const { return value_; }
/// @returns the name for this literal. This name is unique to this value.
std::string name() const override;
/// @returns the literal as a string /// @returns the literal as a string
std::string to_str() const override; std::string to_str() const override;

View File

@ -15,6 +15,7 @@
#include "src/ast/int_literal.h" #include "src/ast/int_literal.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/type/i32_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -23,13 +24,15 @@ namespace {
using IntLiteralTest = testing::Test; using IntLiteralTest = testing::Test;
TEST_F(IntLiteralTest, Value) { TEST_F(IntLiteralTest, Value) {
IntLiteral i{47}; ast::type::I32Type i32;
IntLiteral i{&i32, 47};
ASSERT_TRUE(i.IsInt()); ASSERT_TRUE(i.IsInt());
EXPECT_EQ(i.value(), 47); EXPECT_EQ(i.value(), 47);
} }
TEST_F(IntLiteralTest, Is) { TEST_F(IntLiteralTest, Is) {
IntLiteral i{42}; ast::type::I32Type i32;
IntLiteral i{&i32, 42};
EXPECT_FALSE(i.IsBool()); EXPECT_FALSE(i.IsBool());
EXPECT_TRUE(i.IsInt()); EXPECT_TRUE(i.IsInt());
EXPECT_FALSE(i.IsFloat()); EXPECT_FALSE(i.IsFloat());
@ -37,7 +40,8 @@ TEST_F(IntLiteralTest, Is) {
} }
TEST_F(IntLiteralTest, ToStr) { TEST_F(IntLiteralTest, ToStr) {
IntLiteral i{-42}; ast::type::I32Type i32;
IntLiteral i{&i32, -42};
EXPECT_EQ(i.to_str(), "-42"); EXPECT_EQ(i.to_str(), "-42");
} }

View File

@ -24,7 +24,7 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
Literal::Literal() = default; Literal::Literal(ast::type::Type* type) : type_(type) {}
Literal::~Literal() = default; Literal::~Literal() = default;

View File

@ -17,6 +17,8 @@
#include <string> #include <string>
#include "src/ast/type/type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -48,12 +50,21 @@ class Literal {
/// @returns the literal as a unsigned int literal /// @returns the literal as a unsigned int literal
UintLiteral* AsUint(); UintLiteral* AsUint();
/// @returns the type of the literal
ast::type::Type* type() const { return type_; }
/// @returns the literal as a string /// @returns the literal as a string
virtual std::string to_str() const = 0; virtual std::string to_str() const = 0;
/// @returns the name for this literal. This name is unique to this value.
virtual std::string name() const = 0;
protected: protected:
/// Constructor /// Constructor
Literal(); Literal(ast::type::Type* type);
private:
ast::type::Type* type_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -20,6 +20,7 @@
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/case_statement.h" #include "src/ast/case_statement.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/type/bool_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -28,7 +29,8 @@ namespace {
using SwitchStatementTest = testing::Test; using SwitchStatementTest = testing::Test;
TEST_F(SwitchStatementTest, Creation) { TEST_F(SwitchStatementTest, Creation) {
auto lit = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
auto ident = std::make_unique<IdentifierExpression>("ident"); auto ident = std::make_unique<IdentifierExpression>("ident");
std::vector<std::unique_ptr<CaseStatement>> body; std::vector<std::unique_ptr<CaseStatement>> body;
body.push_back(std::make_unique<CaseStatement>( body.push_back(std::make_unique<CaseStatement>(
@ -59,7 +61,8 @@ TEST_F(SwitchStatementTest, IsSwitch) {
} }
TEST_F(SwitchStatementTest, IsValid) { TEST_F(SwitchStatementTest, IsValid) {
auto lit = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
auto ident = std::make_unique<IdentifierExpression>("ident"); auto ident = std::make_unique<IdentifierExpression>("ident");
std::vector<std::unique_ptr<CaseStatement>> body; std::vector<std::unique_ptr<CaseStatement>> body;
body.push_back(std::make_unique<CaseStatement>( body.push_back(std::make_unique<CaseStatement>(
@ -70,7 +73,8 @@ TEST_F(SwitchStatementTest, IsValid) {
} }
TEST_F(SwitchStatementTest, IsValid_Null_Condition) { TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
auto lit = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
std::vector<std::unique_ptr<CaseStatement>> body; std::vector<std::unique_ptr<CaseStatement>> body;
body.push_back(std::make_unique<CaseStatement>( body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::vector<std::unique_ptr<Statement>>())); std::move(lit), std::vector<std::unique_ptr<Statement>>()));
@ -81,7 +85,8 @@ TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
} }
TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) { TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
auto lit = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
auto ident = std::make_unique<IdentifierExpression>(""); auto ident = std::make_unique<IdentifierExpression>("");
std::vector<std::unique_ptr<CaseStatement>> body; std::vector<std::unique_ptr<CaseStatement>> body;
body.push_back(std::make_unique<CaseStatement>( body.push_back(std::make_unique<CaseStatement>(
@ -92,7 +97,8 @@ TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
} }
TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) { TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
auto lit = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
auto ident = std::make_unique<IdentifierExpression>("ident"); auto ident = std::make_unique<IdentifierExpression>("ident");
std::vector<std::unique_ptr<CaseStatement>> body; std::vector<std::unique_ptr<CaseStatement>> body;
body.push_back(std::make_unique<CaseStatement>( body.push_back(std::make_unique<CaseStatement>(
@ -132,7 +138,8 @@ TEST_F(SwitchStatementTest, ToStr_Empty) {
} }
TEST_F(SwitchStatementTest, ToStr) { TEST_F(SwitchStatementTest, ToStr) {
auto lit = std::make_unique<BoolLiteral>(true); ast::type::BoolType bool_type;
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
auto ident = std::make_unique<IdentifierExpression>("ident"); auto ident = std::make_unique<IdentifierExpression>("ident");
std::vector<std::unique_ptr<CaseStatement>> body; std::vector<std::unique_ptr<CaseStatement>> body;
body.push_back(std::make_unique<CaseStatement>( body.push_back(std::make_unique<CaseStatement>(

View File

@ -17,7 +17,8 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
UintLiteral::UintLiteral(uint32_t value) : value_(value) {} UintLiteral::UintLiteral(ast::type::Type* type, uint32_t value)
: Literal(type), value_(value) {}
UintLiteral::~UintLiteral() = default; UintLiteral::~UintLiteral() = default;
@ -25,5 +26,9 @@ std::string UintLiteral::to_str() const {
return std::to_string(value_); return std::to_string(value_);
} }
std::string UintLiteral::name() const {
return "__uint" + std::to_string(value_);
}
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -26,8 +26,9 @@ namespace ast {
class UintLiteral : public Literal { class UintLiteral : public Literal {
public: public:
/// Constructor /// Constructor
/// @param type the type of the literal
/// @param value the uint literals value /// @param value the uint literals value
explicit UintLiteral(uint32_t value); UintLiteral(ast::type::Type* type, uint32_t value);
~UintLiteral() override; ~UintLiteral() override;
/// @returns true if this is a uint literal /// @returns true if this is a uint literal
@ -36,6 +37,9 @@ class UintLiteral : public Literal {
/// @returns the uint literal value /// @returns the uint literal value
uint32_t value() const { return value_; } uint32_t value() const { return value_; }
/// @returns the name for this literal. This name is unique to this value.
std::string name() const override;
/// @returns the literal as a string /// @returns the literal as a string
std::string to_str() const override; std::string to_str() const override;

View File

@ -15,6 +15,7 @@
#include "src/ast/uint_literal.h" #include "src/ast/uint_literal.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/type/u32_type.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -23,13 +24,15 @@ namespace {
using UintLiteralTest = testing::Test; using UintLiteralTest = testing::Test;
TEST_F(UintLiteralTest, Value) { TEST_F(UintLiteralTest, Value) {
UintLiteral u{47}; ast::type::U32Type u32;
UintLiteral u{&u32, 47};
ASSERT_TRUE(u.IsUint()); ASSERT_TRUE(u.IsUint());
EXPECT_EQ(u.value(), 47); EXPECT_EQ(u.value(), 47);
} }
TEST_F(UintLiteralTest, Is) { TEST_F(UintLiteralTest, Is) {
UintLiteral u{42}; ast::type::U32Type u32;
UintLiteral u{&u32, 42};
EXPECT_FALSE(u.IsBool()); EXPECT_FALSE(u.IsBool());
EXPECT_FALSE(u.IsInt()); EXPECT_FALSE(u.IsInt());
EXPECT_FALSE(u.IsFloat()); EXPECT_FALSE(u.IsFloat());
@ -37,7 +40,8 @@ TEST_F(UintLiteralTest, Is) {
} }
TEST_F(UintLiteralTest, ToStr) { TEST_F(UintLiteralTest, ToStr) {
UintLiteral i{42}; ast::type::U32Type u32;
UintLiteral i{&u32, 42};
EXPECT_EQ(i.to_str(), "42"); EXPECT_EQ(i.to_str(), "42");
} }

View File

@ -2097,23 +2097,44 @@ std::unique_ptr<ast::Literal> ParserImpl::const_literal() {
auto t = peek(); auto t = peek();
if (t.IsTrue()) { if (t.IsTrue()) {
next(); // Consume the peek next(); // Consume the peek
return std::make_unique<ast::BoolLiteral>(true);
auto type = ctx_.type_mgr->Get(std::make_unique<ast::type::BoolType>());
if (!type) {
return nullptr;
}
return std::make_unique<ast::BoolLiteral>(type, true);
} }
if (t.IsFalse()) { if (t.IsFalse()) {
next(); // Consume the peek next(); // Consume the peek
return std::make_unique<ast::BoolLiteral>(false); auto type = ctx_.type_mgr->Get(std::make_unique<ast::type::BoolType>());
if (!type) {
return nullptr;
}
return std::make_unique<ast::BoolLiteral>(type, false);
} }
if (t.IsIntLiteral()) { if (t.IsIntLiteral()) {
next(); // Consume the peek next(); // Consume the peek
return std::make_unique<ast::IntLiteral>(t.to_i32()); auto type = ctx_.type_mgr->Get(std::make_unique<ast::type::I32Type>());
if (!type) {
return nullptr;
}
return std::make_unique<ast::IntLiteral>(type, t.to_i32());
} }
if (t.IsUintLiteral()) { if (t.IsUintLiteral()) {
next(); // Consume the peek next(); // Consume the peek
return std::make_unique<ast::UintLiteral>(t.to_u32()); auto type = ctx_.type_mgr->Get(std::make_unique<ast::type::U32Type>());
if (!type) {
return nullptr;
}
return std::make_unique<ast::UintLiteral>(type, t.to_u32());
} }
if (t.IsFloatLiteral()) { if (t.IsFloatLiteral()) {
next(); // Consume the peek next(); // Consume the peek
return std::make_unique<ast::FloatLiteral>(t.to_f32()); auto type = ctx_.type_mgr->Get(std::make_unique<ast::type::F32Type>());
if (!type) {
return nullptr;
}
return std::make_unique<ast::FloatLiteral>(type, t.to_f32());
} }
return nullptr; return nullptr;
} }

View File

@ -1,5 +1,4 @@
// Copyright 2020 The Tint Authors. // Copyright 2020 The Tint Authors. //
//
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
@ -17,12 +16,16 @@
#include <utility> #include <utility>
#include "spirv/unified1/spirv.h" #include "spirv/unified1/spirv.h"
#include "src/ast/bool_literal.h"
#include "src/ast/float_literal.h"
#include "src/ast/int_literal.h"
#include "src/ast/struct.h" #include "src/ast/struct.h"
#include "src/ast/struct_member.h" #include "src/ast/struct_member.h"
#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/type/matrix_type.h" #include "src/ast/type/matrix_type.h"
#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/uint_literal.h"
namespace tint { namespace tint {
namespace writer { namespace writer {
@ -212,6 +215,44 @@ void Builder::GenerateImport(ast::Import* imp) {
import_name_to_id_[imp->name()] = id; import_name_to_id_[imp->name()] = id;
} }
uint32_t Builder::GenerateLiteralIfNeeded(ast::Literal* lit) {
auto type_id = GenerateTypeIfNeeded(lit->type());
if (type_id == 0) {
return 0;
}
auto name = lit->name();
auto val = const_to_id_.find(name);
if (val != const_to_id_.end()) {
return val->second;
}
auto result = result_op();
auto result_id = result.to_i();
if (lit->IsBool()) {
if (lit->AsBool()->IsTrue()) {
push_type(spv::Op::OpConstantTrue, {Operand::Int(type_id), result});
} else {
push_type(spv::Op::OpConstantFalse, {Operand::Int(type_id), result});
}
} else if (lit->IsInt()) {
push_type(spv::Op::OpConstant, {Operand::Int(type_id), result,
Operand::Int(lit->AsInt()->value())});
} else if (lit->IsUint()) {
push_type(spv::Op::OpConstant, {Operand::Int(type_id), result,
Operand::Int(lit->AsUint()->value())});
} else if (lit->IsFloat()) {
push_type(spv::Op::OpConstant, {Operand::Int(type_id), result,
Operand::Float(lit->AsFloat()->value())});
} else {
error_ = "unknown literal type";
return 0;
}
const_to_id_[name] = result_id;
return result_id;
}
uint32_t Builder::GenerateTypeIfNeeded(ast::type::Type* type) { uint32_t Builder::GenerateTypeIfNeeded(ast::type::Type* type) {
if (type->IsAlias()) { if (type->IsAlias()) {
return GenerateTypeIfNeeded(type->AsAlias()->type()); return GenerateTypeIfNeeded(type->AsAlias()->type());

View File

@ -20,6 +20,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "src/ast/literal.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/struct_member.h" #include "src/ast/struct_member.h"
#include "src/writer/spirv/instruction.h" #include "src/writer/spirv/instruction.h"
@ -136,6 +137,10 @@ class Builder {
/// Generates an import instruction /// Generates an import instruction
/// @param imp the import /// @param imp the import
void GenerateImport(ast::Import* imp); void GenerateImport(ast::Import* imp);
/// Generates a literal constant if needed
/// @param lit the literal to generate
/// @returns the ID on success or 0 on failure
uint32_t GenerateLiteralIfNeeded(ast::Literal* lit);
/// Generates a type if not already created /// Generates a type if not already created
/// @param type the type to create /// @param type the type to create
/// @returns the ID to use for the given type. Returns 0 on unknown type. /// @returns the ID to use for the given type. Returns 0 on unknown type.
@ -181,6 +186,7 @@ class Builder {
std::unordered_map<std::string, uint32_t> import_name_to_id_; std::unordered_map<std::string, uint32_t> import_name_to_id_;
std::unordered_map<std::string, uint32_t> func_name_to_id_; std::unordered_map<std::string, uint32_t> func_name_to_id_;
std::unordered_map<std::string, uint32_t> type_name_to_id_; std::unordered_map<std::string, uint32_t> type_name_to_id_;
std::unordered_map<std::string, uint32_t> const_to_id_;
}; };
} // namespace spirv } // namespace spirv

View File

@ -0,0 +1,172 @@
// 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 "gtest/gtest.h"
#include "spirv/unified1/spirv.h"
#include "src/ast/bool_literal.h"
#include "src/ast/float_literal.h"
#include "src/ast/int_literal.h"
#include "src/ast/literal.h"
#include "src/ast/type/bool_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/u32_type.h"
#include "src/ast/uint_literal.h"
#include "src/writer/spirv/builder.h"
#include "src/writer/spirv/spv_dump.h"
namespace tint {
namespace writer {
namespace spirv {
using BuilderTest = testing::Test;
TEST_F(BuilderTest, Literal_Bool_True) {
ast::type::BoolType bool_type;
ast::BoolLiteral b_true(&bool_type, true);
Builder b;
auto id = b.GenerateLiteralIfNeeded(&b_true);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(2, id);
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
)");
}
TEST_F(BuilderTest, Literal_Bool_False) {
ast::type::BoolType bool_type;
ast::BoolLiteral b_false(&bool_type, false);
Builder b;
auto id = b.GenerateLiteralIfNeeded(&b_false);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(2, id);
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
%2 = OpConstantFalse %1
)");
}
TEST_F(BuilderTest, Literal_Bool_Dedup) {
ast::type::BoolType bool_type;
ast::BoolLiteral b_true(&bool_type, true);
ast::BoolLiteral b_false(&bool_type, false);
Builder b;
ASSERT_NE(b.GenerateLiteralIfNeeded(&b_true), 0);
ASSERT_FALSE(b.has_error()) << b.error();
ASSERT_NE(b.GenerateLiteralIfNeeded(&b_false), 0);
ASSERT_FALSE(b.has_error()) << b.error();
ASSERT_NE(b.GenerateLiteralIfNeeded(&b_true), 0);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%3 = OpConstantFalse %1
)");
}
TEST_F(BuilderTest, Literal_I32) {
ast::type::I32Type i32;
ast::IntLiteral i(&i32, -23);
Builder b;
auto id = b.GenerateLiteralIfNeeded(&i);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(2, id);
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 -23
)");
}
TEST_F(BuilderTest, Literal_I32_Dedup) {
ast::type::I32Type i32;
ast::IntLiteral i1(&i32, -23);
ast::IntLiteral i2(&i32, -23);
Builder b;
ASSERT_NE(b.GenerateLiteralIfNeeded(&i1), 0);
ASSERT_NE(b.GenerateLiteralIfNeeded(&i2), 0);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 -23
)");
}
TEST_F(BuilderTest, Literal_U32) {
ast::type::U32Type u32;
ast::UintLiteral i(&u32, 23);
Builder b;
auto id = b.GenerateLiteralIfNeeded(&i);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(2, id);
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 23
)");
}
TEST_F(BuilderTest, Literal_U32_Dedup) {
ast::type::U32Type u32;
ast::UintLiteral i1(&u32, 23);
ast::UintLiteral i2(&u32, 23);
Builder b;
ASSERT_NE(b.GenerateLiteralIfNeeded(&i1), 0);
ASSERT_NE(b.GenerateLiteralIfNeeded(&i2), 0);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 23
)");
}
TEST_F(BuilderTest, Literal_F32) {
ast::type::F32Type f32;
ast::FloatLiteral i(&f32, 23.245f);
Builder b;
auto id = b.GenerateLiteralIfNeeded(&i);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(2, id);
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 23.2450008
)");
}
TEST_F(BuilderTest, Literal_F32_Dedup) {
ast::type::F32Type f32;
ast::FloatLiteral i1(&f32, 23.245f);
ast::FloatLiteral i2(&f32, 23.245f);
Builder b;
ASSERT_NE(b.GenerateLiteralIfNeeded(&i1), 0);
ASSERT_NE(b.GenerateLiteralIfNeeded(&i2), 0);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 23.2450008
)");
}
} // namespace spirv
} // namespace writer
} // namespace tint
;

View File

@ -19,6 +19,7 @@
#include "src/ast/const_initializer_expression.h" #include "src/ast/const_initializer_expression.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/int_literal.h" #include "src/ast/int_literal.h"
#include "src/ast/type/i32_type.h"
#include "src/writer/wgsl/generator_impl.h" #include "src/writer/wgsl/generator_impl.h"
namespace tint { namespace tint {
@ -29,7 +30,8 @@ namespace {
using GeneratorImplTest = testing::Test; using GeneratorImplTest = testing::Test;
TEST_F(GeneratorImplTest, EmitExpression_ArrayAccessor) { TEST_F(GeneratorImplTest, EmitExpression_ArrayAccessor) {
auto lit = std::make_unique<ast::IntLiteral>(5); ast::type::I32Type i32;
auto lit = std::make_unique<ast::IntLiteral>(&i32, 5);
auto idx = std::make_unique<ast::ConstInitializerExpression>(std::move(lit)); auto idx = std::make_unique<ast::ConstInitializerExpression>(std::move(lit));
auto ary = std::make_unique<ast::IdentifierExpression>("ary"); auto ary = std::make_unique<ast::IdentifierExpression>("ary");

View File

@ -20,6 +20,7 @@
#include "src/ast/case_statement.h" #include "src/ast/case_statement.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/int_literal.h" #include "src/ast/int_literal.h"
#include "src/ast/type/i32_type.h"
#include "src/writer/wgsl/generator_impl.h" #include "src/writer/wgsl/generator_impl.h"
namespace tint { namespace tint {
@ -30,7 +31,8 @@ namespace {
using GeneratorImplTest = testing::Test; using GeneratorImplTest = testing::Test;
TEST_F(GeneratorImplTest, Emit_Case) { TEST_F(GeneratorImplTest, Emit_Case) {
auto cond = std::make_unique<ast::IntLiteral>(5); ast::type::I32Type i32;
auto cond = std::make_unique<ast::IntLiteral>(&i32, 5);
std::vector<std::unique_ptr<ast::Statement>> body; std::vector<std::unique_ptr<ast::Statement>> body;
body.push_back(std::make_unique<ast::BreakStatement>()); body.push_back(std::make_unique<ast::BreakStatement>());

View File

@ -38,7 +38,8 @@ namespace {
using GeneratorImplTest = testing::Test; using GeneratorImplTest = testing::Test;
TEST_F(GeneratorImplTest, EmitInitializer_Bool) { TEST_F(GeneratorImplTest, EmitInitializer_Bool) {
auto lit = std::make_unique<ast::BoolLiteral>(false); ast::type::BoolType bool_type;
auto lit = std::make_unique<ast::BoolLiteral>(&bool_type, false);
ast::ConstInitializerExpression expr(std::move(lit)); ast::ConstInitializerExpression expr(std::move(lit));
GeneratorImpl g; GeneratorImpl g;
@ -47,7 +48,8 @@ TEST_F(GeneratorImplTest, EmitInitializer_Bool) {
} }
TEST_F(GeneratorImplTest, EmitInitializer_Int) { TEST_F(GeneratorImplTest, EmitInitializer_Int) {
auto lit = std::make_unique<ast::IntLiteral>(-12345); ast::type::I32Type i32;
auto lit = std::make_unique<ast::IntLiteral>(&i32, -12345);
ast::ConstInitializerExpression expr(std::move(lit)); ast::ConstInitializerExpression expr(std::move(lit));
GeneratorImpl g; GeneratorImpl g;
@ -56,7 +58,8 @@ TEST_F(GeneratorImplTest, EmitInitializer_Int) {
} }
TEST_F(GeneratorImplTest, EmitInitializer_UInt) { TEST_F(GeneratorImplTest, EmitInitializer_UInt) {
auto lit = std::make_unique<ast::UintLiteral>(56779); ast::type::U32Type u32;
auto lit = std::make_unique<ast::UintLiteral>(&u32, 56779);
ast::ConstInitializerExpression expr(std::move(lit)); ast::ConstInitializerExpression expr(std::move(lit));
GeneratorImpl g; GeneratorImpl g;
@ -65,7 +68,8 @@ TEST_F(GeneratorImplTest, EmitInitializer_UInt) {
} }
TEST_F(GeneratorImplTest, EmitInitializer_Float) { TEST_F(GeneratorImplTest, EmitInitializer_Float) {
auto lit = std::make_unique<ast::FloatLiteral>(1.5e27); ast::type::F32Type f32;
auto lit = std::make_unique<ast::FloatLiteral>(&f32, 1.5e27);
ast::ConstInitializerExpression expr(std::move(lit)); ast::ConstInitializerExpression expr(std::move(lit));
GeneratorImpl g; GeneratorImpl g;
@ -76,7 +80,7 @@ TEST_F(GeneratorImplTest, EmitInitializer_Float) {
TEST_F(GeneratorImplTest, EmitInitializer_Type_Float) { TEST_F(GeneratorImplTest, EmitInitializer_Type_Float) {
ast::type::F32Type f32; ast::type::F32Type f32;
auto lit = std::make_unique<ast::FloatLiteral>(-1.2e-5); auto lit = std::make_unique<ast::FloatLiteral>(&f32, -1.2e-5);
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(
std::make_unique<ast::ConstInitializerExpression>(std::move(lit))); std::make_unique<ast::ConstInitializerExpression>(std::move(lit)));
@ -91,7 +95,7 @@ TEST_F(GeneratorImplTest, EmitInitializer_Type_Float) {
TEST_F(GeneratorImplTest, EmitInitializer_Type_Bool) { TEST_F(GeneratorImplTest, EmitInitializer_Type_Bool) {
ast::type::BoolType b; ast::type::BoolType b;
auto lit = std::make_unique<ast::BoolLiteral>(true); auto lit = std::make_unique<ast::BoolLiteral>(&b, true);
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(
std::make_unique<ast::ConstInitializerExpression>(std::move(lit))); std::make_unique<ast::ConstInitializerExpression>(std::move(lit)));
@ -106,7 +110,7 @@ TEST_F(GeneratorImplTest, EmitInitializer_Type_Bool) {
TEST_F(GeneratorImplTest, EmitInitializer_Type_Int) { TEST_F(GeneratorImplTest, EmitInitializer_Type_Int) {
ast::type::I32Type i32; ast::type::I32Type i32;
auto lit = std::make_unique<ast::IntLiteral>(-12345); auto lit = std::make_unique<ast::IntLiteral>(&i32, -12345);
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(
std::make_unique<ast::ConstInitializerExpression>(std::move(lit))); std::make_unique<ast::ConstInitializerExpression>(std::move(lit)));
@ -121,7 +125,7 @@ TEST_F(GeneratorImplTest, EmitInitializer_Type_Int) {
TEST_F(GeneratorImplTest, EmitInitializer_Type_Uint) { TEST_F(GeneratorImplTest, EmitInitializer_Type_Uint) {
ast::type::U32Type u32; ast::type::U32Type u32;
auto lit = std::make_unique<ast::UintLiteral>(12345); auto lit = std::make_unique<ast::UintLiteral>(&u32, 12345);
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(
std::make_unique<ast::ConstInitializerExpression>(std::move(lit))); std::make_unique<ast::ConstInitializerExpression>(std::move(lit)));
@ -137,9 +141,9 @@ TEST_F(GeneratorImplTest, EmitInitializer_Type_Vec) {
ast::type::F32Type f32; ast::type::F32Type f32;
ast::type::VectorType vec(&f32, 3); ast::type::VectorType vec(&f32, 3);
auto lit1 = std::make_unique<ast::FloatLiteral>(1.f); auto lit1 = std::make_unique<ast::FloatLiteral>(&f32, 1.f);
auto lit2 = std::make_unique<ast::FloatLiteral>(2.f); auto lit2 = std::make_unique<ast::FloatLiteral>(&f32, 2.f);
auto lit3 = std::make_unique<ast::FloatLiteral>(3.f); auto lit3 = std::make_unique<ast::FloatLiteral>(&f32, 3.f);
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(
std::make_unique<ast::ConstInitializerExpression>(std::move(lit1))); std::make_unique<ast::ConstInitializerExpression>(std::move(lit1)));
@ -164,8 +168,8 @@ TEST_F(GeneratorImplTest, EmitInitializer_Type_Mat) {
std::vector<std::unique_ptr<ast::Expression>> mat_values; std::vector<std::unique_ptr<ast::Expression>> mat_values;
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
auto lit1 = std::make_unique<ast::FloatLiteral>(1.f + (i * 2)); auto lit1 = std::make_unique<ast::FloatLiteral>(&f32, 1.f + (i * 2));
auto lit2 = std::make_unique<ast::FloatLiteral>(2.f + (i * 2)); auto lit2 = std::make_unique<ast::FloatLiteral>(&f32, 2.f + (i * 2));
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(
@ -195,9 +199,9 @@ TEST_F(GeneratorImplTest, EmitInitializer_Type_Array) {
std::vector<std::unique_ptr<ast::Expression>> ary_values; std::vector<std::unique_ptr<ast::Expression>> ary_values;
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
auto lit1 = std::make_unique<ast::FloatLiteral>(1.f + (i * 3)); auto lit1 = std::make_unique<ast::FloatLiteral>(&f32, 1.f + (i * 3));
auto lit2 = std::make_unique<ast::FloatLiteral>(2.f + (i * 3)); auto lit2 = std::make_unique<ast::FloatLiteral>(&f32, 2.f + (i * 3));
auto lit3 = std::make_unique<ast::FloatLiteral>(3.f + (i * 3)); auto lit3 = std::make_unique<ast::FloatLiteral>(&f32, 3.f + (i * 3));
std::vector<std::unique_ptr<ast::Expression>> values; std::vector<std::unique_ptr<ast::Expression>> values;
values.push_back( values.push_back(

View File

@ -21,6 +21,7 @@
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/int_literal.h" #include "src/ast/int_literal.h"
#include "src/ast/switch_statement.h" #include "src/ast/switch_statement.h"
#include "src/ast/type/i32_type.h"
#include "src/writer/wgsl/generator_impl.h" #include "src/writer/wgsl/generator_impl.h"
namespace tint { namespace tint {
@ -36,7 +37,8 @@ TEST_F(GeneratorImplTest, Emit_Switch) {
def_body.push_back(std::make_unique<ast::BreakStatement>()); def_body.push_back(std::make_unique<ast::BreakStatement>());
def->set_body(std::move(def_body)); def->set_body(std::move(def_body));
auto case_val = std::make_unique<ast::IntLiteral>(5); ast::type::I32Type i32;
auto case_val = std::make_unique<ast::IntLiteral>(&i32, 5);
std::vector<std::unique_ptr<ast::Statement>> case_body; std::vector<std::unique_ptr<ast::Statement>> case_body;
case_body.push_back(std::make_unique<ast::BreakStatement>()); case_body.push_back(std::make_unique<ast::BreakStatement>());