ast: Remove types from ast::Literals

A literal has an implicit type, so there should be no type on the AST node.

This highlighted that the resolver was nto canonicalizing TypeConstructorExpression types, which has been fixed.
This required preservation of the declared type name in order for error messages to contain aliased names.

Bug: tint:724
Change-Id: I21594a3e8a0fb1b73c6c5b46a14b8664b7f28512
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49345
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
Ben Clayton 2021-04-28 13:50:43 +00:00 committed by Commit Bot service account
parent 0bf0fb9b29
commit 109b18f504
34 changed files with 236 additions and 264 deletions

View File

@ -21,11 +21,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::BoolLiteral);
namespace tint {
namespace ast {
BoolLiteral::BoolLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
bool value)
: Base(program_id, source, type), value_(value) {}
BoolLiteral::BoolLiteral(ProgramID program_id, const Source& source, bool value)
: Base(program_id, source), value_(value) {}
BoolLiteral::~BoolLiteral() = default;
@ -40,8 +37,7 @@ std::string BoolLiteral::name() const {
BoolLiteral* BoolLiteral::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto ty = ctx->Clone(type());
return ctx->dst->create<BoolLiteral>(src, ty, value_);
return ctx->dst->create<BoolLiteral>(src, value_);
}
} // namespace ast

View File

@ -28,12 +28,8 @@ class BoolLiteral : public Castable<BoolLiteral, Literal> {
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the input source
/// @param type the type of the literal
/// @param value the bool literals value
BoolLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
bool value);
BoolLiteral(ProgramID program_id, const Source& source, bool value);
~BoolLiteral() override;
/// @returns true if the bool literal is true

View File

