Remove conditional break/continue.
This CL removes the conditional forms of the break and continue statements as they are no longer in the WGSL spec. Change-Id: I46224d6cb5ce706cfc95d35ab0a4eea46abf62a9 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22580 Reviewed-by: Ryan Harrison <rharrison@chromium.org>
This commit is contained in:
parent
27d42ede4e
commit
6bd7061a2e
2
BUILD.gn
2
BUILD.gn
|
@ -278,8 +278,6 @@ source_set("libtint_core_src") {
|
||||||
"src/ast/sint_literal.h",
|
"src/ast/sint_literal.h",
|
||||||
"src/ast/statement.cc",
|
"src/ast/statement.cc",
|
||||||
"src/ast/statement.h",
|
"src/ast/statement.h",
|
||||||
"src/ast/statement_condition.cc",
|
|
||||||
"src/ast/statement_condition.h",
|
|
||||||
"src/ast/storage_class.cc",
|
"src/ast/storage_class.cc",
|
||||||
"src/ast/storage_class.h",
|
"src/ast/storage_class.h",
|
||||||
"src/ast/struct.cc",
|
"src/ast/struct.cc",
|
||||||
|
|
|
@ -115,8 +115,6 @@ set(TINT_LIB_SRCS
|
||||||
ast/sint_literal.h
|
ast/sint_literal.h
|
||||||
ast/statement.cc
|
ast/statement.cc
|
||||||
ast/statement.h
|
ast/statement.h
|
||||||
ast/statement_condition.cc
|
|
||||||
ast/statement_condition.h
|
|
||||||
ast/storage_class.cc
|
ast/storage_class.cc
|
||||||
ast/storage_class.h
|
ast/storage_class.h
|
||||||
ast/struct_decoration.cc
|
ast/struct_decoration.cc
|
||||||
|
|
|
@ -21,19 +21,6 @@ BreakStatement::BreakStatement() : Statement() {}
|
||||||
|
|
||||||
BreakStatement::BreakStatement(const Source& source) : Statement(source) {}
|
BreakStatement::BreakStatement(const Source& source) : Statement(source) {}
|
||||||
|
|
||||||
BreakStatement::BreakStatement(StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional)
|
|
||||||
: Statement(),
|
|
||||||
condition_(condition),
|
|
||||||
conditional_(std::move(conditional)) {}
|
|
||||||
|
|
||||||
BreakStatement::BreakStatement(const Source& source,
|
|
||||||
StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional)
|
|
||||||
: Statement(source),
|
|
||||||
condition_(condition),
|
|
||||||
conditional_(std::move(conditional)) {}
|
|
||||||
|
|
||||||
BreakStatement::BreakStatement(BreakStatement&&) = default;
|
BreakStatement::BreakStatement(BreakStatement&&) = default;
|
||||||
|
|
||||||
BreakStatement::~BreakStatement() = default;
|
BreakStatement::~BreakStatement() = default;
|
||||||
|
@ -43,26 +30,12 @@ bool BreakStatement::IsBreak() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BreakStatement::IsValid() const {
|
bool BreakStatement::IsValid() const {
|
||||||
if (condition_ == StatementCondition::kNone)
|
return true;
|
||||||
return conditional_ == nullptr;
|
|
||||||
|
|
||||||
return conditional_ != nullptr && conditional_->IsValid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BreakStatement::to_str(std::ostream& out, size_t indent) const {
|
void BreakStatement::to_str(std::ostream& out, size_t indent) const {
|
||||||
make_indent(out, indent);
|
make_indent(out, indent);
|
||||||
out << "Break{";
|
out << "Break{}" << std::endl;
|
||||||
|
|
||||||
if (condition_ != StatementCondition::kNone) {
|
|
||||||
out << std::endl;
|
|
||||||
|
|
||||||
make_indent(out, indent + 2);
|
|
||||||
out << condition_ << std::endl;
|
|
||||||
conditional_->to_str(out, indent + 2);
|
|
||||||
|
|
||||||
make_indent(out, indent);
|
|
||||||
}
|
|
||||||
out << "}" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
|
@ -15,12 +15,7 @@
|
||||||
#ifndef SRC_AST_BREAK_STATEMENT_H_
|
#ifndef SRC_AST_BREAK_STATEMENT_H_
|
||||||
#define SRC_AST_BREAK_STATEMENT_H_
|
#define SRC_AST_BREAK_STATEMENT_H_
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "src/ast/expression.h"
|
|
||||||
#include "src/ast/statement.h"
|
#include "src/ast/statement.h"
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
@ -33,36 +28,10 @@ class BreakStatement : public Statement {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param source the break statement source
|
/// @param source the break statement source
|
||||||
explicit BreakStatement(const Source& source);
|
explicit BreakStatement(const Source& source);
|
||||||
/// Constructor
|
|
||||||
/// @param condition the condition type
|
|
||||||
/// @param conditional the condition expression
|
|
||||||
BreakStatement(StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional);
|
|
||||||
/// Constructor
|
|
||||||
/// @param source the break statement source
|
|
||||||
/// @param condition the condition type
|
|
||||||
/// @param conditional the condition expression
|
|
||||||
BreakStatement(const Source& source,
|
|
||||||
StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional);
|
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
BreakStatement(BreakStatement&&);
|
BreakStatement(BreakStatement&&);
|
||||||
~BreakStatement() override;
|
~BreakStatement() override;
|
||||||
|
|
||||||
/// Sets the condition type
|
|
||||||
/// @param condition the condition type
|
|
||||||
void set_condition(StatementCondition condition) { condition_ = condition; }
|
|
||||||
/// @returns the condition type
|
|
||||||
StatementCondition condition() const { return condition_; }
|
|
||||||
|
|
||||||
/// Sets the conditional expression
|
|
||||||
/// @param conditional the conditional expression
|
|
||||||
void set_conditional(std::unique_ptr<Expression> conditional) {
|
|
||||||
conditional_ = std::move(conditional);
|
|
||||||
}
|
|
||||||
/// @returns the conditional expression
|
|
||||||
Expression* conditional() const { return conditional_.get(); }
|
|
||||||
|
|
||||||
/// @returns true if this is an break statement
|
/// @returns true if this is an break statement
|
||||||
bool IsBreak() const override;
|
bool IsBreak() const override;
|
||||||
|
|
||||||
|
@ -76,9 +45,6 @@ class BreakStatement : public Statement {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BreakStatement(const BreakStatement&) = delete;
|
BreakStatement(const BreakStatement&) = delete;
|
||||||
|
|
||||||
StatementCondition condition_ = StatementCondition::kNone;
|
|
||||||
std::unique_ptr<Expression> conditional_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "src/ast/break_statement.h"
|
#include "src/ast/break_statement.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
@ -24,21 +22,6 @@ namespace {
|
||||||
|
|
||||||
using BreakStatementTest = testing::Test;
|
using BreakStatementTest = testing::Test;
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, Creation) {
|
|
||||||
BreakStatement stmt;
|
|
||||||
EXPECT_EQ(stmt.condition(), StatementCondition::kNone);
|
|
||||||
EXPECT_EQ(stmt.conditional(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, CreationWithConditional) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
auto* expr_ptr = expr.get();
|
|
||||||
|
|
||||||
BreakStatement stmt(StatementCondition::kIf, std::move(expr));
|
|
||||||
EXPECT_EQ(stmt.condition(), StatementCondition::kIf);
|
|
||||||
EXPECT_EQ(stmt.conditional(), expr_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, Creation_WithSource) {
|
TEST_F(BreakStatementTest, Creation_WithSource) {
|
||||||
BreakStatement stmt(Source{20, 2});
|
BreakStatement stmt(Source{20, 2});
|
||||||
auto src = stmt.source();
|
auto src = stmt.source();
|
||||||
|
@ -46,51 +29,17 @@ TEST_F(BreakStatementTest, Creation_WithSource) {
|
||||||
EXPECT_EQ(src.column, 2u);
|
EXPECT_EQ(src.column, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, Creation_WithSourceAndCondition) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
|
|
||||||
BreakStatement stmt(Source{20, 2}, StatementCondition::kUnless,
|
|
||||||
std::move(expr));
|
|
||||||
auto src = stmt.source();
|
|
||||||
EXPECT_EQ(src.line, 20u);
|
|
||||||
EXPECT_EQ(src.column, 2u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, IsBreak) {
|
TEST_F(BreakStatementTest, IsBreak) {
|
||||||
BreakStatement stmt;
|
BreakStatement stmt;
|
||||||
EXPECT_TRUE(stmt.IsBreak());
|
EXPECT_TRUE(stmt.IsBreak());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, IsValid_WithoutCondition) {
|
TEST_F(BreakStatementTest, IsValid) {
|
||||||
BreakStatement stmt;
|
BreakStatement stmt;
|
||||||
EXPECT_TRUE(stmt.IsValid());
|
EXPECT_TRUE(stmt.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, IsValid_WithCondition) {
|
TEST_F(BreakStatementTest, ToStr) {
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
BreakStatement stmt(StatementCondition::kIf, std::move(expr));
|
|
||||||
EXPECT_TRUE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, IsValid_WithConditionAndConditionNone) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
BreakStatement stmt(StatementCondition::kNone, std::move(expr));
|
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, IsValid_WithCondition_MissingConditional) {
|
|
||||||
BreakStatement stmt;
|
|
||||||
stmt.set_condition(StatementCondition::kIf);
|
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, IsValid_InvalidConditional) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("");
|
|
||||||
BreakStatement stmt(StatementCondition::kIf, std::move(expr));
|
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, ToStr_WithoutCondition) {
|
|
||||||
BreakStatement stmt;
|
BreakStatement stmt;
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
stmt.to_str(out, 2);
|
stmt.to_str(out, 2);
|
||||||
|
@ -98,18 +47,6 @@ TEST_F(BreakStatementTest, ToStr_WithoutCondition) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BreakStatementTest, ToStr_WithCondition) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
BreakStatement stmt(StatementCondition::kUnless, std::move(expr));
|
|
||||||
std::ostringstream out;
|
|
||||||
stmt.to_str(out, 2);
|
|
||||||
EXPECT_EQ(out.str(), R"( Break{
|
|
||||||
unless
|
|
||||||
Identifier{expr}
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -22,19 +22,6 @@ ContinueStatement::ContinueStatement() : Statement() {}
|
||||||
ContinueStatement::ContinueStatement(const Source& source)
|
ContinueStatement::ContinueStatement(const Source& source)
|
||||||
: Statement(source) {}
|
: Statement(source) {}
|
||||||
|
|
||||||
ContinueStatement::ContinueStatement(StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional)
|
|
||||||
: Statement(),
|
|
||||||
condition_(condition),
|
|
||||||
conditional_(std::move(conditional)) {}
|
|
||||||
|
|
||||||
ContinueStatement::ContinueStatement(const Source& source,
|
|
||||||
StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional)
|
|
||||||
: Statement(source),
|
|
||||||
condition_(condition),
|
|
||||||
conditional_(std::move(conditional)) {}
|
|
||||||
|
|
||||||
ContinueStatement::ContinueStatement(ContinueStatement&&) = default;
|
ContinueStatement::ContinueStatement(ContinueStatement&&) = default;
|
||||||
|
|
||||||
ContinueStatement::~ContinueStatement() = default;
|
ContinueStatement::~ContinueStatement() = default;
|
||||||
|
@ -44,26 +31,12 @@ bool ContinueStatement::IsContinue() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContinueStatement::IsValid() const {
|
bool ContinueStatement::IsValid() const {
|
||||||
if (condition_ == StatementCondition::kNone)
|
return true;
|
||||||
return conditional_ == nullptr;
|
|
||||||
|
|
||||||
return conditional_ && conditional_->IsValid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContinueStatement::to_str(std::ostream& out, size_t indent) const {
|
void ContinueStatement::to_str(std::ostream& out, size_t indent) const {
|
||||||
make_indent(out, indent);
|
make_indent(out, indent);
|
||||||
out << "Continue{";
|
out << "Continue{}" << std::endl;
|
||||||
|
|
||||||
if (condition_ != StatementCondition::kNone) {
|
|
||||||
out << std::endl;
|
|
||||||
|
|
||||||
make_indent(out, indent + 2);
|
|
||||||
out << condition_ << std::endl;
|
|
||||||
conditional_->to_str(out, indent + 2);
|
|
||||||
|
|
||||||
make_indent(out, indent);
|
|
||||||
}
|
|
||||||
out << "}" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
|
@ -18,9 +18,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/ast/expression.h"
|
|
||||||
#include "src/ast/statement.h"
|
#include "src/ast/statement.h"
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
@ -33,36 +31,10 @@ class ContinueStatement : public Statement {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param source the continue statement source
|
/// @param source the continue statement source
|
||||||
explicit ContinueStatement(const Source& source);
|
explicit ContinueStatement(const Source& source);
|
||||||
/// Constructor
|
|
||||||
/// @param condition the condition type
|
|
||||||
/// @param conditional the condition expression
|
|
||||||
ContinueStatement(StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional);
|
|
||||||
/// Constructor
|
|
||||||
/// @param source the continue statement source
|
|
||||||
/// @param condition the condition type
|
|
||||||
/// @param conditional the condition expression
|
|
||||||
ContinueStatement(const Source& source,
|
|
||||||
StatementCondition condition,
|
|
||||||
std::unique_ptr<Expression> conditional);
|
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
ContinueStatement(ContinueStatement&&);
|
ContinueStatement(ContinueStatement&&);
|
||||||
~ContinueStatement() override;
|
~ContinueStatement() override;
|
||||||
|
|
||||||
/// Sets the condition type
|
|
||||||
/// @param condition the condition type
|
|
||||||
void set_condition(StatementCondition condition) { condition_ = condition; }
|
|
||||||
/// @returns the condition type
|
|
||||||
StatementCondition condition() const { return condition_; }
|
|
||||||
|
|
||||||
/// Sets the conditional expression
|
|
||||||
/// @param conditional the conditional expression
|
|
||||||
void set_conditional(std::unique_ptr<Expression> conditional) {
|
|
||||||
conditional_ = std::move(conditional);
|
|
||||||
}
|
|
||||||
/// @returns the conditional expression
|
|
||||||
Expression* conditional() const { return conditional_.get(); }
|
|
||||||
|
|
||||||
/// @returns true if this is an continue statement
|
/// @returns true if this is an continue statement
|
||||||
bool IsContinue() const override;
|
bool IsContinue() const override;
|
||||||
|
|
||||||
|
@ -76,9 +48,6 @@ class ContinueStatement : public Statement {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ContinueStatement(const ContinueStatement&) = delete;
|
ContinueStatement(const ContinueStatement&) = delete;
|
||||||
|
|
||||||
StatementCondition condition_ = StatementCondition::kNone;
|
|
||||||
std::unique_ptr<Expression> conditional_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
@ -24,21 +22,6 @@ namespace {
|
||||||
|
|
||||||
using ContinueStatementTest = testing::Test;
|
using ContinueStatementTest = testing::Test;
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, Creation) {
|
|
||||||
ContinueStatement stmt;
|
|
||||||
EXPECT_EQ(stmt.condition(), StatementCondition::kNone);
|
|
||||||
EXPECT_EQ(stmt.conditional(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, CreationWithConditional) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
auto* expr_ptr = expr.get();
|
|
||||||
|
|
||||||
ContinueStatement stmt(StatementCondition::kIf, std::move(expr));
|
|
||||||
EXPECT_EQ(stmt.condition(), StatementCondition::kIf);
|
|
||||||
EXPECT_EQ(stmt.conditional(), expr_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, Creation_WithSource) {
|
TEST_F(ContinueStatementTest, Creation_WithSource) {
|
||||||
ContinueStatement stmt(Source{20, 2});
|
ContinueStatement stmt(Source{20, 2});
|
||||||
auto src = stmt.source();
|
auto src = stmt.source();
|
||||||
|
@ -46,51 +29,17 @@ TEST_F(ContinueStatementTest, Creation_WithSource) {
|
||||||
EXPECT_EQ(src.column, 2u);
|
EXPECT_EQ(src.column, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, Creation_WithSourceAndCondition) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
|
|
||||||
ContinueStatement stmt(Source{20, 2}, StatementCondition::kUnless,
|
|
||||||
std::move(expr));
|
|
||||||
auto src = stmt.source();
|
|
||||||
EXPECT_EQ(src.line, 20u);
|
|
||||||
EXPECT_EQ(src.column, 2u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, IsContinue) {
|
TEST_F(ContinueStatementTest, IsContinue) {
|
||||||
ContinueStatement stmt;
|
ContinueStatement stmt;
|
||||||
EXPECT_TRUE(stmt.IsContinue());
|
EXPECT_TRUE(stmt.IsContinue());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, IsValid_WithoutCondition) {
|
TEST_F(ContinueStatementTest, IsValid) {
|
||||||
ContinueStatement stmt;
|
ContinueStatement stmt;
|
||||||
EXPECT_TRUE(stmt.IsValid());
|
EXPECT_TRUE(stmt.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, IsValid_WithCondition) {
|
TEST_F(ContinueStatementTest, ToStr) {
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
ContinueStatement stmt(StatementCondition::kIf, std::move(expr));
|
|
||||||
EXPECT_TRUE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, IsValid_InvalidConditional) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("");
|
|
||||||
ContinueStatement stmt(StatementCondition::kIf, std::move(expr));
|
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, IsValid_NoneConditionWithConditional) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
ContinueStatement stmt(StatementCondition::kNone, std::move(expr));
|
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, IsValid_WithCondition_MissingConditional) {
|
|
||||||
ContinueStatement stmt;
|
|
||||||
stmt.set_condition(StatementCondition::kIf);
|
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, ToStr_WithoutCondition) {
|
|
||||||
ContinueStatement stmt;
|
ContinueStatement stmt;
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
stmt.to_str(out, 2);
|
stmt.to_str(out, 2);
|
||||||
|
@ -98,18 +47,6 @@ TEST_F(ContinueStatementTest, ToStr_WithoutCondition) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ContinueStatementTest, ToStr_WithCondition) {
|
|
||||||
auto expr = std::make_unique<IdentifierExpression>("expr");
|
|
||||||
ContinueStatement stmt(StatementCondition::kUnless, std::move(expr));
|
|
||||||
std::ostringstream out;
|
|
||||||
stmt.to_str(out, 2);
|
|
||||||
EXPECT_EQ(out.str(), R"( Continue{
|
|
||||||
unless
|
|
||||||
Identifier{expr}
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
#ifndef SRC_AST_FALLTHROUGH_STATEMENT_H_
|
#ifndef SRC_AST_FALLTHROUGH_STATEMENT_H_
|
||||||
#define SRC_AST_FALLTHROUGH_STATEMENT_H_
|
#define SRC_AST_FALLTHROUGH_STATEMENT_H_
|
||||||
|
|
||||||
#include "src/ast/expression.h"
|
|
||||||
#include "src/ast/statement.h"
|
#include "src/ast/statement.h"
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
// Copyright 2020 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace ast {
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, StatementCondition condition) {
|
|
||||||
switch (condition) {
|
|
||||||
case StatementCondition::kNone:
|
|
||||||
out << "none";
|
|
||||||
break;
|
|
||||||
case StatementCondition::kIf:
|
|
||||||
out << "if";
|
|
||||||
break;
|
|
||||||
case StatementCondition::kUnless:
|
|
||||||
out << "unless";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ast
|
|
||||||
} // namespace tint
|
|
|
@ -1,31 +0,0 @@
|
||||||
// Copyright 2020 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef SRC_AST_STATEMENT_CONDITION_H_
|
|
||||||
#define SRC_AST_STATEMENT_CONDITION_H_
|
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace ast {
|
|
||||||
|
|
||||||
/// Type of condition attached to a statement
|
|
||||||
enum class StatementCondition { kNone = 0, kIf, kUnless };
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, StatementCondition condition);
|
|
||||||
|
|
||||||
} // namespace ast
|
|
||||||
} // namespace tint
|
|
||||||
|
|
||||||
#endif // SRC_AST_STATEMENT_CONDITION_H_
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "src/ast/expression.h"
|
#include "src/ast/expression.h"
|
||||||
#include "src/ast/literal.h"
|
#include "src/ast/literal.h"
|
||||||
#include "src/ast/statement.h"
|
#include "src/ast/statement.h"
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
#include "src/ast/switch_statement.h"
|
#include "src/ast/switch_statement.h"
|
||||||
#include "src/ast/type/alias_type.h"
|
#include "src/ast/type/alias_type.h"
|
||||||
|
@ -1943,73 +1942,25 @@ std::unique_ptr<ast::LoopStatement> ParserImpl::loop_stmt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// break_stmt
|
// break_stmt
|
||||||
// : BREAK ({IF | UNLESS} paren_rhs_stmt)?
|
// : BREAK
|
||||||
std::unique_ptr<ast::BreakStatement> ParserImpl::break_stmt() {
|
std::unique_ptr<ast::BreakStatement> ParserImpl::break_stmt() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsBreak())
|
if (!t.IsBreak())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto source = t.source();
|
|
||||||
next(); // Consume the peek
|
next(); // Consume the peek
|
||||||
|
return std::make_unique<ast::BreakStatement>(t.source());
|
||||||
ast::StatementCondition condition = ast::StatementCondition::kNone;
|
|
||||||
std::unique_ptr<ast::Expression> conditional = nullptr;
|
|
||||||
|
|
||||||
t = peek();
|
|
||||||
if (t.IsIf() || t.IsUnless()) {
|
|
||||||
next(); // Consume the peek
|
|
||||||
|
|
||||||
if (t.IsIf())
|
|
||||||
condition = ast::StatementCondition::kIf;
|
|
||||||
else
|
|
||||||
condition = ast::StatementCondition::kUnless;
|
|
||||||
|
|
||||||
conditional = paren_rhs_stmt();
|
|
||||||
if (has_error())
|
|
||||||
return nullptr;
|
|
||||||
if (conditional == nullptr) {
|
|
||||||
set_error(peek(), "unable to parse conditional statement");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_unique<ast::BreakStatement>(source, condition,
|
|
||||||
std::move(conditional));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue_stmt
|
// continue_stmt
|
||||||
// : CONTINUE ({IF | UNLESS} paren_rhs_stmt)?
|
// : CONTINUE
|
||||||
std::unique_ptr<ast::ContinueStatement> ParserImpl::continue_stmt() {
|
std::unique_ptr<ast::ContinueStatement> ParserImpl::continue_stmt() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsContinue())
|
if (!t.IsContinue())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto source = t.source();
|
|
||||||
next(); // Consume the peek
|
next(); // Consume the peek
|
||||||
|
return std::make_unique<ast::ContinueStatement>(t.source());
|
||||||
ast::StatementCondition condition = ast::StatementCondition::kNone;
|
|
||||||
std::unique_ptr<ast::Expression> conditional = nullptr;
|
|
||||||
|
|
||||||
t = peek();
|
|
||||||
if (t.IsIf() || t.IsUnless()) {
|
|
||||||
next(); // Consume the peek
|
|
||||||
|
|
||||||
if (t.IsIf())
|
|
||||||
condition = ast::StatementCondition::kIf;
|
|
||||||
else
|
|
||||||
condition = ast::StatementCondition::kUnless;
|
|
||||||
|
|
||||||
conditional = paren_rhs_stmt();
|
|
||||||
if (has_error())
|
|
||||||
return nullptr;
|
|
||||||
if (conditional == nullptr) {
|
|
||||||
set_error(peek(), "unable to parse conditional statement");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_unique<ast::ContinueStatement>(source, condition,
|
|
||||||
std::move(conditional));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// continuing_stmt
|
// continuing_stmt
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/break_statement.h"
|
#include "src/ast/break_statement.h"
|
||||||
#include "src/ast/return_statement.h"
|
|
||||||
#include "src/ast/statement.h"
|
|
||||||
#include "src/reader/wgsl/parser_impl.h"
|
#include "src/reader/wgsl/parser_impl.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
|
@ -30,46 +28,6 @@ TEST_F(ParserImplTest, BreakStmt) {
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e, nullptr);
|
ASSERT_NE(e, nullptr);
|
||||||
ASSERT_TRUE(e->IsBreak());
|
ASSERT_TRUE(e->IsBreak());
|
||||||
EXPECT_EQ(e->condition(), ast::StatementCondition::kNone);
|
|
||||||
EXPECT_EQ(e->conditional(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, BreakStmt_WithIf) {
|
|
||||||
auto* p = parser("break if (a == b)");
|
|
||||||
auto e = p->break_stmt();
|
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
|
||||||
ASSERT_NE(e, nullptr);
|
|
||||||
ASSERT_TRUE(e->IsBreak());
|
|
||||||
EXPECT_EQ(e->condition(), ast::StatementCondition::kIf);
|
|
||||||
ASSERT_NE(e->conditional(), nullptr);
|
|
||||||
EXPECT_TRUE(e->conditional()->IsBinary());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, BreakStmt_WithUnless) {
|
|
||||||
auto* p = parser("break unless (a == b)");
|
|
||||||
auto e = p->break_stmt();
|
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
|
||||||
ASSERT_NE(e, nullptr);
|
|
||||||
ASSERT_TRUE(e->IsBreak());
|
|
||||||
EXPECT_EQ(e->condition(), ast::StatementCondition::kUnless);
|
|
||||||
ASSERT_NE(e->conditional(), nullptr);
|
|
||||||
EXPECT_TRUE(e->conditional()->IsBinary());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, BreakStmt_InvalidRHS) {
|
|
||||||
auto* p = parser("break if (a = b)");
|
|
||||||
auto e = p->break_stmt();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(e, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:13: expected )");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, BreakStmt_MissingRHS) {
|
|
||||||
auto* p = parser("break if");
|
|
||||||
auto e = p->break_stmt();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(e, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:9: expected (");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/return_statement.h"
|
|
||||||
#include "src/ast/statement.h"
|
|
||||||
#include "src/reader/wgsl/parser_impl.h"
|
#include "src/reader/wgsl/parser_impl.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
|
@ -30,46 +28,6 @@ TEST_F(ParserImplTest, ContinueStmt) {
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e, nullptr);
|
ASSERT_NE(e, nullptr);
|
||||||
ASSERT_TRUE(e->IsContinue());
|
ASSERT_TRUE(e->IsContinue());
|
||||||
EXPECT_EQ(e->condition(), ast::StatementCondition::kNone);
|
|
||||||
EXPECT_EQ(e->conditional(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, ContinueStmt_WithIf) {
|
|
||||||
auto* p = parser("continue if (a == b)");
|
|
||||||
auto e = p->continue_stmt();
|
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
|
||||||
ASSERT_NE(e, nullptr);
|
|
||||||
ASSERT_TRUE(e->IsContinue());
|
|
||||||
EXPECT_EQ(e->condition(), ast::StatementCondition::kIf);
|
|
||||||
ASSERT_NE(e->conditional(), nullptr);
|
|
||||||
EXPECT_TRUE(e->conditional()->IsBinary());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, ContinueStmt_WithUnless) {
|
|
||||||
auto* p = parser("continue unless (a == b)");
|
|
||||||
auto e = p->continue_stmt();
|
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
|
||||||
ASSERT_NE(e, nullptr);
|
|
||||||
ASSERT_TRUE(e->IsContinue());
|
|
||||||
EXPECT_EQ(e->condition(), ast::StatementCondition::kUnless);
|
|
||||||
ASSERT_NE(e->conditional(), nullptr);
|
|
||||||
EXPECT_TRUE(e->conditional()->IsBinary());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, ContinueStmt_InvalidRHS) {
|
|
||||||
auto* p = parser("continue if (a = b)");
|
|
||||||
auto e = p->continue_stmt();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(e, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:16: expected )");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, ContinueStmt_MissingRHS) {
|
|
||||||
auto* p = parser("continue if");
|
|
||||||
auto e = p->continue_stmt();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(e, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:12: expected (");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -197,20 +197,12 @@ TEST_F(ParserImplTest, Statement_Break) {
|
||||||
EXPECT_TRUE(e->IsBreak());
|
EXPECT_TRUE(e->IsBreak());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Statement_Break_Invalid) {
|
|
||||||
auto* p = parser("break if (a = b);");
|
|
||||||
auto e = p->statement();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(e, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:13: expected )");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Statement_Break_MissingSemicolon) {
|
TEST_F(ParserImplTest, Statement_Break_MissingSemicolon) {
|
||||||
auto* p = parser("break if (a == b)");
|
auto* p = parser("break");
|
||||||
auto e = p->statement();
|
auto e = p->statement();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(e, nullptr);
|
ASSERT_EQ(e, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:18: missing ;");
|
EXPECT_EQ(p->error(), "1:6: missing ;");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Statement_Continue) {
|
TEST_F(ParserImplTest, Statement_Continue) {
|
||||||
|
@ -221,20 +213,12 @@ TEST_F(ParserImplTest, Statement_Continue) {
|
||||||
EXPECT_TRUE(e->IsContinue());
|
EXPECT_TRUE(e->IsContinue());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Statement_Continue_Invalid) {
|
|
||||||
auto* p = parser("continue if (a = b);");
|
|
||||||
auto e = p->statement();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(e, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:16: expected )");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Statement_Continue_MissingSemicolon) {
|
TEST_F(ParserImplTest, Statement_Continue_MissingSemicolon) {
|
||||||
auto* p = parser("continue if (a == b)");
|
auto* p = parser("continue");
|
||||||
auto e = p->statement();
|
auto e = p->statement();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(e, nullptr);
|
ASSERT_EQ(e, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:21: missing ;");
|
EXPECT_EQ(p->error(), "1:9: missing ;");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Statement_Kill) {
|
TEST_F(ParserImplTest, Statement_Kill) {
|
||||||
|
|
|
@ -159,16 +159,14 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
||||||
return DetermineResultType(a->lhs()) && DetermineResultType(a->rhs());
|
return DetermineResultType(a->lhs()) && DetermineResultType(a->rhs());
|
||||||
}
|
}
|
||||||
if (stmt->IsBreak()) {
|
if (stmt->IsBreak()) {
|
||||||
auto* b = stmt->AsBreak();
|
return true;
|
||||||
return DetermineResultType(b->conditional());
|
|
||||||
}
|
}
|
||||||
if (stmt->IsCase()) {
|
if (stmt->IsCase()) {
|
||||||
auto* c = stmt->AsCase();
|
auto* c = stmt->AsCase();
|
||||||
return DetermineStatements(c->body());
|
return DetermineStatements(c->body());
|
||||||
}
|
}
|
||||||
if (stmt->IsContinue()) {
|
if (stmt->IsContinue()) {
|
||||||
auto* c = stmt->AsContinue();
|
return true;
|
||||||
return DetermineResultType(c->conditional());
|
|
||||||
}
|
}
|
||||||
if (stmt->IsElse()) {
|
if (stmt->IsElse()) {
|
||||||
auto* e = stmt->AsElse();
|
auto* e = stmt->AsElse();
|
||||||
|
|
|
@ -129,26 +129,6 @@ TEST_F(TypeDeterminerTest, Stmt_Assign) {
|
||||||
EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
|
EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TypeDeterminerTest, Stmt_Break) {
|
|
||||||
ast::type::I32Type i32;
|
|
||||||
|
|
||||||
auto cond = std::make_unique<ast::ScalarConstructorExpression>(
|
|
||||||
std::make_unique<ast::SintLiteral>(&i32, 2));
|
|
||||||
auto* cond_ptr = cond.get();
|
|
||||||
|
|
||||||
ast::BreakStatement brk(ast::StatementCondition::kIf, std::move(cond));
|
|
||||||
|
|
||||||
EXPECT_TRUE(td()->DetermineResultType(&brk));
|
|
||||||
ASSERT_NE(cond_ptr->result_type(), nullptr);
|
|
||||||
EXPECT_TRUE(cond_ptr->result_type()->IsI32());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TypeDeterminerTest, Stmt_Break_WithoutCondition) {
|
|
||||||
ast::type::I32Type i32;
|
|
||||||
ast::BreakStatement brk;
|
|
||||||
EXPECT_TRUE(td()->DetermineResultType(&brk));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TypeDeterminerTest, Stmt_Case) {
|
TEST_F(TypeDeterminerTest, Stmt_Case) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
|
@ -176,26 +156,6 @@ TEST_F(TypeDeterminerTest, Stmt_Case) {
|
||||||
EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
|
EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TypeDeterminerTest, Stmt_Continue) {
|
|
||||||
ast::type::I32Type i32;
|
|
||||||
|
|
||||||
auto cond = std::make_unique<ast::ScalarConstructorExpression>(
|
|
||||||
std::make_unique<ast::SintLiteral>(&i32, 2));
|
|
||||||
auto* cond_ptr = cond.get();
|
|
||||||
|
|
||||||
ast::ContinueStatement stmt(ast::StatementCondition::kIf, std::move(cond));
|
|
||||||
|
|
||||||
EXPECT_TRUE(td()->DetermineResultType(&stmt));
|
|
||||||
ASSERT_NE(cond_ptr->result_type(), nullptr);
|
|
||||||
EXPECT_TRUE(cond_ptr->result_type()->IsI32());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TypeDeterminerTest, Stmt_Continue_WithoutStatement) {
|
|
||||||
ast::type::I32Type i32;
|
|
||||||
ast::ContinueStatement stmt;
|
|
||||||
EXPECT_TRUE(td()->DetermineResultType(&stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TypeDeterminerTest, Stmt_Else) {
|
TEST_F(TypeDeterminerTest, Stmt_Else) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "src/ast/return_statement.h"
|
#include "src/ast/return_statement.h"
|
||||||
#include "src/ast/scalar_constructor_expression.h"
|
#include "src/ast/scalar_constructor_expression.h"
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
#include "src/ast/statement_condition.h"
|
|
||||||
#include "src/ast/type/bool_type.h"
|
#include "src/ast/type/bool_type.h"
|
||||||
#include "src/ast/type/i32_type.h"
|
#include "src/ast/type/i32_type.h"
|
||||||
#include "src/context.h"
|
#include "src/context.h"
|
||||||
|
@ -488,67 +487,6 @@ OpBranch %1
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is blocked on implementing conditional break
|
|
||||||
TEST_F(BuilderTest, DISABLED_If_WithConditionalBreak) {
|
|
||||||
ast::type::BoolType bool_type;
|
|
||||||
// loop {
|
|
||||||
// if (true) {
|
|
||||||
// break if (false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
auto cond_true = std::make_unique<ast::ScalarConstructorExpression>(
|
|
||||||
std::make_unique<ast::BoolLiteral>(&bool_type, true));
|
|
||||||
auto cond_false = std::make_unique<ast::ScalarConstructorExpression>(
|
|
||||||
std::make_unique<ast::BoolLiteral>(&bool_type, false));
|
|
||||||
|
|
||||||
ast::StatementList if_body;
|
|
||||||
if_body.push_back(std::make_unique<ast::BreakStatement>(
|
|
||||||
ast::StatementCondition::kIf, std::move(cond_false)));
|
|
||||||
|
|
||||||
auto if_stmt = std::make_unique<ast::IfStatement>(std::move(cond_true),
|
|
||||||
std::move(if_body));
|
|
||||||
|
|
||||||
ast::StatementList loop_body;
|
|
||||||
loop_body.push_back(std::move(if_stmt));
|
|
||||||
|
|
||||||
ast::LoopStatement expr(std::move(loop_body), {});
|
|
||||||
|
|
||||||
Context ctx;
|
|
||||||
ast::Module mod;
|
|
||||||
TypeDeterminer td(&ctx, &mod);
|
|
||||||
|
|
||||||
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
|
|
||||||
|
|
||||||
Builder b(&mod);
|
|
||||||
b.push_function(Function{});
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error();
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
|
|
||||||
%6 = OpConstantTrue %5
|
|
||||||
%7 = OpConstantFalse %5
|
|
||||||
)");
|
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
|
||||||
R"(OpBranch %1
|
|
||||||
%1 = OpLabel
|
|
||||||
OpLoopMerge %2 %3 None
|
|
||||||
OpBranch %4
|
|
||||||
%4 = OpLabel
|
|
||||||
OpSelectionMerge %8 None
|
|
||||||
OpBranchConditional %6 %9 %8
|
|
||||||
%9 = OpLabel
|
|
||||||
OpBranchConditional %7 %2 %8
|
|
||||||
%8 = OpLabel
|
|
||||||
OpBranch %3
|
|
||||||
%3 = OpLabel
|
|
||||||
OpBranch %1
|
|
||||||
%2 = OpLabel
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BuilderTest, DISABLED_If_WithElseConditionalBreak) {
|
|
||||||
FAIL();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BuilderTest, If_WithContinue) {
|
TEST_F(BuilderTest, If_WithContinue) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
// loop {
|
// loop {
|
||||||
|
@ -601,10 +539,6 @@ OpBranch %1
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, DISABLED_If_WithConditionalContinue) {
|
|
||||||
FAIL();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BuilderTest, If_WithElseContinue) {
|
TEST_F(BuilderTest, If_WithElseContinue) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
// loop {
|
// loop {
|
||||||
|
@ -666,10 +600,6 @@ OpBranch %1
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, DISABLED_If_WithElseConditionalContinue) {
|
|
||||||
FAIL();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BuilderTest, If_WithReturn) {
|
TEST_F(BuilderTest, If_WithReturn) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
// if (true) {
|
// if (true) {
|
||||||
|
|
|
@ -202,8 +202,6 @@ OpBranch %1
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, DISABLED_Loop_WithConditionalContinue) {}
|
|
||||||
|
|
||||||
TEST_F(BuilderTest, Loop_WithBreak) {
|
TEST_F(BuilderTest, Loop_WithBreak) {
|
||||||
// loop {
|
// loop {
|
||||||
// break;
|
// break;
|
||||||
|
@ -236,8 +234,6 @@ OpBranch %1
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, DISABLED_Loop_WithConditionalBreak) {}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
|
|
|
@ -472,16 +472,6 @@ TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) {
|
||||||
EXPECT_EQ(b.error(), "fallthrough of last case statement is disallowed");
|
EXPECT_EQ(b.error(), "fallthrough of last case statement is disallowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dsinclair): Implement when parsing is handled for multi-value
|
|
||||||
// case labels.
|
|
||||||
TEST_F(BuilderTest, DISABLED_Switch_CaseWithMulitpleLabels) {
|
|
||||||
// switch (a) {
|
|
||||||
// case 1, 2, 3:
|
|
||||||
// v = 1;
|
|
||||||
// }
|
|
||||||
FAIL();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BuilderTest, Switch_WithNestedBreak) {
|
TEST_F(BuilderTest, Switch_WithNestedBreak) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
|
|
|
@ -691,28 +691,9 @@ bool GeneratorImpl::EmitAssign(ast::AssignmentStatement* stmt) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitBreak(ast::BreakStatement* stmt) {
|
bool GeneratorImpl::EmitBreak(ast::BreakStatement*) {
|
||||||
make_indent();
|
make_indent();
|
||||||
|
out_ << "break;" << std::endl;
|
||||||
out_ << "break";
|
|
||||||
|
|
||||||
if (stmt->condition() != ast::StatementCondition::kNone) {
|
|
||||||
out_ << " ";
|
|
||||||
if (stmt->condition() == ast::StatementCondition::kIf) {
|
|
||||||
out_ << "if";
|
|
||||||
} else {
|
|
||||||
out_ << "unless";
|
|
||||||
}
|
|
||||||
|
|
||||||
out_ << " (";
|
|
||||||
if (!EmitExpression(stmt->conditional())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out_ << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
out_ << ";" << std::endl;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,28 +723,9 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
|
||||||
return EmitStatementBlockAndNewline(stmt->body());
|
return EmitStatementBlockAndNewline(stmt->body());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitContinue(ast::ContinueStatement* stmt) {
|
bool GeneratorImpl::EmitContinue(ast::ContinueStatement*) {
|
||||||
make_indent();
|
make_indent();
|
||||||
|
out_ << "continue;" << std::endl;
|
||||||
out_ << "continue";
|
|
||||||
|
|
||||||
if (stmt->condition() != ast::StatementCondition::kNone) {
|
|
||||||
out_ << " ";
|
|
||||||
if (stmt->condition() == ast::StatementCondition::kIf) {
|
|
||||||
out_ << "if";
|
|
||||||
} else {
|
|
||||||
out_ << "unless";
|
|
||||||
}
|
|
||||||
|
|
||||||
out_ << " (";
|
|
||||||
if (!EmitExpression(stmt->conditional())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out_ << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
out_ << ";" << std::endl;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/break_statement.h"
|
#include "src/ast/break_statement.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
|
||||||
#include "src/writer/wgsl/generator_impl.h"
|
#include "src/writer/wgsl/generator_impl.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -37,28 +36,6 @@ TEST_F(GeneratorImplTest, Emit_Break) {
|
||||||
EXPECT_EQ(g.result(), " break;\n");
|
EXPECT_EQ(g.result(), " break;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, Emit_BreakWithIf) {
|
|
||||||
auto expr = std::make_unique<ast::IdentifierExpression>("expr");
|
|
||||||
ast::BreakStatement b(ast::StatementCondition::kIf, std::move(expr));
|
|
||||||
|
|
||||||
GeneratorImpl g;
|
|
||||||
g.increment_indent();
|
|
||||||
|
|
||||||
ASSERT_TRUE(g.EmitStatement(&b)) << g.error();
|
|
||||||
EXPECT_EQ(g.result(), " break if (expr);\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, Emit_BreakWithUnless) {
|
|
||||||
auto expr = std::make_unique<ast::IdentifierExpression>("expr");
|
|
||||||
ast::BreakStatement b(ast::StatementCondition::kUnless, std::move(expr));
|
|
||||||
|
|
||||||
GeneratorImpl g;
|
|
||||||
g.increment_indent();
|
|
||||||
|
|
||||||
ASSERT_TRUE(g.EmitStatement(&b)) << g.error();
|
|
||||||
EXPECT_EQ(g.result(), " break unless (expr);\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace wgsl
|
} // namespace wgsl
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/identifier_expression.h"
|
|
||||||
#include "src/writer/wgsl/generator_impl.h"
|
#include "src/writer/wgsl/generator_impl.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -37,28 +36,6 @@ TEST_F(GeneratorImplTest, Emit_Continue) {
|
||||||
EXPECT_EQ(g.result(), " continue;\n");
|
EXPECT_EQ(g.result(), " continue;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, Emit_ContinueWithIf) {
|
|
||||||
auto expr = std::make_unique<ast::IdentifierExpression>("expr");
|
|
||||||
ast::ContinueStatement c(ast::StatementCondition::kIf, std::move(expr));
|
|
||||||
|
|
||||||
GeneratorImpl g;
|
|
||||||
g.increment_indent();
|
|
||||||
|
|
||||||
ASSERT_TRUE(g.EmitStatement(&c)) << g.error();
|
|
||||||
EXPECT_EQ(g.result(), " continue if (expr);\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, Emit_ContinueWithUnless) {
|
|
||||||
auto expr = std::make_unique<ast::IdentifierExpression>("expr");
|
|
||||||
ast::ContinueStatement c(ast::StatementCondition::kUnless, std::move(expr));
|
|
||||||
|
|
||||||
GeneratorImpl g;
|
|
||||||
g.increment_indent();
|
|
||||||
|
|
||||||
ASSERT_TRUE(g.EmitStatement(&c)) << g.error();
|
|
||||||
EXPECT_EQ(g.result(), " continue unless (expr);\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace wgsl
|
} // namespace wgsl
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
|
|
Loading…
Reference in New Issue