Convert CaseStatement to use BlockStatement.

This CL converts the CaseStatement class to using a BlockStatement
internally. All usages have been updated execept for the two readers.

Bug: tint:130
Change-Id: Idb9114230f7d9eb0f2208af635316edb0a0e8f99
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/25721
Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
This commit is contained in:
dan sinclair 2020-07-27 15:25:00 +00:00 committed by Sarah Mashayekhi
parent 4069f3357d
commit 7c2fa1e7bc
21 changed files with 200 additions and 171 deletions

View File

@ -42,13 +42,20 @@ class BlockStatement : public Statement {
statements_.push_back(std::move(stmt));
}
/// @returns true if the block is empty
bool empty() const { return statements_.empty(); }
/// @returns the number of statements directly in the block
size_t size() const { return statements_.size(); }
/// @returns the last statement in the block or nullptr if block empty
const ast::Statement* last() const {
return statements_.empty() ? nullptr : statements_.back().get();
}
/// Retrieves the statement at |idx|
/// @param idx the index. The index is not bounds checked.
/// @returns the statement at |idx|
ast::Statement* get(size_t idx) { return statements_[idx].get(); }
const ast::Statement* get(size_t idx) const { return statements_[idx].get(); }
/// Retrieves the statement at |idx|
/// @param idx the index. The index is not bounds checked.

View File

