tint: Merge [S|U]intLiteralExpression
Merge SintLiteralExpression and UintLiteralExpression with IntLiteralExpression. IntLiteralExpression has a new Suffix field which indicates whether the literal is either a: • 'i' suffixed integer literal • 'u' suffixed integer literal • no-suffix integer literal Have the SPIR-V reader produce no-suffixed literals for i32 types, to keep this change small. In future changes the SPIR-V reader will produce 'i' suffixed types for these. Have all consumers of IntLiteralExpression treat unsuffixed integers the same as 'i'-suffixed literals. Unsuffixed will be treated as abstract in future changes. Removed SemHelper::TypeOf(const ast::LiteralExpression* lit). Fixed: tint:1510 Bug: tint:1504 Change-Id: I443f41984e637ddd948182ee756af1010c5f8226 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88842 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
5afd422e44
commit
8822e2966a
|
@ -288,8 +288,6 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/sampled_texture.h",
|
||||
"ast/sampler.cc",
|
||||
"ast/sampler.h",
|
||||
"ast/sint_literal_expression.cc",
|
||||
"ast/sint_literal_expression.h",
|
||||
"ast/stage_attribute.cc",
|
||||
"ast/stage_attribute.h",
|
||||
"ast/statement.cc",
|
||||
|
@ -322,8 +320,6 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/type_name.h",
|
||||
"ast/u32.cc",
|
||||
"ast/u32.h",
|
||||
"ast/uint_literal_expression.cc",
|
||||
"ast/uint_literal_expression.h",
|
||||
"ast/unary_op.cc",
|
||||
"ast/unary_op.h",
|
||||
"ast/unary_op_expression.cc",
|
||||
|
|
|
@ -174,8 +174,6 @@ set(TINT_LIB_SRCS
|
|||
ast/sampled_texture.h
|
||||
ast/sampler.cc
|
||||
ast/sampler.h
|
||||
ast/sint_literal_expression.cc
|
||||
ast/sint_literal_expression.h
|
||||
ast/stage_attribute.cc
|
||||
ast/stage_attribute.h
|
||||
ast/statement.cc
|
||||
|
@ -211,8 +209,6 @@ set(TINT_LIB_SRCS
|
|||
ast/type_name.h
|
||||
ast/u32.cc
|
||||
ast/u32.h
|
||||
ast/uint_literal_expression.cc
|
||||
ast/uint_literal_expression.h
|
||||
ast/unary_op_expression.cc
|
||||
ast/unary_op_expression.h
|
||||
ast/unary_op.cc
|
||||
|
@ -711,7 +707,6 @@ if(TINT_BUILD_TESTS)
|
|||
ast/return_statement_test.cc
|
||||
ast/sampled_texture_test.cc
|
||||
ast/sampler_test.cc
|
||||
ast/sint_literal_expression_test.cc
|
||||
ast/stage_attribute_test.cc
|
||||
ast/storage_texture_test.cc
|
||||
ast/stride_attribute_test.cc
|
||||
|
@ -725,7 +720,6 @@ if(TINT_BUILD_TESTS)
|
|||
ast/texture_test.cc
|
||||
ast/traverse_expressions_test.cc
|
||||
ast/u32_test.cc
|
||||
ast/uint_literal_expression_test.cc
|
||||
ast/unary_op_expression_test.cc
|
||||
ast/variable_decl_statement_test.cc
|
||||
ast/variable_test.cc
|
||||
|
|
|
@ -29,7 +29,7 @@ std::string SizeExprToString(const Expression* size, const SymbolTable& symbols)
|
|||
return symbols.NameFor(ident->symbol);
|
||||
}
|
||||
if (auto* literal = size->As<IntLiteralExpression>()) {
|
||||
return std::to_string(literal->ValueAsU32());
|
||||
return std::to_string(literal->value);
|
||||
}
|
||||
// This will never be exposed to the user as the Resolver will reject this
|
||||
// expression for array size.
|
||||
|
|
|
@ -26,7 +26,7 @@ using CaseStatementTest = TestHelper;
|
|||
|
||||
TEST_F(CaseStatementTest, Creation_i32) {
|
||||
CaseSelectorList b;
|
||||
auto* selector = create<SintLiteralExpression>(2);
|
||||
auto* selector = Expr(2);
|
||||
b.push_back(selector);
|
||||
|
||||
auto* discard = create<DiscardStatement>();
|
||||
|
@ -41,7 +41,7 @@ TEST_F(CaseStatementTest, Creation_i32) {
|
|||
|
||||
TEST_F(CaseStatementTest, Creation_u32) {
|
||||
CaseSelectorList b;
|
||||
auto* selector = create<UintLiteralExpression>(2u);
|
||||
auto* selector = Expr(2u);
|
||||
b.push_back(selector);
|
||||
|
||||
auto* discard = create<DiscardStatement>();
|
||||
|
@ -56,7 +56,7 @@ TEST_F(CaseStatementTest, Creation_u32) {
|
|||
|
||||
TEST_F(CaseStatementTest, Creation_WithSource) {
|
||||
CaseSelectorList b;
|
||||
b.push_back(create<SintLiteralExpression>(2));
|
||||
b.push_back(Expr(2));
|
||||
|
||||
auto* body = create<BlockStatement>(StatementList{
|
||||
create<DiscardStatement>(),
|
||||
|
@ -77,7 +77,7 @@ TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
|
|||
|
||||
TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
|
||||
CaseSelectorList b;
|
||||
b.push_back(create<SintLiteralExpression>(2));
|
||||
b.push_back(Expr(2));
|
||||
|
||||
auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
|
||||
EXPECT_FALSE(c->IsDefault());
|
||||
|
@ -123,7 +123,7 @@ TEST_F(CaseStatementTest, Assert_DifferentProgramID_Selector) {
|
|||
{
|
||||
ProgramBuilder b1;
|
||||
ProgramBuilder b2;
|
||||
b1.create<CaseStatement>(CaseSelectorList{b2.create<SintLiteralExpression>(2)},
|
||||
b1.create<CaseStatement>(CaseSelectorList{b2.Expr(2)},
|
||||
b1.create<BlockStatement>(StatementList{}));
|
||||
},
|
||||
"internal compiler error");
|
||||
|
|
|
@ -14,12 +14,35 @@
|
|||
|
||||
#include "src/tint/ast/int_literal_expression.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::IntLiteralExpression);
|
||||
|
||||
namespace tint::ast {
|
||||
|
||||
IntLiteralExpression::IntLiteralExpression(ProgramID pid, const Source& src) : Base(pid, src) {}
|
||||
IntLiteralExpression::IntLiteralExpression(ProgramID pid,
|
||||
const Source& src,
|
||||
int64_t val,
|
||||
Suffix suf)
|
||||
: Base(pid, src), value(val), suffix(suf) {}
|
||||
|
||||
IntLiteralExpression::~IntLiteralExpression() = default;
|
||||
|
||||
const IntLiteralExpression* IntLiteralExpression::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<IntLiteralExpression>(src, value, suffix);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, IntLiteralExpression::Suffix suffix) {
|
||||
switch (suffix) {
|
||||
default:
|
||||
return out;
|
||||
case IntLiteralExpression::Suffix::kI:
|
||||
return out << "i";
|
||||
case IntLiteralExpression::Suffix::kU:
|
||||
return out << "u";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tint::ast
|
||||
|
|
|
@ -19,23 +19,46 @@
|
|||
|
||||
namespace tint::ast {
|
||||
|
||||
/// An integer literal. This could be either signed or unsigned.
|
||||
/// An integer literal. The literal may have an 'i', 'u' or no suffix.
|
||||
class IntLiteralExpression : public Castable<IntLiteralExpression, LiteralExpression> {
|
||||
public:
|
||||
~IntLiteralExpression() override;
|
||||
/// Literal suffix
|
||||
enum class Suffix {
|
||||
/// No suffix
|
||||
kNone,
|
||||
/// 'i' suffix (i32)
|
||||
kI,
|
||||
/// 'u' suffix (u32)
|
||||
kU,
|
||||
};
|
||||
|
||||
/// @returns the literal value as a u32
|
||||
virtual uint32_t ValueAsU32() const = 0;
|
||||
|
||||
/// @returns the literal value as an i32
|
||||
int32_t ValueAsI32() const { return static_cast<int32_t>(ValueAsU32()); }
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
IntLiteralExpression(ProgramID pid, const Source& src);
|
||||
}; // namespace ast
|
||||
/// @param val the literal value
|
||||
/// @param suf the literal suffix
|
||||
IntLiteralExpression(ProgramID pid, const Source& src, int64_t val, Suffix suf);
|
||||
|
||||
~IntLiteralExpression() override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const IntLiteralExpression* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The literal value
|
||||
const int64_t value;
|
||||
|
||||
/// The literal suffix
|
||||
const Suffix suffix;
|
||||
};
|
||||
|
||||
/// Writes the integer literal suffix to the std::ostream.
|
||||
/// @param out the std::ostream to write to
|
||||
/// @param suffix the suffix to write
|
||||
/// @returns out so calls can be chained
|
||||
std::ostream& operator<<(std::ostream& out, IntLiteralExpression::Suffix suffix);
|
||||
|
||||
} // namespace tint::ast
|
||||
|
||||
|
|
|
@ -19,14 +19,25 @@ namespace {
|
|||
|
||||
using IntLiteralExpressionTest = TestHelper;
|
||||
|
||||
TEST_F(IntLiteralExpressionTest, Sint_IsInt) {
|
||||
auto* i = create<SintLiteralExpression>(47);
|
||||
TEST_F(IntLiteralExpressionTest, SuffixNone) {
|
||||
auto* i = create<IntLiteralExpression>(42, IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_TRUE(i->Is<IntLiteralExpression>());
|
||||
EXPECT_EQ(i->value, 42);
|
||||
EXPECT_EQ(i->suffix, IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(IntLiteralExpressionTest, Uint_IsInt) {
|
||||
auto* i = create<UintLiteralExpression>(42);
|
||||
EXPECT_TRUE(i->Is<IntLiteralExpression>());
|
||||
TEST_F(IntLiteralExpressionTest, SuffixI) {
|
||||
auto* i = create<IntLiteralExpression>(42, IntLiteralExpression::Suffix::kI);
|
||||
ASSERT_TRUE(i->Is<IntLiteralExpression>());
|
||||
EXPECT_EQ(i->value, 42);
|
||||
EXPECT_EQ(i->suffix, IntLiteralExpression::Suffix::kI);
|
||||
}
|
||||
|
||||
TEST_F(IntLiteralExpressionTest, SuffixU) {
|
||||
auto* i = create<IntLiteralExpression>(42, IntLiteralExpression::Suffix::kU);
|
||||
ASSERT_TRUE(i->Is<IntLiteralExpression>());
|
||||
EXPECT_EQ(i->value, 42);
|
||||
EXPECT_EQ(i->suffix, IntLiteralExpression::Suffix::kU);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/ast/sint_literal_expression.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::SintLiteralExpression);
|
||||
|
||||
namespace tint::ast {
|
||||
|
||||
SintLiteralExpression::SintLiteralExpression(ProgramID pid, const Source& src, int32_t val)
|
||||
: Base(pid, src), value(val) {}
|
||||
|
||||
SintLiteralExpression::~SintLiteralExpression() = default;
|
||||
|
||||
uint32_t SintLiteralExpression::ValueAsU32() const {
|
||||
return static_cast<uint32_t>(value);
|
||||
}
|
||||
|
||||
const SintLiteralExpression* SintLiteralExpression::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<SintLiteralExpression>(src, value);
|
||||
}
|
||||
|
||||
} // namespace tint::ast
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_AST_SINT_LITERAL_EXPRESSION_H_
|
||||
#define SRC_TINT_AST_SINT_LITERAL_EXPRESSION_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/ast/int_literal_expression.h"
|
||||
|
||||
namespace tint::ast {
|
||||
|
||||
/// A signed int literal
|
||||
class SintLiteralExpression final : public Castable<SintLiteralExpression, IntLiteralExpression> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param value the signed int literals value
|
||||
SintLiteralExpression(ProgramID pid, const Source& src, int32_t value);
|
||||
~SintLiteralExpression() override;
|
||||
|
||||
/// @returns the literal value as a u32
|
||||
uint32_t ValueAsU32() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const SintLiteralExpression* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The int literal value
|
||||
const int32_t value;
|
||||
};
|
||||
|
||||
} // namespace tint::ast
|
||||
|
||||
#endif // SRC_TINT_AST_SINT_LITERAL_EXPRESSION_H_
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/ast/test_helper.h"
|
||||
|
||||
namespace tint::ast {
|
||||
namespace {
|
||||
|
||||
using SintLiteralExpressionTest = TestHelper;
|
||||
|
||||
TEST_F(SintLiteralExpressionTest, Value) {
|
||||
auto* i = create<SintLiteralExpression>(47);
|
||||
ASSERT_TRUE(i->Is<SintLiteralExpression>());
|
||||
EXPECT_EQ(i->value, 47);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ast
|
|
@ -24,7 +24,7 @@ using SwitchStatementTest = TestHelper;
|
|||
|
||||
TEST_F(SwitchStatementTest, Creation) {
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(create<SintLiteralExpression>(1));
|
||||
lit.push_back(Expr(1));
|
||||
|
||||
auto* ident = Expr("ident");
|
||||
CaseStatementList body;
|
||||
|
@ -49,7 +49,7 @@ TEST_F(SwitchStatementTest, Creation_WithSource) {
|
|||
|
||||
TEST_F(SwitchStatementTest, IsSwitch) {
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(create<SintLiteralExpression>(2));
|
||||
lit.push_back(Expr(2));
|
||||
|
||||
auto* ident = Expr("ident");
|
||||
CaseStatementList body;
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/ast/uint_literal_expression.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::UintLiteralExpression);
|
||||
|
||||
namespace tint::ast {
|
||||
|
||||
UintLiteralExpression::UintLiteralExpression(ProgramID pid, const Source& src, uint32_t val)
|
||||
: Base(pid, src), value(val) {}
|
||||
|
||||
UintLiteralExpression::~UintLiteralExpression() = default;
|
||||
|
||||
uint32_t UintLiteralExpression::ValueAsU32() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
const UintLiteralExpression* UintLiteralExpression::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<UintLiteralExpression>(src, value);
|
||||
}
|
||||
|
||||
} // namespace tint::ast
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_AST_UINT_LITERAL_EXPRESSION_H_
|
||||
#define SRC_TINT_AST_UINT_LITERAL_EXPRESSION_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/ast/int_literal_expression.h"
|
||||
|
||||
namespace tint::ast {
|
||||
|
||||
/// A uint literal
|
||||
class UintLiteralExpression final : public Castable<UintLiteralExpression, IntLiteralExpression> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param value the uint literals value
|
||||
UintLiteralExpression(ProgramID pid, const Source& src, uint32_t value);
|
||||
~UintLiteralExpression() override;
|
||||
|
||||
/// @returns the literal value as a u32
|
||||
uint32_t ValueAsU32() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const UintLiteralExpression* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The int literal value
|
||||
const uint32_t value;
|
||||
};
|
||||
|
||||
} // namespace tint::ast
|
||||
|
||||
#endif // SRC_TINT_AST_UINT_LITERAL_EXPRESSION_H_
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/ast/test_helper.h"
|
||||
|
||||
namespace tint::ast {
|
||||
namespace {
|
||||
|
||||
using UintLiteralExpressionTest = TestHelper;
|
||||
|
||||
TEST_F(UintLiteralExpressionTest, Value) {
|
||||
auto* u = create<UintLiteralExpression>(47);
|
||||
ASSERT_TRUE(u->Is<UintLiteralExpression>());
|
||||
EXPECT_EQ(u->value, 47u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ast
|
|
@ -27,7 +27,7 @@ TEST_F(WorkgroupAttributeTest, Creation_1param) {
|
|||
auto values = d->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
|
||||
EXPECT_EQ(values[1], nullptr);
|
||||
EXPECT_EQ(values[2], nullptr);
|
||||
|
@ -37,10 +37,10 @@ TEST_F(WorkgroupAttributeTest, Creation_2param) {
|
|||
auto values = d->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
|
||||
EXPECT_EQ(values[2], nullptr);
|
||||
}
|
||||
|
@ -50,13 +50,13 @@ TEST_F(WorkgroupAttributeTest, Creation_3param) {
|
|||
auto values = d->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
|
||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->value, 6);
|
||||
}
|
||||
|
||||
TEST_F(WorkgroupAttributeTest, Creation_WithIdentifier) {
|
||||
|
@ -64,10 +64,10 @@ TEST_F(WorkgroupAttributeTest, Creation_WithIdentifier) {
|
|||
auto values = d->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
|
||||
auto* z_ident = As<ast::IdentifierExpression>(values[2]);
|
||||
ASSERT_TRUE(z_ident);
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include "src/tint/ast/interpolate_attribute.h"
|
||||
#include "src/tint/ast/location_attribute.h"
|
||||
#include "src/tint/ast/module.h"
|
||||
#include "src/tint/ast/sint_literal_expression.h"
|
||||
#include "src/tint/ast/uint_literal_expression.h"
|
||||
#include "src/tint/sem/array.h"
|
||||
#include "src/tint/sem/call.h"
|
||||
#include "src/tint/sem/depth_multisampled_texture.h"
|
||||
|
@ -248,14 +246,16 @@ std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (auto* l = literal->As<ast::UintLiteralExpression>()) {
|
||||
result[constant_id] = Scalar(l->value);
|
||||
if (auto* l = literal->As<ast::IntLiteralExpression>()) {
|
||||
switch (l->suffix) {
|
||||
case ast::IntLiteralExpression::Suffix::kNone:
|
||||
case ast::IntLiteralExpression::Suffix::kI:
|
||||
result[constant_id] = Scalar(static_cast<int32_t>(l->value));
|
||||
continue;
|
||||
case ast::IntLiteralExpression::Suffix::kU:
|
||||
result[constant_id] = Scalar(static_cast<uint32_t>(l->value));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto* l = literal->As<ast::SintLiteralExpression>()) {
|
||||
result[constant_id] = Scalar(l->value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto* l = literal->As<ast::FloatLiteralExpression>()) {
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#include "src/tint/ast/return_statement.h"
|
||||
#include "src/tint/ast/sampled_texture.h"
|
||||
#include "src/tint/ast/sampler.h"
|
||||
#include "src/tint/ast/sint_literal_expression.h"
|
||||
#include "src/tint/ast/stage_attribute.h"
|
||||
#include "src/tint/ast/storage_texture.h"
|
||||
#include "src/tint/ast/stride_attribute.h"
|
||||
|
@ -71,7 +70,6 @@
|
|||
#include "src/tint/ast/switch_statement.h"
|
||||
#include "src/tint/ast/type_name.h"
|
||||
#include "src/tint/ast/u32.h"
|
||||
#include "src/tint/ast/uint_literal_expression.h"
|
||||
#include "src/tint/ast/unary_op_expression.h"
|
||||
#include "src/tint/ast/variable_decl_statement.h"
|
||||
#include "src/tint/ast/vector.h"
|
||||
|
@ -1018,27 +1016,29 @@ class ProgramBuilder {
|
|||
/// @param source the source information
|
||||
/// @param value the integer value
|
||||
/// @return a Scalar constructor for the given value
|
||||
const ast::SintLiteralExpression* Expr(const Source& source, i32 value) {
|
||||
return create<ast::SintLiteralExpression>(source, value);
|
||||
const ast::IntLiteralExpression* Expr(const Source& source, i32 value) {
|
||||
return create<ast::IntLiteralExpression>(source, value,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
/// @param value the integer value
|
||||
/// @return a Scalar constructor for the given value
|
||||
const ast::SintLiteralExpression* Expr(i32 value) {
|
||||
return create<ast::SintLiteralExpression>(value);
|
||||
const ast::IntLiteralExpression* Expr(i32 value) {
|
||||
return create<ast::IntLiteralExpression>(value, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
/// @param source the source information
|
||||
/// @param value the unsigned int value
|
||||
/// @return a Scalar constructor for the given value
|
||||
const ast::UintLiteralExpression* Expr(const Source& source, u32 value) {
|
||||
return create<ast::UintLiteralExpression>(source, value);
|
||||
const ast::IntLiteralExpression* Expr(const Source& source, u32 value) {
|
||||
return create<ast::IntLiteralExpression>(source, value,
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
}
|
||||
|
||||
/// @param value the unsigned int value
|
||||
/// @return a Scalar constructor for the given value
|
||||
const ast::UintLiteralExpression* Expr(u32 value) {
|
||||
return create<ast::UintLiteralExpression>(value);
|
||||
const ast::IntLiteralExpression* Expr(u32 value) {
|
||||
return create<ast::IntLiteralExpression>(value, ast::IntLiteralExpression::Suffix::kU);
|
||||
}
|
||||
|
||||
/// Converts `arg` to an `ast::Expression` using `Expr()`, then appends it to
|
||||
|
|
|
@ -2986,9 +2986,12 @@ 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->IsUnsignedScalarOrVector()) {
|
||||
selectors.emplace_back(create<ast::UintLiteralExpression>(Source{}, value32));
|
||||
selectors.emplace_back(create<ast::IntLiteralExpression>(
|
||||
Source{}, value32, ast::IntLiteralExpression::Suffix::kU));
|
||||
} else {
|
||||
selectors.emplace_back(create<ast::SintLiteralExpression>(Source{}, value32));
|
||||
selectors.emplace_back(create<ast::IntLiteralExpression>(
|
||||
Source{}, static_cast<int32_t>(value32),
|
||||
ast::IntLiteralExpression::Suffix::kNone));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4298,7 +4301,8 @@ TypedExpression FunctionEmitter::MakeCompositeValueDecomposition(
|
|||
auto current_type_id = composite_type_id;
|
||||
|
||||
auto make_index = [this](uint32_t literal) {
|
||||
return create<ast::UintLiteralExpression>(Source{}, literal);
|
||||
return create<ast::IntLiteralExpression>(Source{}, literal,
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
};
|
||||
|
||||
// Build up a nested expression for the decomposition by walking down the type
|
||||
|
|
|
@ -1327,18 +1327,25 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
|||
case SpvOpSpecConstant: {
|
||||
ast_type = ConvertType(inst.type_id());
|
||||
const uint32_t literal_value = inst.GetSingleWordInOperand(0);
|
||||
if (ast_type->Is<I32>()) {
|
||||
ast_expr = create<ast::SintLiteralExpression>(
|
||||
Source{}, static_cast<int32_t>(literal_value));
|
||||
} else if (ast_type->Is<U32>()) {
|
||||
ast_expr = create<ast::UintLiteralExpression>(
|
||||
Source{}, static_cast<uint32_t>(literal_value));
|
||||
} else if (ast_type->Is<F32>()) {
|
||||
ast_expr = Switch(
|
||||
ast_type, //
|
||||
[&](const I32*) {
|
||||
return create<ast::IntLiteralExpression>(
|
||||
Source{}, static_cast<int64_t>(literal_value),
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
},
|
||||
[&](const U32*) {
|
||||
return create<ast::IntLiteralExpression>(
|
||||
Source{}, static_cast<uint64_t>(literal_value),
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
},
|
||||
[&](const 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::FloatLiteralExpression>(Source{}, float_value);
|
||||
} else {
|
||||
return create<ast::FloatLiteralExpression>(Source{}, float_value);
|
||||
});
|
||||
if (ast_expr == nullptr) {
|
||||
return Fail() << " invalid result type for OpSpecConstant "
|
||||
<< inst.PrettyPrint();
|
||||
}
|
||||
|
@ -1895,22 +1902,31 @@ TypedExpression ParserImpl::MakeConstantExpressionForScalarSpirvConstant(
|
|||
// So canonicalization should map that way too.
|
||||
// Currently "null<type>" is missing from the WGSL parser.
|
||||
// See https://bugs.chromium.org/p/tint/issues/detail?id=34
|
||||
if (ast_type->Is<U32>()) {
|
||||
return {ty_.U32(), create<ast::UintLiteralExpression>(source, spirv_const->GetU32())};
|
||||
}
|
||||
if (ast_type->Is<I32>()) {
|
||||
return {ty_.I32(), create<ast::SintLiteralExpression>(source, spirv_const->GetS32())};
|
||||
}
|
||||
if (ast_type->Is<F32>()) {
|
||||
return {ty_.F32(), create<ast::FloatLiteralExpression>(source, spirv_const->GetFloat())};
|
||||
}
|
||||
if (ast_type->Is<Bool>()) {
|
||||
return Switch(
|
||||
ast_type,
|
||||
[&](const I32*) {
|
||||
return TypedExpression{ty_.I32(), create<ast::IntLiteralExpression>(
|
||||
source, spirv_const->GetS32(),
|
||||
ast::IntLiteralExpression::Suffix::kNone)};
|
||||
},
|
||||
[&](const U32*) {
|
||||
return TypedExpression{ty_.U32(), create<ast::IntLiteralExpression>(
|
||||
source, spirv_const->GetU32(),
|
||||
ast::IntLiteralExpression::Suffix::kU)};
|
||||
},
|
||||
[&](const F32*) {
|
||||
return TypedExpression{
|
||||
ty_.F32(), create<ast::FloatLiteralExpression>(source, spirv_const->GetFloat())};
|
||||
},
|
||||
[&](const Bool*) {
|
||||
const bool value =
|
||||
spirv_const->AsNullConstant() ? false : spirv_const->AsBoolConstant()->value();
|
||||
return {ty_.Bool(), create<ast::BoolLiteralExpression>(source, value)};
|
||||
}
|
||||
return TypedExpression{ty_.Bool(), create<ast::BoolLiteralExpression>(source, value)};
|
||||
},
|
||||
[&](Default) {
|
||||
Fail() << "expected scalar constant";
|
||||
return {};
|
||||
return TypedExpression{};
|
||||
});
|
||||
}
|
||||
|
||||
const ast::Expression* ParserImpl::MakeNullValue(const Type* type) {
|
||||
|
@ -1927,31 +1943,33 @@ const ast::Expression* ParserImpl::MakeNullValue(const Type* type) {
|
|||
auto* original_type = type;
|
||||
type = type->UnwrapAlias();
|
||||
|
||||
if (type->Is<Bool>()) {
|
||||
return create<ast::BoolLiteralExpression>(Source{}, false);
|
||||
}
|
||||
if (type->Is<U32>()) {
|
||||
return create<ast::UintLiteralExpression>(Source{}, 0u);
|
||||
}
|
||||
if (type->Is<I32>()) {
|
||||
return create<ast::SintLiteralExpression>(Source{}, 0);
|
||||
}
|
||||
if (type->Is<F32>()) {
|
||||
return create<ast::FloatLiteralExpression>(Source{}, 0.0f);
|
||||
}
|
||||
if (type->IsAnyOf<Vector, Matrix, Array>()) {
|
||||
return builder_.Construct(Source{}, type->Build(builder_));
|
||||
}
|
||||
if (auto* struct_ty = type->As<Struct>()) {
|
||||
return Switch(
|
||||
type, //
|
||||
[&](const I32*) {
|
||||
return create<ast::IntLiteralExpression>(Source{}, 0,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
},
|
||||
[&](const U32*) {
|
||||
return create<ast::IntLiteralExpression>(Source{}, 0,
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
},
|
||||
[&](const F32*) { return create<ast::FloatLiteralExpression>(Source{}, 0.0f); },
|
||||
[&](const Vector*) { return builder_.Construct(Source{}, type->Build(builder_)); },
|
||||
[&](const Matrix*) { return builder_.Construct(Source{}, type->Build(builder_)); },
|
||||
[&](const Array*) { return builder_.Construct(Source{}, type->Build(builder_)); },
|
||||
[&](const Bool*) { return create<ast::BoolLiteralExpression>(Source{}, false); },
|
||||
[&](const Struct* struct_ty) {
|
||||
ast::ExpressionList ast_components;
|
||||
for (auto* member : struct_ty->members) {
|
||||
ast_components.emplace_back(MakeNullValue(member));
|
||||
}
|
||||
return builder_.Construct(Source{}, original_type->Build(builder_),
|
||||
std::move(ast_components));
|
||||
}
|
||||
},
|
||||
[&](Default) {
|
||||
Fail() << "can't make null value for type: " << type->TypeInfo().name;
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
TypedExpression ParserImpl::MakeNullExpression(const Type* type) {
|
||||
|
|
|
@ -2772,20 +2772,22 @@ Maybe<const ast::Statement*> ParserImpl::assignment_stmt() {
|
|||
|
||||
// const_literal
|
||||
// : INT_LITERAL
|
||||
// | UINT_LITERAL
|
||||
// | FLOAT_LITERAL
|
||||
// | TRUE
|
||||
// | FALSE
|
||||
Maybe<const ast::LiteralExpression*> ParserImpl::const_literal() {
|
||||
auto t = peek();
|
||||
if (match(Token::Type::kIntLiteral)) {
|
||||
return create<ast::SintLiteralExpression>(t.source(), static_cast<int32_t>(t.to_i64()));
|
||||
return create<ast::IntLiteralExpression>(t.source(), t.to_i64(),
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
if (match(Token::Type::kIntILiteral)) {
|
||||
return create<ast::SintLiteralExpression>(t.source(), static_cast<int32_t>(t.to_i64()));
|
||||
return create<ast::IntLiteralExpression>(t.source(), t.to_i64(),
|
||||
ast::IntLiteralExpression::Suffix::kI);
|
||||
}
|
||||
if (match(Token::Type::kIntULiteral)) {
|
||||
return create<ast::UintLiteralExpression>(t.source(), static_cast<uint32_t>(t.to_i64()));
|
||||
return create<ast::IntLiteralExpression>(t.source(), t.to_i64(),
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
}
|
||||
if (match(Token::Type::kFloatLiteral)) {
|
||||
return create<ast::FloatLiteralExpression>(t.source(), t.to_f32());
|
||||
|
|
|
@ -34,8 +34,10 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToVariable) {
|
|||
auto* ident = a->lhs->As<ast::IdentifierExpression>();
|
||||
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
|
||||
|
||||
ASSERT_TRUE(a->rhs->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::SintLiteralExpression>()->value, 123);
|
||||
ASSERT_TRUE(a->rhs->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->value, 123);
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
||||
|
@ -51,8 +53,10 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
|||
ASSERT_NE(a->lhs, nullptr);
|
||||
ASSERT_NE(a->rhs, nullptr);
|
||||
|
||||
ASSERT_TRUE(a->rhs->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::SintLiteralExpression>()->value, 123);
|
||||
ASSERT_TRUE(a->rhs->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->value, 123);
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(a->lhs->Is<ast::MemberAccessorExpression>());
|
||||
auto* mem = a->lhs->As<ast::MemberAccessorExpression>();
|
||||
|
@ -65,8 +69,8 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
|||
auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
|
||||
|
||||
ASSERT_NE(idx->index, nullptr);
|
||||
ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
|
||||
ASSERT_TRUE(idx->index->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(idx->index->As<ast::IntLiteralExpression>()->value, 2);
|
||||
|
||||
ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
|
||||
mem = idx->object->As<ast::MemberAccessorExpression>();
|
||||
|
@ -87,7 +91,7 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
|||
}
|
||||
|
||||
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToPhony) {
|
||||
auto p = parser("_ = 123");
|
||||
auto p = parser("_ = 123i");
|
||||
auto e = p->assignment_stmt();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -99,14 +103,16 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToPhony) {
|
|||
ASSERT_NE(a->lhs, nullptr);
|
||||
ASSERT_NE(a->rhs, nullptr);
|
||||
|
||||
ASSERT_TRUE(a->rhs->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::SintLiteralExpression>()->value, 123);
|
||||
ASSERT_TRUE(a->rhs->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->value, 123);
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kI);
|
||||
|
||||
ASSERT_TRUE(a->lhs->Is<ast::PhonyExpression>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, AssignmentStmt_Parses_CompoundOp) {
|
||||
auto p = parser("a += 123");
|
||||
auto p = parser("a += 123u");
|
||||
auto e = p->assignment_stmt();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -123,8 +129,10 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_CompoundOp) {
|
|||
auto* ident = a->lhs->As<ast::IdentifierExpression>();
|
||||
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
|
||||
|
||||
ASSERT_TRUE(a->rhs->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::SintLiteralExpression>()->value, 123);
|
||||
ASSERT_TRUE(a->rhs->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->value, 123);
|
||||
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, AssignmentStmt_MissingEqual) {
|
||||
|
|
|
@ -49,8 +49,10 @@ TEST_F(ParserImplTest, ConstLiteral_Int) {
|
|||
EXPECT_FALSE(c.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(c.value, nullptr);
|
||||
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, 234);
|
||||
ASSERT_TRUE(c->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->value, 234);
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
|
||||
}
|
||||
{
|
||||
|
@ -60,8 +62,10 @@ TEST_F(ParserImplTest, ConstLiteral_Int) {
|
|||
EXPECT_FALSE(c.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(c.value, nullptr);
|
||||
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, 234);
|
||||
ASSERT_TRUE(c->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->value, 234);
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kI);
|
||||
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
|
||||
}
|
||||
{
|
||||
|
@ -71,8 +75,10 @@ TEST_F(ParserImplTest, ConstLiteral_Int) {
|
|||
EXPECT_FALSE(c.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(c.value, nullptr);
|
||||
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, -234);
|
||||
ASSERT_TRUE(c->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->value, -234);
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
|
||||
}
|
||||
{
|
||||
|
@ -82,8 +88,10 @@ TEST_F(ParserImplTest, ConstLiteral_Int) {
|
|||
EXPECT_FALSE(c.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(c.value, nullptr);
|
||||
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, -234);
|
||||
ASSERT_TRUE(c->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->value, -234);
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kI);
|
||||
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 6u}}));
|
||||
}
|
||||
}
|
||||
|
@ -95,8 +103,9 @@ TEST_F(ParserImplTest, ConstLiteral_Uint) {
|
|||
EXPECT_FALSE(c.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(c.value, nullptr);
|
||||
ASSERT_TRUE(c->Is<ast::UintLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::UintLiteralExpression>()->value, 234u);
|
||||
ASSERT_TRUE(c->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->value, 234);
|
||||
EXPECT_EQ(c->As<ast::IntLiteralExpression>()->suffix, ast::IntLiteralExpression::Suffix::kU);
|
||||
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,9 @@ TEST_F(ParserImplTest, AttributeList_Parses) {
|
|||
auto* x_literal = x->As<ast::LiteralExpression>();
|
||||
ASSERT_NE(x_literal, nullptr);
|
||||
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
|
||||
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->value, 2);
|
||||
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_TRUE(attr_1->Is<ast::StageAttribute>());
|
||||
EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ TEST_F(ParserImplTest, Attribute_Workgroup) {
|
|||
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
EXPECT_EQ(values[1], nullptr);
|
||||
EXPECT_EQ(values[2], nullptr);
|
||||
|
@ -53,10 +55,14 @@ TEST_F(ParserImplTest, Attribute_Workgroup_2Param) {
|
|||
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 5);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
EXPECT_EQ(values[2], nullptr);
|
||||
}
|
||||
|
@ -75,13 +81,19 @@ TEST_F(ParserImplTest, Attribute_Workgroup_3Param) {
|
|||
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 5);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->value, 6);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
|
||||
|
@ -98,7 +110,9 @@ TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
|
|||
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_NE(values[1], nullptr);
|
||||
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
|
||||
|
|
|
@ -116,13 +116,19 @@ TEST_F(ParserImplTest, FunctionDecl_AttributeList) {
|
|||
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 3u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 3);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
auto* body = f->body;
|
||||
ASSERT_EQ(body->statements.size(), 1u);
|
||||
|
@ -155,13 +161,19 @@ fn main() { return; })");
|
|||
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 3u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 3);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(attributes[1]->Is<ast::StageAttribute>());
|
||||
EXPECT_EQ(attributes[1]->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
|
||||
|
@ -198,13 +210,19 @@ fn main() { return; })");
|
|||
auto values = attrs[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 3u);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->value, 3);
|
||||
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(attrs[1]->Is<ast::StageAttribute>());
|
||||
EXPECT_EQ(attrs[1]->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
|
||||
|
|
|
@ -98,8 +98,8 @@ TEST_F(ParserImplTest, IncrementDecrementStmt_ToMember) {
|
|||
auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
|
||||
|
||||
ASSERT_NE(idx->index, nullptr);
|
||||
ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
|
||||
ASSERT_TRUE(idx->index->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(idx->index->As<ast::IntLiteralExpression>()->value, 2);
|
||||
|
||||
ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
|
||||
mem = idx->object->As<ast::MemberAccessorExpression>();
|
||||
|
|
|
@ -44,17 +44,25 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl) {
|
|||
|
||||
ASSERT_EQ(call->args.size(), 4u);
|
||||
const auto& val = call->args;
|
||||
ASSERT_TRUE(val[0]->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(val[0]->As<ast::SintLiteralExpression>()->value, 1);
|
||||
ASSERT_TRUE(val[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(val[0]->As<ast::IntLiteralExpression>()->value, 1);
|
||||
EXPECT_EQ(val[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(val[1]->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(val[1]->As<ast::SintLiteralExpression>()->value, 2);
|
||||
ASSERT_TRUE(val[1]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(val[1]->As<ast::IntLiteralExpression>()->value, 2);
|
||||
EXPECT_EQ(val[1]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(val[2]->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(val[2]->As<ast::SintLiteralExpression>()->value, 3);
|
||||
ASSERT_TRUE(val[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(val[2]->As<ast::IntLiteralExpression>()->value, 3);
|
||||
EXPECT_EQ(val[2]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(val[3]->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(val[3]->As<ast::SintLiteralExpression>()->value, 4);
|
||||
ASSERT_TRUE(val[3]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(val[3]->As<ast::IntLiteralExpression>()->value, 4);
|
||||
EXPECT_EQ(val[3]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_ZeroConstructor) {
|
||||
|
@ -158,8 +166,10 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructConstructor_NotEmpty) {
|
|||
|
||||
ASSERT_EQ(call->args.size(), 2u);
|
||||
|
||||
ASSERT_TRUE(call->args[0]->Is<ast::UintLiteralExpression>());
|
||||
EXPECT_EQ(call->args[0]->As<ast::UintLiteralExpression>()->value, 1u);
|
||||
ASSERT_TRUE(call->args[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(call->args[0]->As<ast::IntLiteralExpression>()->value, 1u);
|
||||
EXPECT_EQ(call->args[0]->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
|
||||
ASSERT_TRUE(call->args[1]->Is<ast::FloatLiteralExpression>());
|
||||
EXPECT_EQ(call->args[1]->As<ast::FloatLiteralExpression>()->value, 2.f);
|
||||
|
|
|
@ -32,8 +32,10 @@ TEST_F(ParserImplTest, SingularExpression_Array_ConstantIndex) {
|
|||
auto* ident = idx->object->As<ast::IdentifierExpression>();
|
||||
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
|
||||
|
||||
ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 1);
|
||||
ASSERT_TRUE(idx->index->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(idx->index->As<ast::IntLiteralExpression>()->value, 1);
|
||||
EXPECT_EQ(idx->index->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SingularExpression_Array_ExpressionIndex) {
|
||||
|
|
|
@ -28,7 +28,8 @@ TEST_F(ParserImplTest, SwitchBody_Case) {
|
|||
EXPECT_FALSE(e->IsDefault());
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.size(), 1u);
|
||||
EXPECT_EQ(stmt->selectors[0]->ValueAsU32(), 1u);
|
||||
EXPECT_EQ(stmt->selectors[0]->value, 1);
|
||||
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_EQ(e->body->statements.size(), 1u);
|
||||
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||
}
|
||||
|
@ -44,7 +45,8 @@ TEST_F(ParserImplTest, SwitchBody_Case_WithColon) {
|
|||
EXPECT_FALSE(e->IsDefault());
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.size(), 1u);
|
||||
EXPECT_EQ(stmt->selectors[0]->ValueAsU32(), 1u);
|
||||
EXPECT_EQ(stmt->selectors[0]->value, 1);
|
||||
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_EQ(e->body->statements.size(), 1u);
|
||||
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||
}
|
||||
|
@ -60,8 +62,9 @@ TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma) {
|
|||
EXPECT_FALSE(e->IsDefault());
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.size(), 2u);
|
||||
EXPECT_EQ(stmt->selectors[0]->ValueAsU32(), 1u);
|
||||
EXPECT_EQ(stmt->selectors[1]->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(stmt->selectors[0]->value, 1);
|
||||
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
EXPECT_EQ(stmt->selectors[1]->value, 2);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma_WithColon) {
|
||||
|
@ -75,8 +78,9 @@ TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma_WithColon) {
|
|||
EXPECT_FALSE(e->IsDefault());
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.size(), 2u);
|
||||
EXPECT_EQ(stmt->selectors[0]->ValueAsU32(), 1u);
|
||||
EXPECT_EQ(stmt->selectors[1]->ValueAsU32(), 2u);
|
||||
EXPECT_EQ(stmt->selectors[0]->value, 1);
|
||||
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
EXPECT_EQ(stmt->selectors[1]->value, 2);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_InvalidConstLiteral) {
|
||||
|
@ -160,8 +164,10 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
|
|||
EXPECT_FALSE(e->IsDefault());
|
||||
ASSERT_EQ(e->body->statements.size(), 0u);
|
||||
ASSERT_EQ(e->selectors.size(), 2u);
|
||||
ASSERT_EQ(e->selectors[0]->ValueAsI32(), 1);
|
||||
ASSERT_EQ(e->selectors[1]->ValueAsI32(), 2);
|
||||
ASSERT_EQ(e->selectors[0]->value, 1);
|
||||
EXPECT_EQ(e->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_EQ(e->selectors[1]->value, 2);
|
||||
EXPECT_EQ(e->selectors[1]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_WithColon) {
|
||||
|
@ -175,8 +181,10 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_WithColon) {
|
|||
EXPECT_FALSE(e->IsDefault());
|
||||
ASSERT_EQ(e->body->statements.size(), 0u);
|
||||
ASSERT_EQ(e->selectors.size(), 2u);
|
||||
ASSERT_EQ(e->selectors[0]->ValueAsI32(), 1);
|
||||
ASSERT_EQ(e->selectors[1]->ValueAsI32(), 2);
|
||||
ASSERT_EQ(e->selectors[0]->value, 1);
|
||||
EXPECT_EQ(e->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_EQ(e->selectors[1]->value, 2);
|
||||
EXPECT_EQ(e->selectors[1]->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
|
||||
|
|
|
@ -376,7 +376,7 @@ TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
|
|||
ASSERT_EQ(p->error(), "1:8: invalid type for atomic declaration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_SintLiteralSize) {
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_AbstractIntLiteralSize) {
|
||||
auto p = parser("array<f32, 5>");
|
||||
auto t = p->type_decl();
|
||||
EXPECT_TRUE(t.matched);
|
||||
|
@ -391,9 +391,31 @@ TEST_F(ParserImplTest, TypeDecl_Array_SintLiteralSize) {
|
|||
EXPECT_EQ(a->attributes.size(), 0u);
|
||||
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 14u}}));
|
||||
|
||||
auto* size = a->count->As<ast::SintLiteralExpression>();
|
||||
auto* size = a->count->As<ast::IntLiteralExpression>();
|
||||
ASSERT_NE(size, nullptr);
|
||||
EXPECT_EQ(size->ValueAsI32(), 5);
|
||||
EXPECT_EQ(size->value, 5);
|
||||
EXPECT_EQ(size->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_SintLiteralSize) {
|
||||
auto p = parser("array<f32, 5i>");
|
||||
auto t = p->type_decl();
|
||||
EXPECT_TRUE(t.matched);
|
||||
EXPECT_FALSE(t.errored);
|
||||
ASSERT_NE(t.value, nullptr) << p->error();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_TRUE(t.value->Is<ast::Array>());
|
||||
|
||||
auto* a = t.value->As<ast::Array>();
|
||||
ASSERT_FALSE(a->IsRuntimeArray());
|
||||
ASSERT_TRUE(a->type->Is<ast::F32>());
|
||||
EXPECT_EQ(a->attributes.size(), 0u);
|
||||
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 15u}}));
|
||||
|
||||
auto* size = a->count->As<ast::IntLiteralExpression>();
|
||||
ASSERT_NE(size, nullptr);
|
||||
EXPECT_EQ(size->value, 5);
|
||||
EXPECT_EQ(size->suffix, ast::IntLiteralExpression::Suffix::kI);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_UintLiteralSize) {
|
||||
|
@ -411,9 +433,9 @@ TEST_F(ParserImplTest, TypeDecl_Array_UintLiteralSize) {
|
|||
EXPECT_EQ(a->attributes.size(), 0u);
|
||||
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 15u}}));
|
||||
|
||||
auto* size = a->count->As<ast::UintLiteralExpression>();
|
||||
auto* size = a->count->As<ast::IntLiteralExpression>();
|
||||
ASSERT_NE(size, nullptr);
|
||||
EXPECT_EQ(size->ValueAsU32(), 5u);
|
||||
EXPECT_EQ(size->suffix, ast::IntLiteralExpression::Suffix::kU);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_ConstantSize) {
|
||||
|
|
|
@ -32,8 +32,10 @@ TEST_F(ParserImplTest, UnaryExpression_Postix) {
|
|||
auto* ident = idx->object->As<ast::IdentifierExpression>();
|
||||
EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
|
||||
|
||||
ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
|
||||
ASSERT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
|
||||
ASSERT_TRUE(idx->index->Is<ast::IntLiteralExpression>());
|
||||
ASSERT_EQ(idx->index->As<ast::IntLiteralExpression>()->value, 2);
|
||||
ASSERT_EQ(idx->index->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_Minus) {
|
||||
|
@ -48,8 +50,10 @@ TEST_F(ParserImplTest, UnaryExpression_Minus) {
|
|||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
ASSERT_EQ(u->op, ast::UnaryOp::kNegation);
|
||||
|
||||
ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
|
||||
ASSERT_TRUE(u->expr->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(u->expr->As<ast::IntLiteralExpression>()->value, 1);
|
||||
ASSERT_EQ(u->expr->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_AddressOf) {
|
||||
|
@ -130,8 +134,10 @@ TEST_F(ParserImplTest, UnaryExpression_Bang) {
|
|||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
ASSERT_EQ(u->op, ast::UnaryOp::kNot);
|
||||
|
||||
ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
|
||||
ASSERT_TRUE(u->expr->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(u->expr->As<ast::IntLiteralExpression>()->value, 1);
|
||||
ASSERT_EQ(u->expr->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_Bang_InvalidRHS) {
|
||||
|
@ -156,8 +162,10 @@ TEST_F(ParserImplTest, UnaryExpression_Tilde) {
|
|||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
ASSERT_EQ(u->op, ast::UnaryOp::kComplement);
|
||||
|
||||
ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
|
||||
EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
|
||||
ASSERT_TRUE(u->expr->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(u->expr->As<ast::IntLiteralExpression>()->value, 1);
|
||||
ASSERT_EQ(u->expr->As<ast::IntLiteralExpression>()->suffix,
|
||||
ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_PrefixPlusPlus) {
|
||||
|
|
|
@ -859,7 +859,9 @@ sem::CaseStatement* Resolver::CaseStatement(const ast::CaseStatement* stmt) {
|
|||
builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
|
||||
return StatementScope(stmt, sem, [&] {
|
||||
for (auto* sel : stmt->selectors) {
|
||||
Mark(sel);
|
||||
if (!Expression(sel)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Mark(stmt->body);
|
||||
auto* body = BlockStatement(stmt->body);
|
||||
|
@ -1525,8 +1527,27 @@ sem::Call* Resolver::TypeConstructor(const ast::CallExpression* expr,
|
|||
}
|
||||
|
||||
sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
||||
auto* ty = sem_.TypeOf(literal);
|
||||
if (!ty) {
|
||||
auto* ty = Switch(
|
||||
literal,
|
||||
[&](const ast::IntLiteralExpression* i) -> sem::Type* {
|
||||
switch (i->suffix) {
|
||||
case ast::IntLiteralExpression::Suffix::kNone:
|
||||
// TODO(crbug.com/tint/1504): This will need to become abstract-int.
|
||||
// For now, treat as 'i32'.
|
||||
case ast::IntLiteralExpression::Suffix::kI:
|
||||
return builder_->create<sem::I32>();
|
||||
case ast::IntLiteralExpression::Suffix::kU:
|
||||
return builder_->create<sem::U32>();
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression*) { return builder_->create<sem::F32>(); },
|
||||
[&](const ast::BoolLiteralExpression*) { return builder_->create<sem::Bool>(); },
|
||||
[&](Default) { return nullptr; });
|
||||
|
||||
if (ty == nullptr) {
|
||||
TINT_UNREACHABLE(Resolver, builder_->Diagnostics())
|
||||
<< "Unhandled literal type: " << literal->TypeInfo().name;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,20 +39,20 @@ sem::Constant Resolver::EvaluateConstantValue(const ast::Expression* expr, const
|
|||
|
||||
sem::Constant Resolver::EvaluateConstantValue(const ast::LiteralExpression* literal,
|
||||
const sem::Type* type) {
|
||||
if (auto* lit = literal->As<ast::SintLiteralExpression>()) {
|
||||
return {type, {lit->ValueAsI32()}};
|
||||
return Switch(
|
||||
literal,
|
||||
[&](const ast::IntLiteralExpression* lit) {
|
||||
if (lit->suffix == ast::IntLiteralExpression::Suffix::kU) {
|
||||
return sem::Constant{type, {static_cast<uint32_t>(lit->value)}};
|
||||
}
|
||||
if (auto* lit = literal->As<ast::UintLiteralExpression>()) {
|
||||
return {type, {lit->ValueAsU32()}};
|
||||
}
|
||||
if (auto* lit = literal->As<ast::FloatLiteralExpression>()) {
|
||||
return {type, {lit->value}};
|
||||
}
|
||||
if (auto* lit = literal->As<ast::BoolLiteralExpression>()) {
|
||||
return {type, {lit->value}};
|
||||
}
|
||||
TINT_UNREACHABLE(Resolver, builder_->Diagnostics());
|
||||
return {};
|
||||
return sem::Constant{type, {static_cast<int32_t>(lit->value)}};
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression* lit) {
|
||||
return sem::Constant{type, {lit->value}};
|
||||
},
|
||||
[&](const ast::BoolLiteralExpression* lit) {
|
||||
return sem::Constant{type, {lit->value}};
|
||||
});
|
||||
}
|
||||
|
||||
sem::Constant Resolver::EvaluateConstantValue(const ast::CallExpression* call,
|
||||
|
|
|
@ -113,7 +113,7 @@ TEST_F(ResolverTest, Stmt_Case) {
|
|||
auto* assign = Assign(lhs, rhs);
|
||||
auto* block = Block(assign);
|
||||
ast::CaseSelectorList lit;
|
||||
lit.push_back(create<ast::SintLiteralExpression>(3));
|
||||
lit.push_back(Expr(3));
|
||||
auto* cse = create<ast::CaseStatement>(lit, block);
|
||||
auto* cond_var = Var("c", ty.i32());
|
||||
auto* sw = Switch(cond_var, cse, DefaultCase());
|
||||
|
@ -1922,8 +1922,8 @@ TEST_F(ResolverTest, ASTNodeNotReached) {
|
|||
b.Expr("expr");
|
||||
Resolver(&b).Resolve();
|
||||
},
|
||||
"internal compiler error: AST node 'tint::ast::IdentifierExpression' was "
|
||||
"not reached by the resolver");
|
||||
"internal compiler error: AST node 'tint::ast::IdentifierExpression' was not reached by "
|
||||
"the resolver");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, ASTNodeReachedTwice) {
|
||||
|
@ -1935,8 +1935,8 @@ TEST_F(ResolverTest, ASTNodeReachedTwice) {
|
|||
b.Global("b", b.ty.i32(), ast::StorageClass::kPrivate, expr);
|
||||
Resolver(&b).Resolve();
|
||||
},
|
||||
"internal compiler error: AST node 'tint::ast::SintLiteralExpression' "
|
||||
"was encountered twice in the same AST of a Program");
|
||||
"internal compiler error: AST node 'tint::ast::IntLiteralExpression' was encountered twice "
|
||||
"in the same AST of a Program");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, UnaryOp_Not) {
|
||||
|
|
|
@ -36,17 +36,4 @@ sem::Type* SemHelper::TypeOf(const ast::Expression* expr) const {
|
|||
return sem ? const_cast<sem::Type*>(sem->Type()) : nullptr;
|
||||
}
|
||||
|
||||
sem::Type* SemHelper::TypeOf(const ast::LiteralExpression* lit) {
|
||||
return Switch(
|
||||
lit, [&](const ast::SintLiteralExpression*) { return builder_->create<sem::I32>(); },
|
||||
[&](const ast::UintLiteralExpression*) { return builder_->create<sem::U32>(); },
|
||||
[&](const ast::FloatLiteralExpression*) { return builder_->create<sem::F32>(); },
|
||||
[&](const ast::BoolLiteralExpression*) { return builder_->create<sem::Bool>(); },
|
||||
[&](Default) {
|
||||
TINT_UNREACHABLE(Resolver, builder_->Diagnostics())
|
||||
<< "Unhandled literal type: " << lit->TypeInfo().name;
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace tint::resolver
|
||||
|
|
|
@ -62,10 +62,6 @@ class SemHelper {
|
|||
/// @param expr the expression
|
||||
sem::Type* TypeOf(const ast::Expression* expr) const;
|
||||
|
||||
/// @returns the semantic type of the AST literal `lit`
|
||||
/// @param lit the literal
|
||||
sem::Type* TypeOf(const ast::LiteralExpression* lit);
|
||||
|
||||
/// @returns the type name of the given semantic type, unwrapping
|
||||
/// references.
|
||||
/// @param ty the type to look up
|
||||
|
|
|
@ -2178,7 +2178,7 @@ bool Validator::SwitchStatement(const ast::SwitchStatement* s) {
|
|||
}
|
||||
|
||||
bool has_default = false;
|
||||
std::unordered_map<uint32_t, Source> selectors;
|
||||
std::unordered_map<int64_t, Source> selectors;
|
||||
|
||||
for (auto* case_stmt : s->body) {
|
||||
if (case_stmt->IsDefault()) {
|
||||
|
@ -2200,17 +2200,14 @@ bool Validator::SwitchStatement(const ast::SwitchStatement* s) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto v = selector->ValueAsU32();
|
||||
auto it = selectors.find(v);
|
||||
auto it = selectors.find(selector->value);
|
||||
if (it != selectors.end()) {
|
||||
auto val = selector->Is<ast::IntLiteralExpression>()
|
||||
? std::to_string(selector->ValueAsI32())
|
||||
: std::to_string(selector->ValueAsU32());
|
||||
auto val = std::to_string(selector->value);
|
||||
AddError("duplicate switch case '" + val + "'", selector->source);
|
||||
AddNote("previous case declared here", it->second);
|
||||
return false;
|
||||
}
|
||||
selectors.emplace(v, selector->source);
|
||||
selectors.emplace(selector->value, selector->source);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -320,11 +320,9 @@ struct DecomposeMemoryAccess::State {
|
|||
/// @param expr the expression to convert to an Offset
|
||||
/// @returns an Offset for the given ast::Expression
|
||||
const Offset* ToOffset(const ast::Expression* expr) {
|
||||
if (auto* u32 = expr->As<ast::UintLiteralExpression>()) {
|
||||
return offsets_.Create<OffsetLiteral>(u32->value);
|
||||
} else if (auto* i32 = expr->As<ast::SintLiteralExpression>()) {
|
||||
if (i32->value > 0) {
|
||||
return offsets_.Create<OffsetLiteral>(i32->value);
|
||||
if (auto* lit = expr->As<ast::IntLiteralExpression>()) {
|
||||
if (lit->value > 0) {
|
||||
return offsets_.Create<OffsetLiteral>(static_cast<uint32_t>(lit->value));
|
||||
}
|
||||
}
|
||||
return offsets_.Create<OffsetExpr>(expr);
|
||||
|
|
|
@ -73,7 +73,7 @@ TEST_F(CreateASTTypeForTest, ArrayImplicitStride) {
|
|||
|
||||
auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteralExpression>();
|
||||
ASSERT_NE(size, nullptr);
|
||||
EXPECT_EQ(size->ValueAsI32(), 2);
|
||||
EXPECT_EQ(size->value, 2);
|
||||
}
|
||||
|
||||
TEST_F(CreateASTTypeForTest, ArrayNonImplicitStride) {
|
||||
|
@ -88,7 +88,7 @@ TEST_F(CreateASTTypeForTest, ArrayNonImplicitStride) {
|
|||
|
||||
auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteralExpression>();
|
||||
ASSERT_NE(size, nullptr);
|
||||
EXPECT_EQ(size->ValueAsI32(), 2);
|
||||
EXPECT_EQ(size->value, 2);
|
||||
}
|
||||
|
||||
TEST_F(CreateASTTypeForTest, Struct) {
|
||||
|
|
|
@ -453,7 +453,7 @@ TEST_F(AppendVectorTest, ZeroVec3i32_i32) {
|
|||
ASSERT_NE(vec_0004, nullptr);
|
||||
ASSERT_EQ(vec_0004->args.size(), 4u);
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
auto* literal = As<ast::SintLiteralExpression>(vec_0004->args[i]);
|
||||
auto* literal = As<ast::IntLiteralExpression>(vec_0004->args[i]);
|
||||
ASSERT_NE(literal, nullptr);
|
||||
EXPECT_EQ(literal->value, 0);
|
||||
}
|
||||
|
|
|
@ -2164,26 +2164,34 @@ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) {
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit) {
|
||||
if (auto* l = lit->As<ast::BoolLiteralExpression>()) {
|
||||
return Switch(
|
||||
lit,
|
||||
[&](const ast::BoolLiteralExpression* l) {
|
||||
out << (l->value ? "true" : "false");
|
||||
} else if (auto* fl = lit->As<ast::FloatLiteralExpression>()) {
|
||||
if (std::isinf(fl->value)) {
|
||||
out << (fl->value >= 0 ? "uintBitsToFloat(0x7f800000u)"
|
||||
return true;
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression* l) {
|
||||
if (std::isinf(l->value)) {
|
||||
out << (l->value >= 0 ? "uintBitsToFloat(0x7f800000u)"
|
||||
: "uintBitsToFloat(0xff800000u)");
|
||||
} else if (std::isnan(fl->value)) {
|
||||
} else if (std::isnan(l->value)) {
|
||||
out << "uintBitsToFloat(0x7fc00000u)";
|
||||
} else {
|
||||
out << FloatToString(fl->value) << "f";
|
||||
}
|
||||
} else if (auto* sl = lit->As<ast::SintLiteralExpression>()) {
|
||||
out << sl->value;
|
||||
} else if (auto* ul = lit->As<ast::UintLiteralExpression>()) {
|
||||
out << ul->value << "u";
|
||||
} else {
|
||||
diagnostics_.add_error(diag::System::Writer, "unknown literal type");
|
||||
return false;
|
||||
out << FloatToString(l->value) << "f";
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[&](const ast::IntLiteralExpression* l) {
|
||||
out << l->value;
|
||||
if (l->suffix == ast::IntLiteralExpression::Suffix::kU) {
|
||||
out << "u";
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[&](Default) {
|
||||
diagnostics_.add_error(diag::System::Writer, "unknown literal type");
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitZeroValue(std::ostream& out, const sem::Type* type) {
|
||||
|
|
|
@ -3042,13 +3042,18 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression*
|
|||
}
|
||||
return true;
|
||||
},
|
||||
[&](const ast::SintLiteralExpression* sl) {
|
||||
out << sl->value;
|
||||
[&](const ast::IntLiteralExpression* i) {
|
||||
out << i->value;
|
||||
switch (i->suffix) {
|
||||
case ast::IntLiteralExpression::Suffix::kNone:
|
||||
case ast::IntLiteralExpression::Suffix::kI:
|
||||
return true;
|
||||
},
|
||||
[&](const ast::UintLiteralExpression* ul) {
|
||||
out << ul->value << "u";
|
||||
case ast::IntLiteralExpression::Suffix::kU:
|
||||
out << "u";
|
||||
return true;
|
||||
}
|
||||
diagnostics_.add_error(diag::System::Writer, "unknown integer literal suffix type");
|
||||
return false;
|
||||
},
|
||||
[&](Default) {
|
||||
diagnostics_.add_error(diag::System::Writer, "unknown literal type");
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "src/tint/ast/id_attribute.h"
|
||||
#include "src/tint/ast/interpolate_attribute.h"
|
||||
#include "src/tint/ast/module.h"
|
||||
#include "src/tint/ast/sint_literal_expression.h"
|
||||
#include "src/tint/ast/uint_literal_expression.h"
|
||||
#include "src/tint/ast/variable_decl_statement.h"
|
||||
#include "src/tint/ast/void.h"
|
||||
#include "src/tint/sem/array.h"
|
||||
|
@ -1523,7 +1521,10 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression*
|
|||
}
|
||||
return true;
|
||||
},
|
||||
[&](const ast::SintLiteralExpression* l) {
|
||||
[&](const ast::IntLiteralExpression* i) {
|
||||
switch (i->suffix) {
|
||||
case ast::IntLiteralExpression::Suffix::kNone:
|
||||
case ast::IntLiteralExpression::Suffix::kI: {
|
||||
// MSL (and C++) parse `-2147483648` as a `long` because it parses
|
||||
// unary minus and `2147483648` as separate tokens, and the latter
|
||||
// doesn't fit into an (32-bit) `int`. WGSL, OTOH, parses this as an
|
||||
|
@ -1531,16 +1532,20 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression*
|
|||
// `(2147483647 - 1)` instead, which ensures the expression type is
|
||||
// `int`.
|
||||
const auto int_min = std::numeric_limits<int32_t>::min();
|
||||
if (l->ValueAsI32() == int_min) {
|
||||
if (i->value == int_min) {
|
||||
out << "(" << int_min + 1 << " - 1)";
|
||||
} else {
|
||||
out << l->value;
|
||||
out << i->value;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[&](const ast::UintLiteralExpression* l) {
|
||||
out << l->value << "u";
|
||||
}
|
||||
case ast::IntLiteralExpression::Suffix::kU: {
|
||||
out << i->value << "u";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diagnostics_.add_error(diag::System::Writer, "unknown integer literal suffix type");
|
||||
return false;
|
||||
},
|
||||
[&](Default) {
|
||||
diagnostics_.add_error(diag::System::Writer, "unknown literal type");
|
||||
|
|
|
@ -743,22 +743,30 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* var) {
|
|||
}
|
||||
|
||||
// SPIR-V requires specialization constants to have initializers.
|
||||
if (type->Is<sem::F32>()) {
|
||||
ast::FloatLiteralExpression l(ProgramID(), Source{}, 0.0f);
|
||||
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||
} else if (type->Is<sem::U32>()) {
|
||||
ast::UintLiteralExpression l(ProgramID(), Source{}, 0);
|
||||
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||
} else if (type->Is<sem::I32>()) {
|
||||
ast::SintLiteralExpression l(ProgramID(), Source{}, 0);
|
||||
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||
} else if (type->Is<sem::Bool>()) {
|
||||
ast::BoolLiteralExpression l(ProgramID(), Source{}, false);
|
||||
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||
} else {
|
||||
init_id = Switch(
|
||||
type, //
|
||||
[&](const sem::F32*) {
|
||||
ast::FloatLiteralExpression l(ProgramID{}, Source{}, 0.0f);
|
||||
return GenerateLiteralIfNeeded(var, &l);
|
||||
},
|
||||
[&](const sem::U32*) {
|
||||
ast::IntLiteralExpression l(ProgramID{}, Source{}, 0,
|
||||
ast::IntLiteralExpression::Suffix::kU);
|
||||
return GenerateLiteralIfNeeded(var, &l);
|
||||
},
|
||||
[&](const sem::I32*) {
|
||||
ast::IntLiteralExpression l(ProgramID{}, Source{}, 0,
|
||||
ast::IntLiteralExpression::Suffix::kI);
|
||||
return GenerateLiteralIfNeeded(var, &l);
|
||||
},
|
||||
[&](const sem::Bool*) {
|
||||
ast::BoolLiteralExpression l(ProgramID{}, Source{}, false);
|
||||
return GenerateLiteralIfNeeded(var, &l);
|
||||
},
|
||||
[&](Default) {
|
||||
error_ = "invalid type for pipeline constant ID, must be scalar";
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
if (init_id == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1537,28 +1545,22 @@ uint32_t Builder::GenerateCastOrCopyOrPassthrough(const sem::Type* to_type,
|
|||
uint32_t one_id;
|
||||
uint32_t zero_id;
|
||||
if (to_elem_type->Is<sem::F32>()) {
|
||||
ast::FloatLiteralExpression one(ProgramID(), Source{}, 1.0f);
|
||||
ast::FloatLiteralExpression zero(ProgramID(), Source{}, 0.0f);
|
||||
one_id = GenerateLiteralIfNeeded(nullptr, &one);
|
||||
zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
|
||||
zero_id = GenerateConstantIfNeeded(ScalarConstant::F32(0));
|
||||
one_id = GenerateConstantIfNeeded(ScalarConstant::F32(1));
|
||||
} else if (to_elem_type->Is<sem::U32>()) {
|
||||
ast::UintLiteralExpression one(ProgramID(), Source{}, 1);
|
||||
ast::UintLiteralExpression zero(ProgramID(), Source{}, 0);
|
||||
one_id = GenerateLiteralIfNeeded(nullptr, &one);
|
||||
zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
|
||||
zero_id = GenerateConstantIfNeeded(ScalarConstant::U32(0));
|
||||
one_id = GenerateConstantIfNeeded(ScalarConstant::U32(1));
|
||||
} else if (to_elem_type->Is<sem::I32>()) {
|
||||
ast::SintLiteralExpression one(ProgramID(), Source{}, 1);
|
||||
ast::SintLiteralExpression zero(ProgramID(), Source{}, 0);
|
||||
one_id = GenerateLiteralIfNeeded(nullptr, &one);
|
||||
zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
|
||||
zero_id = GenerateConstantIfNeeded(ScalarConstant::I32(0));
|
||||
one_id = GenerateConstantIfNeeded(ScalarConstant::I32(1));
|
||||
} else {
|
||||
error_ = "invalid destination type for bool conversion";
|
||||
return false;
|
||||
}
|
||||
if (auto* to_vec = to_type->As<sem::Vector>()) {
|
||||
// Splat the scalars into vectors.
|
||||
one_id = GenerateConstantVectorSplatIfNeeded(to_vec, one_id);
|
||||
zero_id = GenerateConstantVectorSplatIfNeeded(to_vec, zero_id);
|
||||
one_id = GenerateConstantVectorSplatIfNeeded(to_vec, one_id);
|
||||
}
|
||||
if (!one_id || !zero_id) {
|
||||
return false;
|
||||
|
@ -1605,17 +1607,22 @@ uint32_t Builder::GenerateLiteralIfNeeded(const ast::Variable* var,
|
|||
constant.kind = ScalarConstant::Kind::kBool;
|
||||
constant.value.b = l->value;
|
||||
},
|
||||
[&](const ast::SintLiteralExpression* sl) {
|
||||
[&](const ast::IntLiteralExpression* i) {
|
||||
switch (i->suffix) {
|
||||
case ast::IntLiteralExpression::Suffix::kNone:
|
||||
case ast::IntLiteralExpression::Suffix::kI:
|
||||
constant.kind = ScalarConstant::Kind::kI32;
|
||||
constant.value.i32 = sl->value;
|
||||
},
|
||||
[&](const ast::UintLiteralExpression* ul) {
|
||||
constant.value.i32 = static_cast<int32_t>(i->value);
|
||||
return;
|
||||
case ast::IntLiteralExpression::Suffix::kU:
|
||||
constant.kind = ScalarConstant::Kind::kU32;
|
||||
constant.value.u32 = ul->value;
|
||||
constant.value.u32 = static_cast<uint32_t>(i->value);
|
||||
return;
|
||||
}
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression* fl) {
|
||||
[&](const ast::FloatLiteralExpression* f) {
|
||||
constant.kind = ScalarConstant::Kind::kF32;
|
||||
constant.value.f32 = fl->value;
|
||||
constant.value.f32 = f->value;
|
||||
},
|
||||
[&](Default) { error_ = "unknown literal type"; });
|
||||
|
||||
|
@ -2699,9 +2706,9 @@ bool Builder::GenerateTextureBuiltin(const sem::Call* call,
|
|||
op = spv::Op::OpImageQuerySizeLod;
|
||||
spirv_params.emplace_back(gen(level));
|
||||
} else {
|
||||
ast::SintLiteralExpression i32_0(ProgramID(), Source{}, 0);
|
||||
op = spv::Op::OpImageQuerySizeLod;
|
||||
spirv_params.emplace_back(Operand(GenerateLiteralIfNeeded(nullptr, &i32_0)));
|
||||
spirv_params.emplace_back(
|
||||
Operand(GenerateConstantIfNeeded(ScalarConstant::I32(0))));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2729,9 +2736,9 @@ bool Builder::GenerateTextureBuiltin(const sem::Call* call,
|
|||
texture_type->Is<sem::StorageTexture>()) {
|
||||
op = spv::Op::OpImageQuerySize;
|
||||
} else {
|
||||
ast::SintLiteralExpression i32_0(ProgramID(), Source{}, 0);
|
||||
op = spv::Op::OpImageQuerySizeLod;
|
||||
spirv_params.emplace_back(Operand(GenerateLiteralIfNeeded(nullptr, &i32_0)));
|
||||
spirv_params.emplace_back(
|
||||
Operand(GenerateConstantIfNeeded(ScalarConstant::I32(0))));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3401,7 +3408,7 @@ bool Builder::GenerateSwitchStatement(const ast::SwitchStatement* stmt) {
|
|||
return false;
|
||||
}
|
||||
|
||||
params.push_back(Operand(int_literal->ValueAsU32()));
|
||||
params.push_back(Operand(static_cast<uint32_t>(int_literal->value)));
|
||||
params.push_back(Operand(block_id));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ TEST_F(BuilderTest, Literal_Bool_Dedup) {
|
|||
}
|
||||
|
||||
TEST_F(BuilderTest, Literal_I32) {
|
||||
auto* i = create<ast::SintLiteralExpression>(-23);
|
||||
auto* i = Expr(-23);
|
||||
WrapInFunction(i);
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
@ -84,8 +84,8 @@ TEST_F(BuilderTest, Literal_I32) {
|
|||
}
|
||||
|
||||
TEST_F(BuilderTest, Literal_I32_Dedup) {
|
||||
auto* i1 = create<ast::SintLiteralExpression>(-23);
|
||||
auto* i2 = create<ast::SintLiteralExpression>(-23);
|
||||
auto* i1 = Expr(-23);
|
||||
auto* i2 = Expr(-23);
|
||||
WrapInFunction(i1, i2);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
@ -100,7 +100,7 @@ TEST_F(BuilderTest, Literal_I32_Dedup) {
|
|||
}
|
||||
|
||||
TEST_F(BuilderTest, Literal_U32) {
|
||||
auto* i = create<ast::UintLiteralExpression>(23);
|
||||
auto* i = Expr(23u);
|
||||
WrapInFunction(i);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
@ -115,8 +115,8 @@ TEST_F(BuilderTest, Literal_U32) {
|
|||
}
|
||||
|
||||
TEST_F(BuilderTest, Literal_U32_Dedup) {
|
||||
auto* i1 = create<ast::UintLiteralExpression>(23);
|
||||
auto* i2 = create<ast::UintLiteralExpression>(23);
|
||||
auto* i1 = Expr(23u);
|
||||
auto* i2 = Expr(23u);
|
||||
WrapInFunction(i1, i2);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "src/tint/ast/multisampled_texture.h"
|
||||
#include "src/tint/ast/pointer.h"
|
||||
#include "src/tint/ast/sampled_texture.h"
|
||||
#include "src/tint/ast/sint_literal_expression.h"
|
||||
#include "src/tint/ast/stage_attribute.h"
|
||||
#include "src/tint/ast/storage_texture.h"
|
||||
#include "src/tint/ast/stride_attribute.h"
|
||||
|
@ -46,7 +45,6 @@
|
|||
#include "src/tint/ast/struct_member_size_attribute.h"
|
||||
#include "src/tint/ast/type_name.h"
|
||||
#include "src/tint/ast/u32.h"
|
||||
#include "src/tint/ast/uint_literal_expression.h"
|
||||
#include "src/tint/ast/variable_decl_statement.h"
|
||||
#include "src/tint/ast/vector.h"
|
||||
#include "src/tint/ast/void.h"
|
||||
|
@ -259,20 +257,16 @@ bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr)
|
|||
bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit) {
|
||||
return Switch(
|
||||
lit,
|
||||
[&](const ast::BoolLiteralExpression* bl) { //
|
||||
out << (bl->value ? "true" : "false");
|
||||
[&](const ast::BoolLiteralExpression* l) { //
|
||||
out << (l->value ? "true" : "false");
|
||||
return true;
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression* fl) { //
|
||||
out << FloatToBitPreservingString(fl->value);
|
||||
[&](const ast::FloatLiteralExpression* l) { //
|
||||
out << FloatToBitPreservingString(l->value);
|
||||
return true;
|
||||
},
|
||||
[&](const ast::SintLiteralExpression* sl) { //
|
||||
out << sl->value;
|
||||
return true;
|
||||
},
|
||||
[&](const ast::UintLiteralExpression* ul) { //
|
||||
out << ul->value << "u";
|
||||
[&](const ast::IntLiteralExpression* l) { //
|
||||
out << l->value << l->suffix;
|
||||
return true;
|
||||
},
|
||||
[&](Default) { //
|
||||
|
|
|
@ -192,7 +192,6 @@ tint_unittests_source_set("tint_unittests_ast_src") {
|
|||
"../../src/tint/ast/return_statement_test.cc",
|
||||
"../../src/tint/ast/sampled_texture_test.cc",
|
||||
"../../src/tint/ast/sampler_test.cc",
|
||||
"../../src/tint/ast/sint_literal_expression_test.cc",
|
||||
"../../src/tint/ast/stage_attribute_test.cc",
|
||||
"../../src/tint/ast/storage_texture_test.cc",
|
||||
"../../src/tint/ast/stride_attribute_test.cc",
|
||||
|
@ -206,7 +205,6 @@ tint_unittests_source_set("tint_unittests_ast_src") {
|
|||
"../../src/tint/ast/texture_test.cc",
|
||||
"../../src/tint/ast/traverse_expressions_test.cc",
|
||||
"../../src/tint/ast/u32_test.cc",
|
||||
"../../src/tint/ast/uint_literal_expression_test.cc",
|
||||
"../../src/tint/ast/unary_op_expression_test.cc",
|
||||
"../../src/tint/ast/variable_decl_statement_test.cc",
|
||||
"../../src/tint/ast/variable_test.cc",
|
||||
|
|
Loading…
Reference in New Issue