@ -21,21 +21,21 @@ namespace {
using BoolLiteralTest = TestHelper;
TEST_F(BoolLiteralTest, True) {
auto* b = create<BoolLiteral>(ty.bool_(), true);
auto* b = create<BoolLiteral>(true);
ASSERT_TRUE(b->Is<BoolLiteral>());
ASSERT_TRUE(b->IsTrue());
ASSERT_FALSE(b->IsFalse());
}
TEST_F(BoolLiteralTest, False) {
auto* b = create<BoolLiteral>(ty.bool_(), false);
auto* b = create<BoolLiteral>(false);
ASSERT_TRUE(b->Is<BoolLiteral>());
ASSERT_FALSE(b->IsTrue());
ASSERT_TRUE(b->IsFalse());
}
TEST_F(BoolLiteralTest, Is) {
ast::Literal* l = create<BoolLiteral>(ty.bool_(), false);
ast::Literal* l = create<BoolLiteral>(false);
EXPECT_TRUE(l->Is<BoolLiteral>());
EXPECT_FALSE(l->Is<SintLiteral>());
EXPECT_FALSE(l->Is<FloatLiteral>());
@ -44,8 +44,8 @@ TEST_F(BoolLiteralTest, Is) {
}
TEST_F(BoolLiteralTest, ToStr) {
auto* t = create<BoolLiteral>(ty.bool_(), true);
auto* f = create<BoolLiteral>(ty.bool_(), false);
auto* t = create<BoolLiteral>(true);
auto* f = create<BoolLiteral>(false);
EXPECT_EQ(str(t), "true");
EXPECT_EQ(str(f), "false");

View File

@ -27,7 +27,7 @@ using CaseStatementTest = TestHelper;
TEST_F(CaseStatementTest, Creation_i32) {
CaseSelectorList b;
auto* selector = create<SintLiteral>(ty.i32(), 2);
auto* selector = create<SintLiteral>(2);
b.push_back(selector);
auto* discard = create<DiscardStatement>();
@ -42,7 +42,7 @@ TEST_F(CaseStatementTest, Creation_i32) {
TEST_F(CaseStatementTest, Creation_u32) {
CaseSelectorList b;
auto* selector = create<SintLiteral>(ty.u32(), 2);
auto* selector = create<UintLiteral>(2u);
b.push_back(selector);
auto* discard = create<DiscardStatement>();
@ -57,7 +57,7 @@ TEST_F(CaseStatementTest, Creation_u32) {
TEST_F(CaseStatementTest, Creation_WithSource) {
CaseSelectorList b;
b.push_back(create<SintLiteral>(ty.i32(), 2));
b.push_back(create<SintLiteral>(2));
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
@ -78,7 +78,7 @@ TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
CaseSelectorList b;
b.push_back(create<SintLiteral>(ty.i32(), 2));
b.push_back(create<SintLiteral>(2));
auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
EXPECT_FALSE(c->IsDefault());
@ -125,16 +125,15 @@ TEST_F(CaseStatementTest, Assert_DifferentProgramID_Selector) {
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CaseStatement>(
CaseSelectorList{b2.create<SintLiteral>(b2.ty.i32(), 2)},
b1.create<BlockStatement>(StatementList{}));
b1.create<CaseStatement>(CaseSelectorList{b2.create<SintLiteral>(2)},
b1.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
}
TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
CaseSelectorList b;
b.push_back(create<SintLiteral>(ty.i32(), -2));
b.push_back(create<SintLiteral>(-2));
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
@ -149,7 +148,7 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
TEST_F(CaseStatementTest, ToStr_WithSelectors_u32) {
CaseSelectorList b;
b.push_back(create<UintLiteral>(ty.u32(), 2));
b.push_back(create<UintLiteral>(2));
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
@ -164,8 +163,8 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors_u32) {
TEST_F(CaseStatementTest, ToStr_WithMultipleSelectors) {
CaseSelectorList b;
b.push_back(create<SintLiteral>(ty.i32(), 1));
b.push_back(create<SintLiteral>(ty.i32(), 2));
b.push_back(create<SintLiteral>(1));
b.push_back(create<SintLiteral>(2));
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),

View File

@ -25,9 +25,8 @@ namespace ast {
FloatLiteral::FloatLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
float value)
: Base(program_id, source, type), value_(value) {}
: Base(program_id, source), value_(value) {}
FloatLiteral::~FloatLiteral() = default;
@ -46,8 +45,7 @@ std::string FloatLiteral::name() const {
FloatLiteral* FloatLiteral::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto ty = ctx->Clone(type());
return ctx->dst->create<FloatLiteral>(src, ty, value_);
return ctx->dst->create<FloatLiteral>(src, value_);
}
} // namespace ast

View File

@ -28,12 +28,8 @@ class FloatLiteral : public Castable<FloatLiteral, Literal> {
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the input source
/// @param type the type of the literal
/// @param value the float literals value
FloatLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
float value);
FloatLiteral(ProgramID program_id, const Source& source, float value);
~FloatLiteral() override;
/// @returns the float literal value

View File

@ -21,13 +21,13 @@ namespace {
using FloatLiteralTest = TestHelper;
TEST_F(FloatLiteralTest, Value) {
auto* f = create<FloatLiteral>(ty.f32(), 47.2f);
auto* f = create<FloatLiteral>(47.2f);
ASSERT_TRUE(f->Is<FloatLiteral>());
EXPECT_EQ(f->value(), 47.2f);
}
TEST_F(FloatLiteralTest, Is) {
ast::Literal* l = create<FloatLiteral>(ty.f32(), 42.f);
ast::Literal* l = create<FloatLiteral>(42.f);
EXPECT_FALSE(l->Is<BoolLiteral>());
EXPECT_FALSE(l->Is<SintLiteral>());
EXPECT_FALSE(l->Is<IntLiteral>());
@ -36,12 +36,12 @@ TEST_F(FloatLiteralTest, Is) {
}
TEST_F(FloatLiteralTest, ToStr) {
auto* f = create<FloatLiteral>(ty.f32(), 42.1f);
auto* f = create<FloatLiteral>(42.1f);
EXPECT_EQ(str(f), "42.099998");
}
TEST_F(FloatLiteralTest, ToName) {
auto* f = create<FloatLiteral>(ty.f32(), 42.1f);
auto* f = create<FloatLiteral>(42.1f);
EXPECT_EQ(f->name(), "__float42.0999985");
}

View File

@ -21,9 +21,8 @@ namespace ast {
IntLiteral::IntLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
uint32_t value)
: Base(program_id, source, type), value_(value) {}
: Base(program_id, source), value_(value) {}
IntLiteral::~IntLiteral() = default;

View File

@ -32,12 +32,8 @@ class IntLiteral : public Castable<IntLiteral, Literal> {
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the input source
/// @param type the type of the literal
/// @param value value of the literal
IntLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
uint32_t value);
IntLiteral(ProgramID program_id, const Source& source, uint32_t value);
private:
uint32_t const value_;

View File

@ -21,12 +21,12 @@ namespace {
using IntLiteralTest = TestHelper;
TEST_F(IntLiteralTest, Sint_IsInt) {
auto* i = create<SintLiteral>(ty.i32(), 47);
auto* i = create<SintLiteral>(47);
ASSERT_TRUE(i->Is<IntLiteral>());
}
TEST_F(IntLiteralTest, Uint_IsInt) {
auto* i = create<UintLiteral>(ty.i32(), 42);
auto* i = create<UintLiteral>(42);
EXPECT_TRUE(i->Is<IntLiteral>());
}

View File

@ -19,8 +19,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::Literal);
namespace tint {
namespace ast {
Literal::Literal(ProgramID program_id, const Source& source, typ::Type type)
: Base(program_id, source), type_(type) {}
Literal::Literal(ProgramID program_id, const Source& source)
: Base(program_id, source) {}
Literal::~Literal() = default;

View File

@ -27,9 +27,6 @@ class Literal : public Castable<Literal, Node> {
public:
~Literal() override;
/// @returns the type of the literal
typ::Type type() const { return type_; }
/// Writes a representation of the node to the output stream
/// @param sem the semantic info for the program
/// @param out the stream to write to
@ -49,11 +46,7 @@ class Literal : public Castable<Literal, Node> {
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the input source
/// @param type the type of the literal
explicit Literal(ProgramID program_id, const Source& source, typ::Type type);
private:
typ::Type const type_;
Literal(ProgramID program_id, const Source& source);
};
} // namespace ast

View File

@ -22,7 +22,7 @@ namespace {
using ScalarConstructorExpressionTest = TestHelper;
TEST_F(ScalarConstructorExpressionTest, Creation) {
auto* b = create<BoolLiteral>(ty.bool_(), true);
auto* b = create<BoolLiteral>(true);
auto* c = create<ScalarConstructorExpression>(b);
EXPECT_EQ(c->literal(), b);
}
@ -45,8 +45,7 @@ TEST_F(ScalarConstructorExpressionTest, Assert_DifferentProgramID_Literal) {
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<ScalarConstructorExpression>(
b2.create<BoolLiteral>(b2.ty.bool_(), true));
b1.create<ScalarConstructorExpression>(b2.create<BoolLiteral>(true));
},
"internal compiler error");
}

View File

@ -23,9 +23,8 @@ namespace ast {
SintLiteral::SintLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
int32_t value)
: Base(program_id, source, type, static_cast<uint32_t>(value)) {}
: Base(program_id, source, static_cast<uint32_t>(value)) {}
SintLiteral::~SintLiteral() = default;
@ -34,14 +33,13 @@ std::string SintLiteral::to_str(const sem::Info&) const {
}
std::string SintLiteral::name() const {
return "__sint" + type()->type_name() + "_" + std::to_string(value());
return "__sint_" + std::to_string(value());
}
SintLiteral* SintLiteral::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto ty = ctx->Clone(type());
return ctx->dst->create<SintLiteral>(src, ty, value());
return ctx->dst->create<SintLiteral>(src, value());
}
} // namespace ast

View File

@ -28,12 +28,8 @@ class SintLiteral : public Castable<SintLiteral, IntLiteral> {
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the input source
/// @param type the type
/// @param value the signed int literals value
SintLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
int32_t value);
SintLiteral(ProgramID program_id, const Source& source, int32_t value);
~SintLiteral() override;
/// @returns the int literal value

View File

@ -21,13 +21,13 @@ namespace {
using SintLiteralTest = TestHelper;
TEST_F(SintLiteralTest, Value) {
auto* i = create<SintLiteral>(ty.i32(), 47);
auto* i = create<SintLiteral>(47);
ASSERT_TRUE(i->Is<SintLiteral>());
EXPECT_EQ(i->value(), 47);
}
TEST_F(SintLiteralTest, Is) {
ast::Literal* l = create<SintLiteral>(ty.i32(), 42);
ast::Literal* l = create<SintLiteral>(42);
EXPECT_FALSE(l->Is<BoolLiteral>());
EXPECT_TRUE(l->Is<SintLiteral>());
EXPECT_FALSE(l->Is<FloatLiteral>());
@ -35,18 +35,13 @@ TEST_F(SintLiteralTest, Is) {
}
TEST_F(SintLiteralTest, ToStr) {
auto* i = create<SintLiteral>(ty.i32(), -42);
auto* i = create<SintLiteral>(-42);
EXPECT_EQ(str(i), "-42");
}
TEST_F(SintLiteralTest, Name_I32) {
auto* i = create<SintLiteral>(ty.i32(), 2);
EXPECT_EQ("__sint__i32_2", i->name());
}
TEST_F(SintLiteralTest, Name_U32) {
auto* i = create<SintLiteral>(ty.u32(), 2);
EXPECT_EQ("__sint__u32_2", i->name());
auto* i = create<SintLiteral>(2);
EXPECT_EQ("__sint_2", i->name());
}
} // namespace

View File

@ -25,7 +25,7 @@ using SwitchStatementTest = TestHelper;
TEST_F(SwitchStatementTest, Creation) {
CaseSelectorList lit;
lit.push_back(create<SintLiteral>(ty.i32(), 1));
lit.push_back(create<SintLiteral>(1));
auto* ident = Expr("ident");
CaseStatementList body;
@ -50,7 +50,7 @@ TEST_F(SwitchStatementTest, Creation_WithSource) {
TEST_F(SwitchStatementTest, IsSwitch) {
CaseSelectorList lit;
lit.push_back(create<SintLiteral>(ty.i32(), 2));
lit.push_back(create<SintLiteral>(2));
auto* ident = Expr("ident");
CaseStatementList body;
@ -127,7 +127,7 @@ TEST_F(SwitchStatementTest, ToStr_Empty) {
TEST_F(SwitchStatementTest, ToStr) {
CaseSelectorList lit;
lit.push_back(create<SintLiteral>(ty.i32(), 2));
lit.push_back(create<SintLiteral>(2));
auto* ident = Expr("ident");
CaseStatementList body;

View File

@ -23,9 +23,8 @@ namespace ast {
UintLiteral::UintLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
uint32_t value)
: Base(program_id, source, type, value) {}
: Base(program_id, source, value) {}
UintLiteral::~UintLiteral() = default;
@ -40,8 +39,7 @@ std::string UintLiteral::name() const {
UintLiteral* UintLiteral::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto ty = ctx->Clone(type());
return ctx->dst->create<UintLiteral>(src, ty, value());
return ctx->dst->create<UintLiteral>(src, value());
}
} // namespace ast

View File

@ -28,12 +28,8 @@ class UintLiteral : public Castable<UintLiteral, IntLiteral> {
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the input source
/// @param type the type of the literal
/// @param value the uint literals value
UintLiteral(ProgramID program_id,
const Source& source,
typ::Type type,
uint32_t value);
UintLiteral(ProgramID program_id, const Source& source, uint32_t value);
~UintLiteral() override;
/// @returns the uint literal value

View File

@ -21,13 +21,13 @@ namespace {
using UintLiteralTest = TestHelper;
TEST_F(UintLiteralTest, Value) {
auto* u = create<UintLiteral>(ty.u32(), 47);
auto* u = create<UintLiteral>(47);
ASSERT_TRUE(u->Is<UintLiteral>());
EXPECT_EQ(u->value(), 47u);
}
TEST_F(UintLiteralTest, Is) {
ast::Literal* l = create<UintLiteral>(ty.u32(), 42);
ast::Literal* l = create<UintLiteral>(42);
EXPECT_FALSE(l->Is<BoolLiteral>());
EXPECT_FALSE(l->Is<SintLiteral>());
EXPECT_FALSE(l->Is<FloatLiteral>());
@ -35,7 +35,7 @@ TEST_F(UintLiteralTest, Is) {
}
TEST_F(UintLiteralTest, ToStr) {
auto* u = create<UintLiteral>(ty.u32(), 42u);
auto* u = create<UintLiteral>(42u);
EXPECT_EQ(str(u), "42u");
}

View File

@ -147,8 +147,7 @@ class InspectorHelper : public ProgramBuilder {
void AddConstantID(std::string name, uint32_t id, typ::Type type, T* val) {
ast::Expression* constructor = nullptr;
if (val) {
constructor =
create<ast::ScalarConstructorExpression>(MakeLiteral(type, val));
constructor = Expr(*val);
}
GlobalConst(name, type, constructor,
ast::DecorationList{
@ -156,34 +155,6 @@ class InspectorHelper : public ProgramBuilder {
});
}
/// @param type AST type of the literal, must resolve to BoolLiteral
/// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(typ::Type type, bool* val) {
return create<ast::BoolLiteral>(type, *val);
}
/// @param type AST type of the literal, must resolve to UIntLiteral
/// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(typ::Type type, uint32_t* val) {
return create<ast::UintLiteral>(type, *val);
}
/// @param type AST type of the literal, must resolve to IntLiteral
/// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(typ::Type type, int32_t* val) {
return create<ast::SintLiteral>(type, *val);
}
/// @param type AST type of the literal, must resolve to FloattLiteral
/// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(typ::Type type, float* val) {
return create<ast::FloatLiteral>(type, *val);
}
/// @param vec Vector of StageVariable to be searched
/// @param name Name to be searching for
/// @returns true if name is in vec, otherwise false

View File

@ -97,19 +97,19 @@ ast::ConstructorExpression* ProgramBuilder::ConstructValueFilledWith(
auto* unwrapped_type = type->UnwrapAliasIfNeeded();
if (unwrapped_type->Is<sem::Bool>()) {
return create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(type, elem_value == 0 ? false : true));
create<ast::BoolLiteral>(elem_value == 0 ? false : true));
}
if (unwrapped_type->Is<sem::I32>()) {
return create<ast::ScalarConstructorExpression>(create<ast::SintLiteral>(
type, static_cast<ProgramBuilder::i32>(elem_value)));
return create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(static_cast<i32>(elem_value)));
}
if (unwrapped_type->Is<sem::U32>()) {
return create<ast::ScalarConstructorExpression>(create<ast::UintLiteral>(
type, static_cast<ProgramBuilder::u32>(elem_value)));
return create<ast::ScalarConstructorExpression>(
create<ast::UintLiteral>(static_cast<u32>(elem_value)));
}
if (unwrapped_type->Is<sem::F32>()) {
return create<ast::ScalarConstructorExpression>(create<ast::FloatLiteral>(
type, static_cast<ProgramBuilder::f32>(elem_value)));
return create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(static_cast<f32>(elem_value)));
}
if (auto* v = unwrapped_type->As<sem::Vector>()) {
ast::ExpressionList el(v->size());

View File

@ -992,27 +992,19 @@ class ProgramBuilder {
/// @param val the boolan value
/// @return a boolean literal with the given value
ast::BoolLiteral* Literal(bool val) {
return create<ast::BoolLiteral>(ty.bool_(), val);
}
ast::BoolLiteral* Literal(bool val) { return create<ast::BoolLiteral>(val); }
/// @param val the float value
/// @return a float literal with the given value
ast::FloatLiteral* Literal(f32 val) {
return create<ast::FloatLiteral>(ty.f32(), val);
}
ast::FloatLiteral* Literal(f32 val) { return create<ast::FloatLiteral>(val); }
/// @param val the unsigned int value
/// @return a ast::UintLiteral with the given value
ast::UintLiteral* Literal(u32 val) {
return create<ast::UintLiteral>(ty.u32(), val);
}
ast::UintLiteral* Literal(u32 val) { return create<ast::UintLiteral>(val); }
/// @param val the integer value
/// @return the ast::SintLiteral with the given value
ast::SintLiteral* Literal(i32 val) {
return create<ast::SintLiteral>(ty.i32(), val);
}
ast::SintLiteral* Literal(i32 val) { return create<ast::SintLiteral>(val); }
/// @param args the arguments for the type constructor
/// @return an `ast::TypeConstructorExpression` of type `ty`, with the values

View File

@ -2032,10 +2032,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
<< id;
return {};
case SkipReason::kPointSizeBuiltinValue: {
auto* f32 = create<sem::F32>();
return {f32,
return {create<sem::F32>(),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, f32, 1.0f))};
Source{}, create<ast::FloatLiteral>(Source{}, 1.0f))};
}
case SkipReason::kPointSizeBuiltinPointer:
Fail() << "unhandled use of a pointer to the PointSize builtin, with ID: "
@ -2545,11 +2544,9 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
// The Tint AST handles 32-bit values.
const uint32_t value32 = uint32_t(value & 0xFFFFFFFF);
if (selector.type->is_unsigned_scalar_or_vector()) {
selectors.emplace_back(
create<ast::UintLiteral>(Source{}, selector.type, value32));
selectors.emplace_back(create<ast::UintLiteral>(Source{}, value32));
} else {
selectors.emplace_back(
create<ast::SintLiteral>(Source{}, selector.type, value32));
selectors.emplace_back(create<ast::SintLiteral>(Source{}, value32));
}
}
}
@ -3679,7 +3676,7 @@ TypedExpression FunctionEmitter::MakeCompositeValueDecomposition(
auto make_index = [this](uint32_t literal) {
return create<ast::ScalarConstructorExpression>(
Source{}, create<ast::UintLiteral>(Source{}, u32_, literal));
Source{}, create<ast::UintLiteral>(Source{}, literal));
};
// Build up a nested expression for the decomposition by walking down the type
@ -3795,13 +3792,13 @@ TypedExpression FunctionEmitter::MakeCompositeValueDecomposition(
ast::Expression* FunctionEmitter::MakeTrue(const Source& source) const {
return create<ast::ScalarConstructorExpression>(
source, create<ast::BoolLiteral>(source, parser_impl_.Bool(), true));
source, create<ast::BoolLiteral>(source, true));
}
ast::Expression* FunctionEmitter::MakeFalse(const Source& source) const {
sem::Bool bool_type;
return create<ast::ScalarConstructorExpression>(
source, create<ast::BoolLiteral>(source, parser_impl_.Bool(), false));
source, create<ast::BoolLiteral>(source, false));
}
TypedExpression FunctionEmitter::MakeVectorShuffle(

View File

@ -1066,9 +1066,8 @@ bool ParserImpl::EmitScalarSpecConstants() {
case SpvOpSpecConstantFalse: {
ast_type = ConvertType(inst.type_id());
ast_expr = create<ast::ScalarConstructorExpression>(
Source{},
create<ast::BoolLiteral>(Source{}, ast_type,
inst.opcode() == SpvOpSpecConstantTrue));
Source{}, create<ast::BoolLiteral>(
Source{}, inst.opcode() == SpvOpSpecConstantTrue));
break;
}
case SpvOpSpecConstant: {
@ -1076,21 +1075,18 @@ bool ParserImpl::EmitScalarSpecConstants() {
const uint32_t literal_value = inst.GetSingleWordInOperand(0);
if (ast_type->Is<sem::I32>()) {
ast_expr = create<ast::ScalarConstructorExpression>(
Source{},
create<ast::SintLiteral>(Source{}, ast_type,
static_cast<int32_t>(literal_value)));
Source{}, create<ast::SintLiteral>(
Source{}, static_cast<int32_t>(literal_value)));
} else if (ast_type->Is<sem::U32>()) {
ast_expr = create<ast::ScalarConstructorExpression>(
Source{},
create<ast::UintLiteral>(Source{}, ast_type,
static_cast<uint32_t>(literal_value)));
Source{}, create<ast::UintLiteral>(
Source{}, static_cast<uint32_t>(literal_value)));
} else if (ast_type->Is<sem::F32>()) {
float float_value;
// Copy the bits so we can read them as a float.
std::memcpy(&float_value, &literal_value, sizeof(float_value));
ast_expr = create<ast::ScalarConstructorExpression>(
Source{},
create<ast::FloatLiteral>(Source{}, ast_type, float_value));
Source{}, create<ast::FloatLiteral>(Source{}, float_value));
} else {
return Fail() << " invalid result type for OpSpecConstant "
<< inst.PrettyPrint();
@ -1421,30 +1417,26 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
// Currently "null<type>" is missing from the WGSL parser.
// See https://bugs.chromium.org/p/tint/issues/detail?id=34
if (ast_type->Is<sem::U32>()) {
return {ast_type,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::UintLiteral>(source, ast_type,
spirv_const->GetU32()))};
return {ast_type, create<ast::ScalarConstructorExpression>(
Source{}, create<ast::UintLiteral>(
source, spirv_const->GetU32()))};
}
if (ast_type->Is<sem::I32>()) {
return {ast_type,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(source, ast_type,
spirv_const->GetS32()))};
return {ast_type, create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(
source, spirv_const->GetS32()))};
}
if (ast_type->Is<sem::F32>()) {
return {ast_type,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(source, ast_type,
spirv_const->GetFloat()))};
return {ast_type, create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(
source, spirv_const->GetFloat()))};
}
if (ast_type->Is<sem::Bool>()) {
const bool value = spirv_const->AsNullConstant()
? false
: spirv_const->AsBoolConstant()->value();
return {ast_type,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(source, ast_type, value))};
return {ast_type, create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(source, value))};
}
auto* spirv_composite_const = spirv_const->AsCompositeConstant();
if (spirv_composite_const != nullptr) {
@ -1498,19 +1490,19 @@ ast::Expression* ParserImpl::MakeNullValue(sem::Type* type) {
if (type->Is<sem::Bool>()) {
return create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, type, false));
Source{}, create<ast::BoolLiteral>(Source{}, false));
}
if (type->Is<sem::U32>()) {
return create<ast::ScalarConstructorExpression>(
Source{}, create<ast::UintLiteral>(Source{}, type, 0u));
Source{}, create<ast::UintLiteral>(Source{}, 0u));
}
if (type->Is<sem::I32>()) {
return create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, type, 0));
Source{}, create<ast::SintLiteral>(Source{}, 0));
}
if (type->Is<sem::F32>()) {
return create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, type, 0.0f));
Source{}, create<ast::FloatLiteral>(Source{}, 0.0f));
}
if (const auto* vec_ty = type->As<sem::Vector>()) {
ast::ExpressionList ast_components;

View File

@ -2840,20 +2840,16 @@ Maybe<ast::AssignmentStatement*> ParserImpl::assignment_stmt() {
Maybe<ast::Literal*> ParserImpl::const_literal() {
auto t = peek();
if (match(Token::Type::kTrue)) {
auto* type = builder_.create<sem::Bool>();
return create<ast::BoolLiteral>(Source{}, type, true);
return create<ast::BoolLiteral>(Source{}, true);
}
if (match(Token::Type::kFalse)) {
auto* type = builder_.create<sem::Bool>();
return create<ast::BoolLiteral>(Source{}, type, false);
return create<ast::BoolLiteral>(Source{}, false);
}
if (match(Token::Type::kSintLiteral)) {
auto* type = builder_.create<sem::I32>();
return create<ast::SintLiteral>(Source{}, type, t.to_i32());
return create<ast::SintLiteral>(Source{}, t.to_i32());
}
if (match(Token::Type::kUintLiteral)) {
auto* type = builder_.create<sem::U32>();
return create<ast::UintLiteral>(Source{}, type, t.to_u32());
return create<ast::UintLiteral>(Source{}, t.to_u32());
}
if (match(Token::Type::kFloatLiteral)) {
auto p = peek();
@ -2861,8 +2857,7 @@ Maybe<ast::Literal*> ParserImpl::const_literal() {
next(); // Consume 'f'
add_error(p.source(), "float literals must not be suffixed with 'f'");
}
auto* type = builder_.create<sem::F32>();
return create<ast::FloatLiteral>(Source{}, type, t.to_f32());
return create<ast::FloatLiteral>(Source{}, t.to_f32());
}
return Failure::kNoMatch;
}

View File

@ -119,7 +119,7 @@ TEST_F(ResolverControlBlockValidationTest,
ast::CaseStatementList switch_body;
ast::CaseSelectorList csl;
csl.push_back(create<ast::UintLiteral>(ty.u32(), 1));
csl.push_back(create<ast::UintLiteral>(1u));
switch_body.push_back(create<ast::CaseStatement>(
Source{Source::Location{12, 34}}, csl, Block()));
@ -178,12 +178,12 @@ TEST_F(ResolverControlBlockValidationTest,
ast::CaseStatementList switch_body;
ast::CaseSelectorList csl_1;
csl_1.push_back(create<ast::UintLiteral>(ty.u32(), 0));
csl_1.push_back(create<ast::UintLiteral>(0u));
switch_body.push_back(create<ast::CaseStatement>(csl_1, Block()));
ast::CaseSelectorList csl_2;
csl_2.push_back(create<ast::UintLiteral>(ty.u32(), 2));
csl_2.push_back(create<ast::UintLiteral>(ty.u32(), 2));
csl_2.push_back(create<ast::UintLiteral>(2u));
csl_2.push_back(create<ast::UintLiteral>(2u));
switch_body.push_back(create<ast::CaseStatement>(
Source{Source::Location{12, 34}}, csl_2, Block()));

View File

@ -350,8 +350,13 @@ Resolver::VariableInfo* Resolver::Variable(
return it->second;
}
auto* ctype = Canonical(type ? type : var->declared_type());
auto* info = variable_infos_.Create(var, ctype);
if (!type) {
type = var->declared_type();
}
auto type_name = type->FriendlyName(builder_->Symbols());
auto* ctype = Canonical(type);
auto* info = variable_infos_.Create(var, ctype, type_name);
variable_to_info_.emplace(var, info);
// Resolve variable's type
@ -1304,29 +1309,35 @@ bool Resolver::Constructor(ast::ConstructorExpression* expr) {
return false;
}
}
SetType(expr, type_ctor->type());
// Now that the argument types have been determined, make sure that they
// obey the constructor type rules laid out in
// https://gpuweb.github.io/gpuweb/wgsl.html#type-constructor-expr.
if (auto* vec_type = type_ctor->type()->As<sem::Vector>()) {
return ValidateVectorConstructor(vec_type, type_ctor->values());
return ValidateVectorConstructor(type_ctor, vec_type,
type_ctor->values());
}
if (auto* mat_type = type_ctor->type()->As<sem::Matrix>()) {
return ValidateMatrixConstructor(mat_type, type_ctor->values());
auto mat_typename = TypeNameOf(type_ctor);
return ValidateMatrixConstructor(type_ctor, mat_type,
type_ctor->values());
}
// TODO(crbug.com/tint/634): Validate array constructor
} else if (auto* scalar_ctor = expr->As<ast::ScalarConstructorExpression>()) {
Mark(scalar_ctor->literal());
SetType(expr, scalar_ctor->literal()->type());
SetType(expr, TypeOf(scalar_ctor->literal()));
} else {
TINT_ICE(diagnostics_) << "unexpected constructor expression type";
}
return true;
}
bool Resolver::ValidateVectorConstructor(const sem::Vector* vec_type,
const ast::ExpressionList& values) {
bool Resolver::ValidateVectorConstructor(
const ast::TypeConstructorExpression* ctor,
const sem::Vector* vec_type,
const ast::ExpressionList& values) {
auto* elem_type = vec_type->type()->UnwrapAll();
size_t value_cardinality_sum = 0;
for (auto* value : values) {
@ -1337,7 +1348,7 @@ bool Resolver::ValidateVectorConstructor(const sem::Vector* vec_type,
"type in vector constructor does not match vector type: "
"expected '" +
elem_type->FriendlyName(builder_->Symbols()) + "', found '" +
value_type->FriendlyName(builder_->Symbols()) + "'",
TypeNameOf(value) + "'",
value->source());
return false;
}
@ -1384,8 +1395,7 @@ bool Resolver::ValidateVectorConstructor(const sem::Vector* vec_type,
const Source& values_start = values[0]->source();
const Source& values_end = values[values.size() - 1]->source();
diagnostics_.add_error(
"attempted to construct '" +
vec_type->FriendlyName(builder_->Symbols()) + "' with " +
"attempted to construct '" + TypeNameOf(ctor) + "' with " +
std::to_string(value_cardinality_sum) + " component(s)",
Source::Combine(values_start, values_end));
return false;
@ -1393,8 +1403,10 @@ bool Resolver::ValidateVectorConstructor(const sem::Vector* vec_type,
return true;
}
bool Resolver::ValidateMatrixConstructor(const sem::Matrix* matrix_type,
const ast::ExpressionList& values) {
bool Resolver::ValidateMatrixConstructor(
const ast::TypeConstructorExpression* ctor,
const sem::Matrix* matrix_type,
const ast::ExpressionList& values) {
// Zero Value expression
if (values.empty()) {
return true;
@ -1407,8 +1419,8 @@ bool Resolver::ValidateMatrixConstructor(const sem::Matrix* matrix_type,
diagnostics_.add_error(
"expected " + std::to_string(matrix_type->columns()) + " '" +
VectorPretty(matrix_type->rows(), elem_type) + "' arguments in '" +
matrix_type->FriendlyName(builder_->Symbols()) +
"' constructor, found " + std::to_string(values.size()),
TypeNameOf(ctor) + "' constructor, found " +
std::to_string(values.size()),
Source::Combine(values_start, values_end));
return false;
}
@ -1419,13 +1431,12 @@ bool Resolver::ValidateMatrixConstructor(const sem::Matrix* matrix_type,
if (!value_vec || value_vec->size() != matrix_type->rows() ||
elem_type != value_vec->type()->UnwrapAll()) {
diagnostics_.add_error(
"expected argument type '" +
VectorPretty(matrix_type->rows(), elem_type) + "' in '" +
matrix_type->FriendlyName(builder_->Symbols()) +
"' constructor, found '" +
value_type->FriendlyName(builder_->Symbols()) + "'",
value->source());
diagnostics_.add_error("expected argument type '" +
VectorPretty(matrix_type->rows(), elem_type) +
"' in '" + TypeNameOf(ctor) +
"' constructor, found '" + TypeNameOf(value) +
"'",
value->source());
return false;
}
}
@ -1440,12 +1451,14 @@ bool Resolver::Identifier(ast::IdentifierExpression* expr) {
// A constant is the type, but a variable is always a pointer so synthesize
// the pointer around the variable type.
if (var->declaration->is_const()) {
SetType(expr, var->type);
SetType(expr, var->type, var->type_name);
} else if (var->type->Is<sem::Pointer>()) {
SetType(expr, var->type);
SetType(expr, var->type, var->type_name);
} else {
SetType(expr, builder_->create<sem::Pointer>(
const_cast<sem::Type*>(var->type), var->storage_class));
SetType(expr,
builder_->create<sem::Pointer>(const_cast<sem::Type*>(var->type),
var->storage_class),
var->type_name);
}
var->users.push_back(expr);
@ -1962,7 +1975,7 @@ bool Resolver::VariableDeclStatement(const ast::VariableDeclStatement* stmt) {
return true;
}
const sem::Type* Resolver::TypeOf(ast::Expression* expr) {
const sem::Type* Resolver::TypeOf(const ast::Expression* expr) {
auto it = expr_info_.find(expr);
if (it != expr_info_.end()) {
return it->second.type;
@ -1970,12 +1983,45 @@ const sem::Type* Resolver::TypeOf(ast::Expression* expr) {
return nullptr;
}
std::string Resolver::TypeNameOf(const ast::Expression* expr) {
auto it = expr_info_.find(expr);
if (it != expr_info_.end()) {
return it->second.type_name;
}
return "";
}
const sem::Type* Resolver::TypeOf(const ast::Literal* lit) {
if (lit->Is<ast::SintLiteral>()) {
return builder_->create<sem::I32>();
}
if (lit->Is<ast::UintLiteral>()) {
return builder_->create<sem::U32>();
}
if (lit->Is<ast::FloatLiteral>()) {
return builder_->create<sem::F32>();
}
if (lit->Is<ast::BoolLiteral>()) {
return builder_->create<sem::Bool>();
}
TINT_UNREACHABLE(diagnostics_)
<< "Unhandled literal type: " << lit->TypeInfo().name;
return nullptr;
}
void Resolver::SetType(ast::Expression* expr, const sem::Type* type) {
SetType(expr, type, type->FriendlyName(builder_->Symbols()));
}
void Resolver::SetType(ast::Expression* expr,
const sem::Type* type,
const std::string& type_name) {
if (expr_info_.count(expr)) {
TINT_ICE(builder_->Diagnostics())
<< "SetType() called twice for the same expression";
}
expr_info_.emplace(expr, ExpressionInfo{type, current_statement_});
type = Canonical(type);
expr_info_.emplace(expr, ExpressionInfo{type, type_name, current_statement_});
}
void Resolver::CreateSemanticNodes() const {
@ -2071,7 +2117,8 @@ void Resolver::CreateSemanticNodes() const {
continue;
}
sem.Add(expr,
builder_->create<sem::Expression>(expr, info.type, info.statement));
builder_->create<sem::Expression>(
const_cast<ast::Expression*>(expr), info.type, info.statement));
}
// Create semantic nodes for all structs
@ -2488,7 +2535,7 @@ bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {
}
for (auto* selector : case_stmt->selectors()) {
if (cond_type != selector->type()) {
if (cond_type != TypeOf(selector)) {
diagnostics_.add_error("v-0026",
"the case selector values must have the same "
"type as the selector expression.",
@ -2729,9 +2776,11 @@ void Resolver::Mark(const ast::Node* node) {
}
Resolver::VariableInfo::VariableInfo(const ast::Variable* decl,
const sem::Type* ctype)
const sem::Type* ctype,
const std::string& tn)
: declaration(decl),
type(ctype),
type_name(tn),
storage_class(decl->declared_storage_class()) {}
Resolver::VariableInfo::~VariableInfo() = default;

View File

@ -96,11 +96,14 @@ class Resolver {
/// Structure holding semantic information about a variable.
/// Used to build the sem::Variable nodes at the end of resolving.
struct VariableInfo {
VariableInfo(const ast::Variable* decl, const sem::Type* type);
VariableInfo(const ast::Variable* decl,
const sem::Type* type,
const std::string& type_name);
~VariableInfo();
ast::Variable const* const declaration;
sem::Type const* type;
std::string const type_name;
ast::StorageClass storage_class;
std::vector<ast::IdentifierExpression*> users;
};
@ -125,6 +128,7 @@ class Resolver {
/// Used to build the sem::Expression nodes at the end of resolving.
struct ExpressionInfo {
sem::Type const* type;
std::string const type_name; // Declared type name
sem::Statement* statement;
};
@ -246,14 +250,16 @@ class Resolver {
bool ValidateEntryPoint(const ast::Function* func, const FunctionInfo* info);
bool ValidateFunction(const ast::Function* func, const FunctionInfo* info);
bool ValidateGlobalVariable(const VariableInfo* var);
bool ValidateMatrixConstructor(const sem::Matrix* matrix_type,
bool ValidateMatrixConstructor(const ast::TypeConstructorExpression* ctor,
const sem::Matrix* matrix_type,
const ast::ExpressionList& values);
bool ValidateParameter(const ast::Variable* param);
bool ValidateReturn(const ast::ReturnStatement* ret);
bool ValidateStructure(const sem::StructType* st);
bool ValidateSwitch(const ast::SwitchStatement* s);
bool ValidateVariable(const ast::Variable* param);
bool ValidateVectorConstructor(const sem::Vector* vec_type,
bool ValidateVectorConstructor(const ast::TypeConstructorExpression* ctor,
const sem::Vector* vec_type,
const ast::ExpressionList& values);
/// @returns the sem::Type for the ast::Type `ty`, building it if it
@ -303,7 +309,15 @@ class Resolver {
/// @returns the resolved type of the ast::Expression `expr`
/// @param expr the expression
const sem::Type* TypeOf(ast::Expression* expr);
const sem::Type* TypeOf(const ast::Expression* expr);
/// @returns the declared type name of the ast::Expression `expr`
/// @param expr the type name
std::string TypeNameOf(const ast::Expression* expr);
/// @returns the semantic type of the AST literal `lit`
/// @param lit the literal
const sem::Type* TypeOf(const ast::Literal* lit);
/// Creates a sem::Expression node with the resolved type `type`, and
/// assigns this semantic node to the expression `expr`.
@ -311,6 +325,16 @@ class Resolver {
/// @param type the resolved type
void SetType(ast::Expression* expr, const sem::Type* type);
/// Creates a sem::Expression node with the resolved type `type`, the declared
/// type name `type_name` and assigns this semantic node to the expression
/// `expr`.
/// @param expr the expression
/// @param type the resolved type
/// @param type_name the declared type name
void SetType(ast::Expression* expr,
const sem::Type* type,
const std::string& type_name);
/// Constructs a new BlockInfo with the given type and with #current_block_ as
/// its parent, assigns this to #current_block_, and then calls `callback`.
/// The original #current_block_ is restored on exit.
@ -340,7 +364,7 @@ class Resolver {
std::unordered_map<const ast::Function*, FunctionInfo*> function_to_info_;
std::unordered_map<const ast::Variable*, VariableInfo*> variable_to_info_;
std::unordered_map<ast::CallExpression*, FunctionCallInfo> function_calls_;
std::unordered_map<ast::Expression*, ExpressionInfo> expr_info_;
std::unordered_map<const ast::Expression*, ExpressionInfo> expr_info_;
std::unordered_map<const sem::StructType*, StructInfo*> struct_info_;
std::unordered_map<const sem::Type*, const sem::Type*> type_to_canonical_;
std::unordered_set<const ast::Node*> marked_;

View File

@ -81,7 +81,7 @@ TEST_F(ResolverTest, Stmt_Case) {
auto* assign = Assign(lhs, rhs);
auto* block = Block(assign);
ast::CaseSelectorList lit;
lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
lit.push_back(create<ast::SintLiteral>(3));
auto* cse = create<ast::CaseStatement>(lit, block);
WrapInFunction(v, cse);

View File

@ -77,7 +77,7 @@ TEST_P(InferTypeTest_FromConstructorExpression, All) {
WrapInFunction(Decl(a), Assign(a_ident, "a"));
ASSERT_TRUE(r()->Resolve()) << r()->error();
ASSERT_EQ(TypeOf(a_ident), ty.pointer(rhs_type, sc));
ASSERT_EQ(TypeOf(a_ident), ty.pointer(rhs_type->UnwrapAliasIfNeeded(), sc));
}
static constexpr Params from_constructor_expression_cases[] = {
@ -173,7 +173,7 @@ TEST_P(InferTypeTest_FromCallExpression, All) {
WrapInFunction(Decl(a), Assign(a_ident, "a"));
ASSERT_TRUE(r()->Resolve()) << r()->error();
ASSERT_EQ(TypeOf(a_ident), ty.pointer(rhs_type, sc));
ASSERT_EQ(TypeOf(a_ident), ty.pointer(rhs_type->UnwrapAliasIfNeeded(), sc));
}
static constexpr Params from_call_expression_cases[] = {
Params{ty_bool_},

View File

@ -1693,7 +1693,7 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) {
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: type in vector constructor does not match vector "
"type: expected 'f32', found 'u32'");
"type: expected 'f32', found 'UnsignedInt'");
}
TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
@ -2040,7 +2040,7 @@ TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) {
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: expected argument type 'vec2<f32>' in 'mat2x2<f32>' "
"constructor, found 'vec2<u32>'");
"constructor, found 'VectorUnsigned2'");
}
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {

View File

@ -752,16 +752,16 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
// then WGSL requires an initializer.
if (ast::HasDecoration<ast::ConstantIdDecoration>(var->decorations())) {
if (type_no_ac->Is<sem::F32>()) {
ast::FloatLiteral l(ProgramID(), Source{}, type_no_ac, 0.0f);
ast::FloatLiteral l(ProgramID(), Source{}, 0.0f);
init_id = GenerateLiteralIfNeeded(var, &l);
} else if (type_no_ac->Is<sem::U32>()) {
ast::UintLiteral l(ProgramID(), Source{}, type_no_ac, 0);
ast::UintLiteral l(ProgramID(), Source{}, 0);
init_id = GenerateLiteralIfNeeded(var, &l);
} else if (type_no_ac->Is<sem::I32>()) {
ast::SintLiteral l(ProgramID(), Source{}, type_no_ac, 0);
ast::SintLiteral l(ProgramID(), Source{}, 0);
init_id = GenerateLiteralIfNeeded(var, &l);
} else if (type_no_ac->Is<sem::Bool>()) {
ast::BoolLiteral l(ProgramID(), Source{}, type_no_ac, false);
ast::BoolLiteral l(ProgramID(), Source{}, false);
init_id = GenerateLiteralIfNeeded(var, &l);
} else {
error_ = "invalid type for constant_id, must be scalar";
@ -2305,8 +2305,7 @@ bool Builder::GenerateTextureIntrinsic(ast::CallExpression* call,
op = spv::Op::OpImageQuerySizeLod;
spirv_params.emplace_back(gen(level));
} else {
ast::SintLiteral i32_0(ProgramID(), Source{},
builder_.create<sem::I32>(), 0);
ast::SintLiteral i32_0(ProgramID(), Source{}, 0);
op = spv::Op::OpImageQuerySizeLod;
spirv_params.emplace_back(
Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
@ -2338,8 +2337,7 @@ bool Builder::GenerateTextureIntrinsic(ast::CallExpression* call,
texture_type->Is<sem::StorageTexture>()) {
op = spv::Op::OpImageQuerySize;
} else {
ast::SintLiteral i32_0(ProgramID(), Source{},
builder_.create<sem::I32>(), 0);
ast::SintLiteral i32_0(ProgramID(), Source{}, 0);
op = spv::Op::OpImageQuerySizeLod;
spirv_params.emplace_back(
Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
@ -2449,8 +2447,7 @@ bool Builder::GenerateTextureIntrinsic(ast::CallExpression* call,
}
spirv_params.emplace_back(gen_arg(Usage::kDepthRef));
sem::F32 f32;
ast::FloatLiteral float_0(ProgramID(), Source{}, &f32, 0.0);
ast::FloatLiteral float_0(ProgramID(), Source{}, 0.0);
image_operands.emplace_back(ImageOperand{
SpvImageOperandsLodMask,
Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))});

View File

@ -22,7 +22,7 @@ namespace spirv {
using BuilderTest = TestHelper;
TEST_F(BuilderTest, Literal_Bool_True) {
auto* b_true = create<ast::BoolLiteral>(ty.bool_(), true);
auto* b_true = create<ast::BoolLiteral>(true);
WrapInFunction(b_true);
spirv::Builder& b = Build();
@ -37,7 +37,7 @@ TEST_F(BuilderTest, Literal_Bool_True) {
}
TEST_F(BuilderTest, Literal_Bool_False) {
auto* b_false = create<ast::BoolLiteral>(ty.bool_(), false);
auto* b_false = create<ast::BoolLiteral>(false);
WrapInFunction(b_false);
spirv::Builder& b = Build();
@ -52,8 +52,8 @@ TEST_F(BuilderTest, Literal_Bool_False) {
}
TEST_F(BuilderTest, Literal_Bool_Dedup) {
auto* b_true = create<ast::BoolLiteral>(ty.bool_(), true);
auto* b_false = create<ast::BoolLiteral>(ty.bool_(), false);
auto* b_true = create<ast::BoolLiteral>(true);
auto* b_false = create<ast::BoolLiteral>(false);
WrapInFunction(b_true, b_false);
spirv::Builder& b = Build();
@ -72,7 +72,7 @@ TEST_F(BuilderTest, Literal_Bool_Dedup) {
}
TEST_F(BuilderTest, Literal_I32) {
auto* i = create<ast::SintLiteral>(ty.i32(), -23);
auto* i = create<ast::SintLiteral>(-23);
WrapInFunction(i);
spirv::Builder& b = Build();
@ -86,8 +86,8 @@ TEST_F(BuilderTest, Literal_I32) {
}
TEST_F(BuilderTest, Literal_I32_Dedup) {
auto* i1 = create<ast::SintLiteral>(ty.i32(), -23);
auto* i2 = create<ast::SintLiteral>(ty.i32(), -23);
auto* i1 = create<ast::SintLiteral>(-23);
auto* i2 = create<ast::SintLiteral>(-23);
WrapInFunction(i1, i2);
spirv::Builder& b = Build();
@ -102,7 +102,7 @@ TEST_F(BuilderTest, Literal_I32_Dedup) {
}
TEST_F(BuilderTest, Literal_U32) {
auto* i = create<ast::UintLiteral>(ty.u32(), 23);
auto* i = create<ast::UintLiteral>(23);
WrapInFunction(i);
spirv::Builder& b = Build();
@ -117,8 +117,8 @@ TEST_F(BuilderTest, Literal_U32) {
}
TEST_F(BuilderTest, Literal_U32_Dedup) {
auto* i1 = create<ast::UintLiteral>(ty.u32(), 23);
auto* i2 = create<ast::UintLiteral>(ty.u32(), 23);
auto* i1 = create<ast::UintLiteral>(23);
auto* i2 = create<ast::UintLiteral>(23);
WrapInFunction(i1, i2);
spirv::Builder& b = Build();
@ -133,7 +133,7 @@ TEST_F(BuilderTest, Literal_U32_Dedup) {
}
TEST_F(BuilderTest, Literal_F32) {
auto* i = create<ast::FloatLiteral>(ty.f32(), 23.245f);
auto* i = create<ast::FloatLiteral>(23.245f);
WrapInFunction(i);
spirv::Builder& b = Build();
@ -148,8 +148,8 @@ TEST_F(BuilderTest, Literal_F32) {
}
TEST_F(BuilderTest, Literal_F32_Dedup) {
auto* i1 = create<ast::FloatLiteral>(ty.f32(), 23.245f);
auto* i2 = create<ast::FloatLiteral>(ty.f32(), 23.245f);
auto* i1 = create<ast::FloatLiteral>(23.245f);
auto* i2 = create<ast::FloatLiteral>(23.245f);
WrapInFunction(i1, i2);
spirv::Builder& b = Build();