[hlsl-writer] Support pre stream in if/else statements.

This CL updates the if and else statement support to output the pre
streams in the proper places.

Bug: tint:192
Change-Id: If217de7f838fc033823987e20ba7efc5cd6108ff
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/27781
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-09-02 14:29:05 +00:00 committed by Commit Bot service account
parent b95fc538ed
commit a0842b50b9
3 changed files with 45 additions and 33 deletions

View File

@ -949,40 +949,53 @@ bool GeneratorImpl::EmitIf(std::ostream& out, ast::IfStatement* stmt) {
if (!EmitExpression(pre, cond, stmt->condition())) { if (!EmitExpression(pre, cond, stmt->condition())) {
return false; return false;
} }
out << pre.str();
out << "if (" << cond.str() << ") "; std::ostringstream if_out;
if (!EmitBlock(out, stmt->body())) { if_out << "if (" << cond.str() << ") ";
if (!EmitBlock(if_out, stmt->body())) {
return false; return false;
} }
// TODO(dsinclair): The else pre strings need to mix with the if pre
// strings correctly.
for (const auto& e : stmt->else_statements()) { for (const auto& e : stmt->else_statements()) {
if (!EmitElse(out, e.get())) { if (e->HasCondition()) {
if_out << " else {" << std::endl;
increment_indent();
std::ostringstream else_pre;
std::ostringstream else_cond_out;
if (!EmitExpression(else_pre, else_cond_out, e->condition())) {
return false;
}
if_out << else_pre.str();
make_indent(if_out);
if_out << "if (" << else_cond_out.str() << ") ";
} else {
if_out << " else ";
}
if (!EmitBlock(if_out, e->body())) {
return false; return false;
} }
} }
out << std::endl; if_out << std::endl;
for (const auto& e : stmt->else_statements()) {
if (!e->HasCondition()) {
continue;
}
decrement_indent();
make_indent(if_out);
if_out << "}" << std::endl;
}
out << pre.str();
out << if_out.str();
return true; return true;
} }
bool GeneratorImpl::EmitElse(std::ostream& out, ast::ElseStatement* stmt) {
// TODO(dsinclair): This has to work with the if pre string ....
std::ostringstream pre;
if (stmt->HasCondition()) {
out << " else if (";
if (!EmitExpression(pre, out, stmt->condition())) {
return false;
}
out << ") ";
} else {
out << " else ";
}
return EmitBlock(out, stmt->body());
}
bool GeneratorImpl::has_referenced_in_var_needing_struct(ast::Function* func) { bool GeneratorImpl::has_referenced_in_var_needing_struct(ast::Function* func) {
for (auto data : func->referenced_location_variables()) { for (auto data : func->referenced_location_variables()) {
auto* var = data.first; auto* var = data.first;

View File

@ -164,11 +164,6 @@ class GeneratorImpl {
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully /// @returns true if the statement was emitted successfully
bool EmitContinue(std::ostream& out, ast::ContinueStatement* stmt); bool EmitContinue(std::ostream& out, ast::ContinueStatement* stmt);
/// Handles generating an else statement
/// @param out the output stream
/// @param stmt the statement to emit
/// @returns true if the statement was emitted
bool EmitElse(std::ostream& out, ast::ElseStatement* stmt);
/// Handles generate an Expression /// Handles generate an Expression
/// @param pre the preamble for the expression stream /// @param pre the preamble for the expression stream
/// @param out the output of the expression stream /// @param out the output of the expression stream

View File

@ -62,8 +62,10 @@ TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElseIf) {
ASSERT_TRUE(gen().EmitStatement(out(), &i)) << gen().error(); ASSERT_TRUE(gen().EmitStatement(out(), &i)) << gen().error();
EXPECT_EQ(result(), R"( if (cond) { EXPECT_EQ(result(), R"( if (cond) {
return; return;
} else if (else_cond) { } else {
return; if (else_cond) {
return;
}
} }
)"); )");
} }
@ -119,10 +121,12 @@ TEST_F(HlslGeneratorImplTest_If, Emit_IfWithMultiple) {
ASSERT_TRUE(gen().EmitStatement(out(), &i)) << gen().error(); ASSERT_TRUE(gen().EmitStatement(out(), &i)) << gen().error();
EXPECT_EQ(result(), R"( if (cond) { EXPECT_EQ(result(), R"( if (cond) {
return; return;
} else if (else_cond) {
return;
} else { } else {
return; if (else_cond) {
return;
} else {
return;
}
} }
)"); )");
} }