@ -17,17 +17,19 @@
namespace tint {
namespace ast {
CaseStatement::CaseStatement() : Statement() {}
CaseStatement::CaseStatement()
: Statement(), body_(std::make_unique<BlockStatement>()) {}
CaseStatement::CaseStatement(StatementList body)
CaseStatement::CaseStatement(std::unique_ptr<BlockStatement> body)
: Statement(), body_(std::move(body)) {}
CaseStatement::CaseStatement(CaseSelectorList selectors, StatementList body)
CaseStatement::CaseStatement(CaseSelectorList selectors,
std::unique_ptr<BlockStatement> body)
: Statement(), selectors_(std::move(selectors)), body_(std::move(body)) {}
CaseStatement::CaseStatement(const Source& source,
CaseSelectorList selectors,
StatementList body)
std::unique_ptr<BlockStatement> body)
: Statement(source),
selectors_(std::move(selectors)),
body_(std::move(body)) {}
@ -36,16 +38,18 @@ CaseStatement::CaseStatement(CaseStatement&&) = default;
CaseStatement::~CaseStatement() = default;
void CaseStatement::set_body(StatementList body) {
for (auto& stmt : body) {
body_->append(std::move(stmt));
}
}
bool CaseStatement::IsCase() const {
return true;
}
bool CaseStatement::IsValid() const {
for (const auto& stmt : body_) {
if (stmt == nullptr || !stmt->IsValid())
return false;
}
return true;
return body_ != nullptr && body_->IsValid();
}
void CaseStatement::to_str(std::ostream& out, size_t indent) const {
@ -66,8 +70,11 @@ void CaseStatement::to_str(std::ostream& out, size_t indent) const {
out << "{" << std::endl;
}
for (const auto& stmt : body_)
stmt->to_str(out, indent + 2);
if (body_ != nullptr) {
for (const auto& stmt : *body_) {
stmt->to_str(out, indent + 2);
}
}
make_indent(out, indent);
out << "}" << std::endl;

View File

@ -19,6 +19,7 @@
#include <utility>
#include <vector>
#include "src/ast/block_statement.h"
#include "src/ast/expression.h"
#include "src/ast/int_literal.h"
#include "src/ast/statement.h"
@ -37,18 +38,19 @@ class CaseStatement : public Statement {
/// Constructor
/// Creates a default case statement
/// @param body the case body
explicit CaseStatement(StatementList body);
explicit CaseStatement(std::unique_ptr<BlockStatement> body);
/// Constructor
/// @param selectors the case selectors
/// @param body the case body
CaseStatement(CaseSelectorList selectors, StatementList body);
CaseStatement(CaseSelectorList selectors,
std::unique_ptr<BlockStatement> body);
/// Constructor
/// @param source the source information
/// @param selectors the case selectors
/// @param body the case body
CaseStatement(const Source& source,
CaseSelectorList selectors,
StatementList body);
std::unique_ptr<BlockStatement> body);
/// Move constructor
CaseStatement(CaseStatement&&);
~CaseStatement() override;
@ -65,9 +67,14 @@ class CaseStatement : public Statement {
/// Sets the case body
/// @param body the case body
void set_body(StatementList body) { body_ = std::move(body); }
void set_body(StatementList body);
/// Sets the case body
/// @param body the case body
void set_body(std::unique_ptr<BlockStatement> body) {
body_ = std::move(body);
}
/// @returns the case body
const StatementList& body() const { return body_; }
const BlockStatement* body() const { return body_.get(); }
/// @returns true if this is a case statement
bool IsCase() const override;
@ -84,7 +91,7 @@ class CaseStatement : public Statement {
CaseStatement(const CaseStatement&) = delete;
CaseSelectorList selectors_;
StatementList body_;
std::unique_ptr<BlockStatement> body_;
};
/// A list of unique case statements

View File

@ -34,17 +34,17 @@ TEST_F(CaseStatementTest, Creation_i32) {
CaseSelectorList b;
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
auto* int_ptr = b.back().get();
auto* discard_ptr = stmts[0].get();
auto* discard_ptr = body->get(0);
CaseStatement c(std::move(b), std::move(stmts));
CaseStatement c(std::move(b), std::move(body));
ASSERT_EQ(c.selectors().size(), 1u);
EXPECT_EQ(c.selectors()[0].get(), int_ptr);
ASSERT_EQ(c.body().size(), 1u);
EXPECT_EQ(c.body()[0].get(), discard_ptr);
ASSERT_EQ(c.body()->size(), 1u);
EXPECT_EQ(c.body()->get(0), discard_ptr);
}
TEST_F(CaseStatementTest, Creation_u32) {
@ -53,17 +53,17 @@ TEST_F(CaseStatementTest, Creation_u32) {
CaseSelectorList b;
b.push_back(std::make_unique<UintLiteral>(&u32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
auto* int_ptr = b.back().get();
auto* discard_ptr = stmts[0].get();
auto* discard_ptr = body->get(0);
CaseStatement c(std::move(b), std::move(stmts));
CaseStatement c(std::move(b), std::move(body));
ASSERT_EQ(c.selectors().size(), 1u);
EXPECT_EQ(c.selectors()[0].get(), int_ptr);
ASSERT_EQ(c.body().size(), 1u);
EXPECT_EQ(c.body()[0].get(), discard_ptr);
ASSERT_EQ(c.body()->size(), 1u);
EXPECT_EQ(c.body()->get(0), discard_ptr);
}
TEST_F(CaseStatementTest, Creation_WithSource) {
@ -71,21 +71,21 @@ TEST_F(CaseStatementTest, Creation_WithSource) {
CaseSelectorList b;
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
CaseStatement c(Source{20, 2}, std::move(b), std::move(stmts));
CaseStatement c(Source{20, 2}, std::move(b), std::move(body));
auto src = c.source();
EXPECT_EQ(src.line, 20u);
EXPECT_EQ(src.column, 2u);
}
TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
CaseStatement c;
c.set_body(std::move(stmts));
c.set_body(std::move(body));
EXPECT_TRUE(c.IsDefault());
}
@ -114,11 +114,11 @@ TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
CaseSelectorList b;
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
stmts.push_back(nullptr);
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
body->append(nullptr);
CaseStatement c(std::move(b), std::move(stmts));
CaseStatement c(std::move(b), std::move(body));
EXPECT_FALSE(c.IsValid());
}
@ -127,10 +127,10 @@ TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
CaseSelectorList b;
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<IfStatement>());
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<IfStatement>());
CaseStatement c({std::move(b)}, std::move(stmts));
CaseStatement c({std::move(b)}, std::move(body));
EXPECT_FALSE(c.IsValid());
}
@ -139,9 +139,9 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
CaseSelectorList b;
b.push_back(std::make_unique<SintLiteral>(&i32, -2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
CaseStatement c({std::move(b)}, std::move(stmts));
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
CaseStatement c({std::move(b)}, std::move(body));
std::ostringstream out;
c.to_str(out, 2);
@ -156,9 +156,9 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors_u32) {
CaseSelectorList b;
b.push_back(std::make_unique<UintLiteral>(&u32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
CaseStatement c({std::move(b)}, std::move(stmts));
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
CaseStatement c({std::move(b)}, std::move(body));
std::ostringstream out;
c.to_str(out, 2);
@ -174,9 +174,10 @@ TEST_F(CaseStatementTest, ToStr_WithMultipleSelectors) {
CaseSelectorList b;
b.push_back(std::make_unique<SintLiteral>(&i32, 1));
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
CaseStatement c(std::move(b), std::move(stmts));
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
CaseStatement c(std::move(b), std::move(body));
std::ostringstream out;
c.to_str(out, 2);
@ -187,9 +188,9 @@ TEST_F(CaseStatementTest, ToStr_WithMultipleSelectors) {
}
TEST_F(CaseStatementTest, ToStr_WithoutSelectors) {
StatementList stmts;
stmts.push_back(std::make_unique<DiscardStatement>());
CaseStatement c(CaseSelectorList{}, std::move(stmts));
auto body = std::make_unique<BlockStatement>();
body->append(std::make_unique<DiscardStatement>());
CaseStatement c(CaseSelectorList{}, std::move(body));
std::ostringstream out;
c.to_str(out, 2);

View File

@ -200,8 +200,11 @@ void Function::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "{" << std::endl;
for (const auto& stmt : *body_)
stmt->to_str(out, indent + 2);
if (body_ != nullptr) {
for (const auto& stmt : *body_) {
stmt->to_str(out, indent + 2);
}
}
make_indent(out, indent);
out << "}" << std::endl;

View File

@ -36,8 +36,8 @@ TEST_F(SwitchStatementTest, Creation) {
auto ident = std::make_unique<IdentifierExpression>("ident");
CaseStatementList body;
body.push_back(
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::make_unique<ast::BlockStatement>()));
auto* ident_ptr = ident.get();
auto* case_ptr = body[0].get();
@ -70,8 +70,8 @@ TEST_F(SwitchStatementTest, IsValid) {
auto ident = std::make_unique<IdentifierExpression>("ident");
CaseStatementList body;
body.push_back(
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::make_unique<ast::BlockStatement>()));
SwitchStatement stmt(std::move(ident), std::move(body));
EXPECT_TRUE(stmt.IsValid());
@ -84,8 +84,8 @@ TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
CaseStatementList body;
body.push_back(
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::make_unique<ast::BlockStatement>()));
SwitchStatement stmt;
stmt.set_body(std::move(body));
@ -100,8 +100,8 @@ TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
auto ident = std::make_unique<IdentifierExpression>("");
CaseStatementList body;
body.push_back(
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::make_unique<ast::BlockStatement>()));
SwitchStatement stmt(std::move(ident), std::move(body));
EXPECT_FALSE(stmt.IsValid());
@ -115,8 +115,8 @@ TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
auto ident = std::make_unique<IdentifierExpression>("ident");
CaseStatementList body;
body.push_back(
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::make_unique<ast::BlockStatement>()));
body.push_back(nullptr);
SwitchStatement stmt(std::move(ident), std::move(body));
@ -126,8 +126,8 @@ TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
auto ident = std::make_unique<IdentifierExpression>("ident");
StatementList case_body;
case_body.push_back(nullptr);
auto case_body = std::make_unique<ast::BlockStatement>();
case_body->append(nullptr);
CaseStatementList body;
body.push_back(std::make_unique<CaseStatement>(CaseSelectorList{},
@ -159,8 +159,8 @@ TEST_F(SwitchStatementTest, ToStr) {
auto ident = std::make_unique<IdentifierExpression>("ident");
CaseStatementList body;
body.push_back(
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
body.push_back(std::make_unique<CaseStatement>(
std::move(lit), std::make_unique<ast::BlockStatement>()));
SwitchStatement stmt(std::move(ident), std::move(body));
std::ostringstream out;

View File

@ -29,8 +29,8 @@ TEST_F(ParserImplTest, SwitchBody_Case) {
ASSERT_NE(e, nullptr);
ASSERT_TRUE(e->IsCase());
EXPECT_FALSE(e->IsDefault());
ASSERT_EQ(e->body().size(), 1u);
EXPECT_TRUE(e->body()[0]->IsAssign());
ASSERT_EQ(e->body()->size(), 1u);
EXPECT_TRUE(e->body()->get(0)->IsAssign());
}
TEST_F(ParserImplTest, SwitchBody_Case_InvalidConstLiteral) {
@ -96,8 +96,8 @@ TEST_F(ParserImplTest, SwitchBody_Default) {
ASSERT_NE(e, nullptr);
ASSERT_TRUE(e->IsCase());
EXPECT_TRUE(e->IsDefault());
ASSERT_EQ(e->body().size(), 1u);
EXPECT_TRUE(e->body()[0]->IsAssign());
ASSERT_EQ(e->body()->size(), 1u);
EXPECT_TRUE(e->body()->get(0)->IsAssign());
}
TEST_F(ParserImplTest, SwitchBody_Default_MissingColon) {

View File

@ -145,9 +145,9 @@ TEST_F(TypeDeterminerTest, Stmt_Case) {
std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
auto* rhs_ptr = rhs.get();
ast::StatementList body;
body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
std::move(rhs)));
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
std::move(rhs)));
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 3));
@ -339,9 +339,9 @@ TEST_F(TypeDeterminerTest, Stmt_Switch) {
std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
auto* rhs_ptr = rhs.get();
ast::StatementList body;
body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
std::move(rhs)));
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
std::move(rhs)));
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 3));

View File

@ -31,12 +31,12 @@ namespace writer {
namespace hlsl {
namespace {
bool last_is_break_or_fallthrough(const ast::StatementList& stmts) {
if (stmts.empty()) {
bool last_is_break_or_fallthrough(const ast::BlockStatement* stmts) {
if (stmts->empty()) {
return false;
}
return stmts.back()->IsBreak() || stmts.back()->IsFallthrough();
return stmts->last()->IsBreak() || stmts->last()->IsFallthrough();
}
} // namespace
@ -207,7 +207,7 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
increment_indent();
for (const auto& s : stmt->body()) {
for (const auto& s : *(stmt->body())) {
if (!EmitStatement(s.get())) {
return false;
}

View File

@ -34,8 +34,8 @@ using HlslGeneratorImplTest = testing::Test;
TEST_F(HlslGeneratorImplTest, Emit_Case) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -55,11 +55,9 @@ TEST_F(HlslGeneratorImplTest, Emit_Case) {
TEST_F(HlslGeneratorImplTest, Emit_Case_BreaksByDefault) {
ast::type::I32Type i32;
ast::StatementList body;
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
ast::CaseStatement c(std::move(lit), std::move(body));
ast::CaseStatement c(std::move(lit), std::make_unique<ast::BlockStatement>());
ast::Module m;
GeneratorImpl g(&m);
@ -75,8 +73,8 @@ TEST_F(HlslGeneratorImplTest, Emit_Case_BreaksByDefault) {
TEST_F(HlslGeneratorImplTest, Emit_Case_WithFallthrough) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::FallthroughStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::FallthroughStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -96,8 +94,8 @@ TEST_F(HlslGeneratorImplTest, Emit_Case_WithFallthrough) {
TEST_F(HlslGeneratorImplTest, Emit_Case_MultipleSelectors) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -119,9 +117,8 @@ TEST_F(HlslGeneratorImplTest, Emit_Case_MultipleSelectors) {
TEST_F(HlslGeneratorImplTest, Emit_Case_Default) {
ast::CaseStatement c;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
c.set_body(std::move(body));
ast::Module m;

View File

@ -33,16 +33,16 @@ using HlslGeneratorImplTest = testing::Test;
TEST_F(HlslGeneratorImplTest, Emit_Switch) {
auto def = std::make_unique<ast::CaseStatement>();
ast::StatementList def_body;
def_body.push_back(std::make_unique<ast::BreakStatement>());
auto def_body = std::make_unique<ast::BlockStatement>();
def_body->append(std::make_unique<ast::BreakStatement>());
def->set_body(std::move(def_body));
ast::type::I32Type i32;
ast::CaseSelectorList case_val;
case_val.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
ast::StatementList case_body;
case_body.push_back(std::make_unique<ast::BreakStatement>());
auto case_body = std::make_unique<ast::BlockStatement>();
case_body->append(std::make_unique<ast::BreakStatement>());
auto case_stmt = std::make_unique<ast::CaseStatement>(std::move(case_val),
std::move(case_body));

View File

@ -66,12 +66,12 @@ const char kOutStructNameSuffix[] = "out";
const char kTintStructInVarPrefix[] = "tint_in";
const char kTintStructOutVarPrefix[] = "tint_out";
bool last_is_break_or_fallthrough(const ast::StatementList& stmts) {
if (stmts.empty()) {
bool last_is_break_or_fallthrough(const ast::BlockStatement* stmts) {
if (stmts->empty()) {
return false;
}
return stmts.back()->IsBreak() || stmts.back()->IsFallthrough();
return stmts->last()->IsBreak() || stmts->last()->IsFallthrough();
}
uint32_t adjust_for_alignment(uint32_t count, uint32_t alignment) {
@ -755,7 +755,7 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
increment_indent();
for (const auto& s : stmt->body()) {
for (const auto& s : *(stmt->body())) {
if (!EmitStatement(s.get())) {
return false;
}

View File

@ -34,8 +34,8 @@ using MslGeneratorImplTest = testing::Test;
TEST_F(MslGeneratorImplTest, Emit_Case) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -55,11 +55,9 @@ TEST_F(MslGeneratorImplTest, Emit_Case) {
TEST_F(MslGeneratorImplTest, Emit_Case_BreaksByDefault) {
ast::type::I32Type i32;
ast::StatementList body;
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
ast::CaseStatement c(std::move(lit), std::move(body));
ast::CaseStatement c(std::move(lit), std::make_unique<ast::BlockStatement>());
ast::Module m;
GeneratorImpl g(&m);
@ -75,8 +73,8 @@ TEST_F(MslGeneratorImplTest, Emit_Case_BreaksByDefault) {
TEST_F(MslGeneratorImplTest, Emit_Case_WithFallthrough) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::FallthroughStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::FallthroughStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -96,8 +94,8 @@ TEST_F(MslGeneratorImplTest, Emit_Case_WithFallthrough) {
TEST_F(MslGeneratorImplTest, Emit_Case_MultipleSelectors) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -119,9 +117,8 @@ TEST_F(MslGeneratorImplTest, Emit_Case_MultipleSelectors) {
TEST_F(MslGeneratorImplTest, Emit_Case_Default) {
ast::CaseStatement c;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
c.set_body(std::move(body));
ast::Module m;

View File

@ -33,16 +33,16 @@ using MslGeneratorImplTest = testing::Test;
TEST_F(MslGeneratorImplTest, Emit_Switch) {
auto def = std::make_unique<ast::CaseStatement>();
ast::StatementList def_body;
def_body.push_back(std::make_unique<ast::BreakStatement>());
auto def_body = std::make_unique<ast::BlockStatement>();
def_body->append(std::make_unique<ast::BreakStatement>());
def->set_body(std::move(def_body));
ast::type::I32Type i32;
ast::CaseSelectorList case_val;
case_val.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
ast::StatementList case_body;
case_body.push_back(std::make_unique<ast::BreakStatement>());
auto case_body = std::make_unique<ast::BlockStatement>();
case_body->append(std::make_unique<ast::BreakStatement>());
auto case_stmt = std::make_unique<ast::CaseStatement>(std::move(case_val),
std::move(case_body));

View File

@ -93,13 +93,23 @@ uint32_t pipeline_stage_to_execution_model(ast::PipelineStage stage) {
return model;
}
bool LastIsFallthrough(const ast::StatementList& stmts) {
return !stmts.empty() && stmts.back()->IsFallthrough();
bool LastIsFallthrough(const ast::BlockStatement* stmts) {
return !stmts->empty() && stmts->last()->IsFallthrough();
}
// A terminator is anything which will case a SPIR-V terminator to be emitted.
// This means things like breaks, fallthroughs and continues which all emit an
// OpBranch or return for the OpReturn emission.
bool LastIsTerminator(const ast::BlockStatement* stmts) {
if (stmts->empty()) {
return false;
}
auto* last = stmts->last();
return last->IsBreak() || last->IsContinue() || last->IsDiscard() ||
last->IsReturn() || last->IsFallthrough();
}
bool LastIsTerminator(const ast::StatementList& stmts) {
if (stmts.empty()) {
return false;
@ -1339,7 +1349,7 @@ uint32_t Builder::GenerateBinaryExpression(ast::BinaryExpression* expr) {
return result_id;
}
bool Builder::GenerateBlockStatement(ast::BlockStatement* stmt) {
bool Builder::GenerateBlockStatement(const ast::BlockStatement* stmt) {
scope_stack_.push_scope();
for (const auto& block_stmt : *stmt) {
if (!GenerateStatement(block_stmt.get())) {
@ -1720,7 +1730,7 @@ bool Builder::GenerateSwitchStatement(ast::SwitchStatement* stmt) {
}
GenerateLabel(case_ids[i]);
if (!GenerateStatementList(item->body())) {
if (!GenerateBlockStatement(item->body())) {
return false;
}

View File

@ -170,7 +170,7 @@ class Builder {
/// Generates a block statement
/// @param stmt the statement to generate
/// @returns true if the statement was successfully generated
bool GenerateBlockStatement(ast::BlockStatement* stmt);
bool GenerateBlockStatement(const ast::BlockStatement* stmt);
/// Generates a break statement
/// @param stmt the statement to generate
/// @returns true if the statement was successfully generated

View File

@ -85,14 +85,14 @@ TEST_F(BuilderTest, Switch_WithCase) {
auto a =
std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
ast::StatementList case_1_body;
case_1_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_1_body = std::make_unique<ast::BlockStatement>();
case_1_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1))));
ast::StatementList case_2_body;
case_2_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_2_body = std::make_unique<ast::BlockStatement>();
case_2_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 2))));
@ -170,8 +170,8 @@ TEST_F(BuilderTest, Switch_WithDefault) {
auto a =
std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
ast::StatementList default_body;
default_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto default_body = std::make_unique<ast::BlockStatement>();
default_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1))));
@ -239,20 +239,20 @@ TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
auto a =
std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
ast::StatementList case_1_body;
case_1_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_1_body = std::make_unique<ast::BlockStatement>();
case_1_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1))));
ast::StatementList case_2_body;
case_2_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_2_body = std::make_unique<ast::BlockStatement>();
case_2_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 2))));
ast::StatementList default_body;
default_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto default_body = std::make_unique<ast::BlockStatement>();
default_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 3))));
@ -340,21 +340,21 @@ TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
auto a =
std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
ast::StatementList case_1_body;
case_1_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_1_body = std::make_unique<ast::BlockStatement>();
case_1_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1))));
case_1_body.push_back(std::make_unique<ast::FallthroughStatement>());
case_1_body->append(std::make_unique<ast::FallthroughStatement>());
ast::StatementList case_2_body;
case_2_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_2_body = std::make_unique<ast::BlockStatement>();
case_2_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 2))));
ast::StatementList default_body;
default_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto default_body = std::make_unique<ast::BlockStatement>();
default_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 3))));
@ -437,12 +437,12 @@ TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) {
auto a =
std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
ast::StatementList case_1_body;
case_1_body.push_back(std::make_unique<ast::AssignmentStatement>(
auto case_1_body = std::make_unique<ast::BlockStatement>();
case_1_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1))));
case_1_body.push_back(std::make_unique<ast::FallthroughStatement>());
case_1_body->append(std::make_unique<ast::FallthroughStatement>());
ast::CaseSelectorList selector_1;
selector_1.push_back(std::make_unique<ast::SintLiteral>(&i32, 1));
@ -492,13 +492,13 @@ TEST_F(BuilderTest, Switch_WithNestedBreak) {
ast::StatementList if_body;
if_body.push_back(std::make_unique<ast::BreakStatement>());
ast::StatementList case_1_body;
case_1_body.push_back(std::make_unique<ast::IfStatement>(
auto case_1_body = std::make_unique<ast::BlockStatement>();
case_1_body->append(std::make_unique<ast::IfStatement>(
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::BoolLiteral>(&bool_type, true)),
std::move(if_body)));
case_1_body.push_back(std::make_unique<ast::AssignmentStatement>(
case_1_body->append(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>("v"),
std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1))));

View File

@ -600,7 +600,7 @@ bool GeneratorImpl::EmitUnaryOp(ast::UnaryOpExpression* expr) {
return true;
}
bool GeneratorImpl::EmitBlock(ast::BlockStatement* stmt) {
bool GeneratorImpl::EmitBlock(const ast::BlockStatement* stmt) {
out_ << "{" << std::endl;
increment_indent();
@ -617,7 +617,8 @@ bool GeneratorImpl::EmitBlock(ast::BlockStatement* stmt) {
return true;
}
bool GeneratorImpl::EmitIndentedBlockAndNewline(ast::BlockStatement* stmt) {
bool GeneratorImpl::EmitIndentedBlockAndNewline(
const ast::BlockStatement* stmt) {
make_indent();
const bool result = EmitBlock(stmt);
if (result) {
@ -626,7 +627,7 @@ bool GeneratorImpl::EmitIndentedBlockAndNewline(ast::BlockStatement* stmt) {
return result;
}
bool GeneratorImpl::EmitBlockAndNewline(ast::BlockStatement* stmt) {
bool GeneratorImpl::EmitBlockAndNewline(const ast::BlockStatement* stmt) {
const bool result = EmitBlock(stmt);
if (result) {
out_ << std::endl;
@ -736,7 +737,7 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
make_indent();
if (stmt->IsDefault()) {
out_ << "default:";
out_ << "default";
} else {
out_ << "case ";
@ -752,10 +753,10 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
}
}
out_ << ":";
}
out_ << ": ";
return EmitStatementBlockAndNewline(stmt->body());
return EmitBlockAndNewline(stmt->body());
}
bool GeneratorImpl::EmitContinue(ast::ContinueStatement*) {

View File

@ -70,15 +70,15 @@ class GeneratorImpl : public TextGenerator {
/// Handles a block statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
bool EmitBlock(ast::BlockStatement* stmt);
bool EmitBlock(const ast::BlockStatement* stmt);
/// Handles a block statement with a newline at the end
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
bool EmitIndentedBlockAndNewline(ast::BlockStatement* stmt);
bool EmitIndentedBlockAndNewline(const ast::BlockStatement* stmt);
/// Handles a block statement with a newline at the end
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
bool EmitBlockAndNewline(ast::BlockStatement* stmt);
bool EmitBlockAndNewline(const ast::BlockStatement* stmt);
/// Handles a break statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully

View File

@ -32,8 +32,8 @@ using WgslGeneratorImplTest = testing::Test;
TEST_F(WgslGeneratorImplTest, Emit_Case) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -52,8 +52,8 @@ TEST_F(WgslGeneratorImplTest, Emit_Case) {
TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
ast::type::I32Type i32;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
ast::CaseSelectorList lit;
lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
@ -73,9 +73,8 @@ TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
TEST_F(WgslGeneratorImplTest, Emit_Case_Default) {
ast::CaseStatement c;
ast::StatementList body;
body.push_back(std::make_unique<ast::BreakStatement>());
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::BreakStatement>());
c.set_body(std::move(body));
GeneratorImpl g;

View File

@ -32,16 +32,16 @@ using WgslGeneratorImplTest = testing::Test;
TEST_F(WgslGeneratorImplTest, Emit_Switch) {
auto def = std::make_unique<ast::CaseStatement>();
ast::StatementList def_body;
def_body.push_back(std::make_unique<ast::BreakStatement>());
auto def_body = std::make_unique<ast::BlockStatement>();
def_body->append(std::make_unique<ast::BreakStatement>());
def->set_body(std::move(def_body));
ast::type::I32Type i32;
ast::CaseSelectorList case_val;
case_val.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
ast::StatementList case_body;
case_body.push_back(std::make_unique<ast::BreakStatement>());
auto case_body = std::make_unique<ast::BlockStatement>();
case_body->append(std::make_unique<ast::BreakStatement>());
auto case_stmt = std::make_unique<ast::CaseStatement>(std::move(case_val),
std::move(case_body));