[hlsl-writer] Emit pre strings
This Cl updates the various statements to emit any pre strings which are
generated when emitting the statements.
Bug: tint:192
Change-Id: Ieb2e621a500c5d91a0b6a2938eabe8e2ffdd11d1
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/27800
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 5f620c9..01cfe59 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -263,34 +263,38 @@
if (stmt->lhs()->IsMemberAccessor()) {
auto* mem = stmt->lhs()->AsMemberAccessor();
if (is_storage_buffer_access(mem)) {
- if (!EmitStorageBufferAccessor(pre, out, mem, stmt->rhs())) {
+ std::ostringstream accessor_out;
+ if (!EmitStorageBufferAccessor(pre, accessor_out, mem, stmt->rhs())) {
return false;
}
- out << ";" << std::endl;
+ out << pre.str();
+ out << accessor_out.str() << ";" << std::endl;
return true;
}
} else if (stmt->lhs()->IsArrayAccessor()) {
auto* ary = stmt->lhs()->AsArrayAccessor();
if (is_storage_buffer_access(ary)) {
- if (!EmitStorageBufferAccessor(pre, out, ary, stmt->rhs())) {
+ std::ostringstream accessor_out;
+ if (!EmitStorageBufferAccessor(pre, accessor_out, ary, stmt->rhs())) {
return false;
}
- out << ";" << std::endl;
+ out << pre.str();
+ out << accessor_out.str() << ";" << std::endl;
return true;
}
}
- if (!EmitExpression(pre, out, stmt->lhs())) {
+ std::ostringstream lhs_out;
+ if (!EmitExpression(pre, lhs_out, stmt->lhs())) {
+ return false;
+ }
+ std::ostringstream rhs_out;
+ if (!EmitExpression(pre, rhs_out, stmt->rhs())) {
return false;
}
- out << " = ";
-
- if (!EmitExpression(pre, out, stmt->rhs())) {
- return false;
- }
-
- out << ";" << std::endl;
+ out << pre.str();
+ out << lhs_out.str() << " = " << rhs_out.str() << ";" << std::endl;
return true;
}
@@ -941,16 +945,18 @@
make_indent(out);
std::ostringstream pre;
- out << "if (";
- if (!EmitExpression(pre, out, stmt->condition())) {
+ std::ostringstream cond;
+ if (!EmitExpression(pre, cond, stmt->condition())) {
return false;
}
- out << ") ";
-
+ out << pre.str();
+ out << "if (" << cond.str() << ") ";
if (!EmitBlock(out, stmt->body())) {
return false;
}
+ // TODO(dsinclair): The else pre strings need to mix with the if pre
+ // strings correctly.
for (const auto& e : stmt->else_statements()) {
if (!EmitElse(out, e.get())) {
return false;
@@ -962,6 +968,7 @@
}
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 (";
@@ -1529,12 +1536,19 @@
make_indent(out);
auto* var = s->AsVariableDecl()->variable();
- out << var->name() << " = ";
+
+ std::ostringstream pre;
+ std::ostringstream constructor_out;
if (var->constructor() != nullptr) {
- std::ostringstream pre;
- if (!EmitExpression(pre, out, var->constructor())) {
+ if (!EmitExpression(pre, constructor_out, var->constructor())) {
return false;
}
+ }
+ out << pre.str();
+
+ out << var->name() << " = ";
+ if (var->constructor() != nullptr) {
+ out << constructor_out.str();
} else {
if (!EmitZeroValue(out, var->type())) {
return false;
@@ -1564,6 +1578,7 @@
}
std::string GeneratorImpl::generate_storage_buffer_index_expression(
+ std::ostream& pre,
ast::Expression* expr) {
std::ostringstream out;
bool first = true;
@@ -1635,7 +1650,6 @@
return "";
}
out << " * ";
- std::ostringstream pre;
if (!EmitExpression(pre, out, ary->idx_expr())) {
return "";
}
@@ -1689,7 +1703,7 @@
return false;
}
- auto idx = generate_storage_buffer_index_expression(expr);
+ auto idx = generate_storage_buffer_index_expression(pre, expr);
if (idx.empty()) {
return false;
}
@@ -1829,19 +1843,22 @@
bool GeneratorImpl::EmitReturn(std::ostream& out, ast::ReturnStatement* stmt) {
make_indent(out);
- out << "return";
-
if (generating_entry_point_) {
+ out << "return";
auto outdata = ep_name_to_out_data_.find(current_ep_name_);
if (outdata != ep_name_to_out_data_.end()) {
out << " " << outdata->second.var_name;
}
} else if (stmt->has_value()) {
- out << " ";
std::ostringstream pre;
- if (!EmitExpression(pre, out, stmt->value())) {
+ std::ostringstream ret_out;
+ if (!EmitExpression(pre, ret_out, stmt->value())) {
return false;
}
+ out << pre.str();
+ out << "return " << ret_out.str();
+ } else {
+ out << "return";
}
out << ";" << std::endl;
return true;
@@ -1860,10 +1877,12 @@
if (stmt->IsCall()) {
make_indent(out);
std::ostringstream pre;
- if (!EmitCall(pre, out, stmt->AsCall()->expr())) {
+ std::ostringstream call_out;
+ if (!EmitCall(pre, call_out, stmt->AsCall()->expr())) {
return false;
}
- out << ";" << std::endl;
+ out << pre.str();
+ out << call_out.str() << ";" << std::endl;
return true;
}
if (stmt->IsContinue()) {
@@ -1901,11 +1920,13 @@
make_indent(out);
std::ostringstream pre;
- out << "switch(";
- if (!EmitExpression(pre, out, stmt->condition())) {
+ std::ostringstream cond;
+ if (!EmitExpression(pre, cond, stmt->condition())) {
return false;
}
- out << ") {" << std::endl;
+
+ out << pre.str();
+ out << "switch(" << cond.str() << ") {" << std::endl;
increment_indent();
@@ -2054,6 +2075,17 @@
return false;
}
+ std::ostringstream constructor_out;
+ if (!skip_constructor && var->constructor() != nullptr) {
+ constructor_out << " = ";
+
+ std::ostringstream pre;
+ if (!EmitExpression(pre, constructor_out, var->constructor())) {
+ return false;
+ }
+ out << pre.str();
+ }
+
if (var->is_const()) {
out << "const ";
}
@@ -2063,16 +2095,7 @@
if (!var->type()->IsArray()) {
out << " " << var->name();
}
-
- if (!skip_constructor && var->constructor() != nullptr) {
- out << " = ";
-
- std::ostringstream pre;
- if (!EmitExpression(pre, out, var->constructor())) {
- return false;
- }
- }
- out << ";" << std::endl;
+ out << constructor_out.str() << ";" << std::endl;
return true;
}
@@ -2090,6 +2113,17 @@
return false;
}
+ std::ostringstream constructor_out;
+ if (var->constructor() != nullptr) {
+ constructor_out << " = ";
+
+ std::ostringstream pre;
+ if (!EmitExpression(pre, constructor_out, var->constructor())) {
+ return false;
+ }
+ out << pre.str();
+ }
+
out << "static const ";
if (!EmitType(out, var->type(), var->name())) {
return false;
@@ -2097,16 +2131,7 @@
if (!var->type()->IsArray()) {
out << " " << var->name();
}
-
- if (var->constructor() != nullptr) {
- out << " = ";
-
- std::ostringstream pre;
- if (!EmitExpression(pre, out, var->constructor())) {
- return false;
- }
- }
- out << ";" << std::endl;
+ out << constructor_out.str() << ";" << std::endl;
return true;
}
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index 4c261f5..d4f9126 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -319,9 +319,11 @@
/// @returns true if the global is in an input or output struct
bool global_is_in_struct(ast::Variable* var) const;
/// Creates a text string representing the index into a storage buffer
+ /// @param pre the pre stream
/// @param expr the expression to use as the index
/// @returns the index string, or blank if unable to generate
- std::string generate_storage_buffer_index_expression(ast::Expression* expr);
+ std::string generate_storage_buffer_index_expression(std::ostream& pre,
+ ast::Expression* expr);
/// Generates a name for the prefix
/// @param prefix the prefix of the name to generate
/// @returns the name