Convert HLSL generator over to utils::StringStream.

This CL converts the HLSL generator to use utils::StringStream instead
of std::stringstream.

Bug: tint:1686
Change-Id: I69d4deec9b65bbcba6afe319cc1266879cd7c373
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121900
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
dan sinclair 2023-02-28 14:49:25 +00:00 committed by Dawn LUCI CQ
parent dba03d30fb
commit 2b9d5b338a
12 changed files with 184 additions and 163 deletions

View File

@ -75,6 +75,7 @@
#include "src/tint/utils/map.h" #include "src/tint/utils/map.h"
#include "src/tint/utils/scoped_assignment.h" #include "src/tint/utils/scoped_assignment.h"
#include "src/tint/utils/string.h" #include "src/tint/utils/string.h"
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/append_vector.h" #include "src/tint/writer/append_vector.h"
#include "src/tint/writer/check_supported_extensions.h" #include "src/tint/writer/check_supported_extensions.h"
#include "src/tint/writer/float_to_string.h" #include "src/tint/writer/float_to_string.h"
@ -114,7 +115,7 @@ const char* image_format_to_rwtexture_type(builtin::TexelFormat image_format) {
} }
} }
void PrintF32(std::ostream& out, float value) { void PrintF32(utils::StringStream& out, float value) {
if (std::isinf(value)) { if (std::isinf(value)) {
out << "0.0f " << (value >= 0 ? "/* inf */" : "/* -inf */"); out << "0.0f " << (value >= 0 ? "/* inf */" : "/* -inf */");
} else if (std::isnan(value)) { } else if (std::isnan(value)) {
@ -124,7 +125,7 @@ void PrintF32(std::ostream& out, float value) {
} }
} }
void PrintF16(std::ostream& out, float value) { void PrintF16(utils::StringStream& out, float value) {
if (std::isinf(value)) { if (std::isinf(value)) {
out << "0.0h " << (value >= 0 ? "/* inf */" : "/* -inf */"); out << "0.0h " << (value >= 0 ? "/* inf */" : "/* -inf */");
} else if (std::isnan(value)) { } else if (std::isnan(value)) {
@ -143,7 +144,7 @@ struct RegisterAndSpace {
sem::BindingPoint const binding_point; sem::BindingPoint const binding_point;
}; };
std::ostream& operator<<(std::ostream& s, const RegisterAndSpace& rs) { utils::StringStream& operator<<(utils::StringStream& s, const RegisterAndSpace& rs) {
s << " : register(" << rs.reg << rs.binding_point.binding << ", space" << rs.binding_point.group s << " : register(" << rs.reg << rs.binding_point.binding << ", space" << rs.binding_point.group
<< ")"; << ")";
return s; return s;
@ -377,7 +378,7 @@ bool GeneratorImpl::EmitDynamicVectorAssignment(const ast::AssignmentStatement*
auto name = utils::GetOrCreate(dynamic_vector_write_, vec, [&]() -> std::string { auto name = utils::GetOrCreate(dynamic_vector_write_, vec, [&]() -> std::string {
std::string fn; std::string fn;
{ {
std::ostringstream ss; utils::StringStream ss;
if (!EmitType(ss, vec, tint::builtin::AddressSpace::kUndefined, if (!EmitType(ss, vec, tint::builtin::AddressSpace::kUndefined,
builtin::Access::kUndefined, "")) { builtin::Access::kUndefined, "")) {
return ""; return "";
@ -451,7 +452,7 @@ bool GeneratorImpl::EmitDynamicMatrixVectorAssignment(const ast::AssignmentState
auto name = utils::GetOrCreate(dynamic_matrix_vector_write_, mat, [&]() -> std::string { auto name = utils::GetOrCreate(dynamic_matrix_vector_write_, mat, [&]() -> std::string {
std::string fn; std::string fn;
{ {
std::ostringstream ss; utils::StringStream ss;
if (!EmitType(ss, mat, tint::builtin::AddressSpace::kUndefined, if (!EmitType(ss, mat, tint::builtin::AddressSpace::kUndefined,
builtin::Access::kUndefined, "")) { builtin::Access::kUndefined, "")) {
return ""; return "";
@ -520,7 +521,7 @@ bool GeneratorImpl::EmitDynamicMatrixScalarAssignment(const ast::AssignmentState
auto name = utils::GetOrCreate(dynamic_matrix_scalar_write_, mat, [&]() -> std::string { auto name = utils::GetOrCreate(dynamic_matrix_scalar_write_, mat, [&]() -> std::string {
std::string fn; std::string fn;
{ {
std::ostringstream ss; utils::StringStream ss;
if (!EmitType(ss, mat, tint::builtin::AddressSpace::kUndefined, if (!EmitType(ss, mat, tint::builtin::AddressSpace::kUndefined,
builtin::Access::kUndefined, "")) { builtin::Access::kUndefined, "")) {
return ""; return "";
@ -616,7 +617,8 @@ bool GeneratorImpl::EmitDynamicMatrixScalarAssignment(const ast::AssignmentState
return true; return true;
} }
bool GeneratorImpl::EmitIndexAccessor(std::ostream& out, const ast::IndexAccessorExpression* expr) { bool GeneratorImpl::EmitIndexAccessor(utils::StringStream& out,
const ast::IndexAccessorExpression* expr) {
if (!EmitExpression(out, expr->object)) { if (!EmitExpression(out, expr->object)) {
return false; return false;
} }
@ -630,7 +632,7 @@ bool GeneratorImpl::EmitIndexAccessor(std::ostream& out, const ast::IndexAccesso
return true; return true;
} }
bool GeneratorImpl::EmitBitcast(std::ostream& out, const ast::BitcastExpression* expr) { bool GeneratorImpl::EmitBitcast(utils::StringStream& out, const ast::BitcastExpression* expr) {
auto* type = TypeOf(expr); auto* type = TypeOf(expr);
if (auto* vec = type->UnwrapRef()->As<type::Vector>()) { if (auto* vec = type->UnwrapRef()->As<type::Vector>()) {
type = vec->type(); type = vec->type();
@ -698,7 +700,7 @@ bool GeneratorImpl::EmitAssign(const ast::AssignmentStatement* stmt) {
return true; return true;
} }
bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* expr) { bool GeneratorImpl::EmitBinary(utils::StringStream& out, const ast::BinaryExpression* expr) {
if (expr->op == ast::BinaryOp::kLogicalAnd || expr->op == ast::BinaryOp::kLogicalOr) { if (expr->op == ast::BinaryOp::kLogicalAnd || expr->op == ast::BinaryOp::kLogicalOr) {
auto name = UniqueIdentifier(kTempNamePrefix); auto name = UniqueIdentifier(kTempNamePrefix);
@ -755,7 +757,7 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* e
return true; return true;
} }
ScopedParen sp(out); ScopedParen sp(out.stream());
if (!EmitExpression(out, expr->lhs)) { if (!EmitExpression(out, expr->lhs)) {
return false; return false;
@ -873,7 +875,7 @@ bool GeneratorImpl::EmitBreakIf(const ast::BreakIfStatement* b) {
return true; return true;
} }
bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) { bool GeneratorImpl::EmitCall(utils::StringStream& out, const ast::CallExpression* expr) {
auto* call = builder_.Sem().Get<sem::Call>(expr); auto* call = builder_.Sem().Get<sem::Call>(expr);
auto* target = call->Target(); auto* target = call->Target();
return Switch( return Switch(
@ -888,7 +890,7 @@ bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr)
}); });
} }
bool GeneratorImpl::EmitFunctionCall(std::ostream& out, bool GeneratorImpl::EmitFunctionCall(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::Function* func) { const sem::Function* func) {
auto* expr = call->Declaration(); auto* expr = call->Declaration();
@ -944,7 +946,7 @@ bool GeneratorImpl::EmitFunctionCall(std::ostream& out,
return true; return true;
} }
bool GeneratorImpl::EmitBuiltinCall(std::ostream& out, bool GeneratorImpl::EmitBuiltinCall(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
const auto type = builtin->Type(); const auto type = builtin->Type();
@ -1029,7 +1031,7 @@ bool GeneratorImpl::EmitBuiltinCall(std::ostream& out,
return true; return true;
} }
bool GeneratorImpl::EmitValueConversion(std::ostream& out, bool GeneratorImpl::EmitValueConversion(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::ValueConversion* conv) { const sem::ValueConversion* conv) {
if (!EmitType(out, conv->Target(), builtin::AddressSpace::kUndefined, if (!EmitType(out, conv->Target(), builtin::AddressSpace::kUndefined,
@ -1046,7 +1048,7 @@ bool GeneratorImpl::EmitValueConversion(std::ostream& out,
return true; return true;
} }
bool GeneratorImpl::EmitValueConstructor(std::ostream& out, bool GeneratorImpl::EmitValueConstructor(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::ValueConstructor* ctor) { const sem::ValueConstructor* ctor) {
auto* type = call->Type(); auto* type = call->Type();
@ -1110,7 +1112,7 @@ bool GeneratorImpl::EmitValueConstructor(std::ostream& out,
} }
bool GeneratorImpl::EmitUniformBufferAccess( bool GeneratorImpl::EmitUniformBufferAccess(
std::ostream& out, utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic) { const transform::DecomposeMemoryAccess::Intrinsic* intrinsic) {
auto const buffer = program_->Symbols().NameFor(intrinsic->buffer); auto const buffer = program_->Symbols().NameFor(intrinsic->buffer);
@ -1182,7 +1184,7 @@ bool GeneratorImpl::EmitUniformBufferAccess(
out << ")"; out << ")";
return result; return result;
}; };
auto load_u32_to = [&](std::ostream& target) { auto load_u32_to = [&](utils::StringStream& target) {
target << buffer; target << buffer;
if (scalar_offset_constant) { if (scalar_offset_constant) {
target << "[" << (scalar_offset_index / 4) << "]." target << "[" << (scalar_offset_index / 4) << "]."
@ -1195,7 +1197,7 @@ bool GeneratorImpl::EmitUniformBufferAccess(
}; };
auto load_u32 = [&] { return load_u32_to(out); }; auto load_u32 = [&] { return load_u32_to(out); };
// Has a minimum alignment of 8 bytes, so is either .xy or .zw // Has a minimum alignment of 8 bytes, so is either .xy or .zw
auto load_vec2_u32_to = [&](std::ostream& target) { auto load_vec2_u32_to = [&](utils::StringStream& target) {
if (scalar_offset_constant) { if (scalar_offset_constant) {
target << buffer << "[" << (scalar_offset_index / 4) << "]" target << buffer << "[" << (scalar_offset_index / 4) << "]"
<< ((scalar_offset_index & 2) == 0 ? ".xy" : ".zw"); << ((scalar_offset_index & 2) == 0 ? ".xy" : ".zw");
@ -1398,7 +1400,7 @@ bool GeneratorImpl::EmitUniformBufferAccess(
} }
bool GeneratorImpl::EmitStorageBufferAccess( bool GeneratorImpl::EmitStorageBufferAccess(
std::ostream& out, utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic) { const transform::DecomposeMemoryAccess::Intrinsic* intrinsic) {
auto const buffer = program_->Symbols().NameFor(intrinsic->buffer); auto const buffer = program_->Symbols().NameFor(intrinsic->buffer);
@ -1417,7 +1419,7 @@ bool GeneratorImpl::EmitStorageBufferAccess(
if (n > 1) { if (n > 1) {
out << n; out << n;
} }
ScopedParen sp(out); ScopedParen sp(out.stream());
if (!EmitExpression(out, offset)) { if (!EmitExpression(out, offset)) {
return false; return false;
} }
@ -1431,7 +1433,7 @@ bool GeneratorImpl::EmitStorageBufferAccess(
// to emit `buffer.Load<float16_t>(offset)`. // to emit `buffer.Load<float16_t>(offset)`.
auto templated_load = [&](const char* type) { auto templated_load = [&](const char* type) {
out << buffer << ".Load<" << type << ">"; // templated load out << buffer << ".Load<" << type << ">"; // templated load
ScopedParen sp(out); ScopedParen sp(out.stream());
if (!EmitExpression(out, offset)) { if (!EmitExpression(out, offset)) {
return false; return false;
} }
@ -1483,12 +1485,12 @@ bool GeneratorImpl::EmitStorageBufferAccess(
if (n > 1) { if (n > 1) {
out << n; out << n;
} }
ScopedParen sp1(out); ScopedParen sp1(out.stream());
if (!EmitExpression(out, offset)) { if (!EmitExpression(out, offset)) {
return false; return false;
} }
out << ", asuint"; out << ", asuint";
ScopedParen sp2(out); ScopedParen sp2(out.stream());
if (!EmitExpression(out, value)) { if (!EmitExpression(out, value)) {
return false; return false;
} }
@ -1499,7 +1501,7 @@ bool GeneratorImpl::EmitStorageBufferAccess(
// to emit `buffer.Store<float16_t>(offset)`. // to emit `buffer.Store<float16_t>(offset)`.
auto templated_store = [&](const char* type) { auto templated_store = [&](const char* type) {
out << buffer << ".Store<" << type << ">"; // templated store out << buffer << ".Store<" << type << ">"; // templated store
ScopedParen sp1(out); ScopedParen sp1(out.stream());
if (!EmitExpression(out, offset)) { if (!EmitExpression(out, offset)) {
return false; return false;
} }
@ -1763,7 +1765,7 @@ bool GeneratorImpl::EmitStorageAtomicIntrinsic(
return false; return false;
} }
bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out, bool GeneratorImpl::EmitWorkgroupAtomicCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
std::string result = UniqueIdentifier("atomic_result"); std::string result = UniqueIdentifier("atomic_result");
@ -1847,7 +1849,7 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
out << "InterlockedExchange"; out << "InterlockedExchange";
{ {
ScopedParen sp(out); ScopedParen sp(out.stream());
if (!EmitExpression(out, expr->args[0])) { if (!EmitExpression(out, expr->args[0])) {
return false; return false;
} }
@ -1938,11 +1940,11 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
return false; return false;
} }
bool GeneratorImpl::EmitSelectCall(std::ostream& out, const ast::CallExpression* expr) { bool GeneratorImpl::EmitSelectCall(utils::StringStream& out, const ast::CallExpression* expr) {
auto* expr_false = expr->args[0]; auto* expr_false = expr->args[0];
auto* expr_true = expr->args[1]; auto* expr_true = expr->args[1];
auto* expr_cond = expr->args[2]; auto* expr_cond = expr->args[2];
ScopedParen paren(out); ScopedParen paren(out.stream());
if (!EmitExpression(out, expr_cond)) { if (!EmitExpression(out, expr_cond)) {
return false; return false;
} }
@ -1962,7 +1964,7 @@ bool GeneratorImpl::EmitSelectCall(std::ostream& out, const ast::CallExpression*
return true; return true;
} }
bool GeneratorImpl::EmitModfCall(std::ostream& out, bool GeneratorImpl::EmitModfCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
return CallBuiltinHelper( return CallBuiltinHelper(
@ -1995,7 +1997,7 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitFrexpCall(std::ostream& out, bool GeneratorImpl::EmitFrexpCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
return CallBuiltinHelper( return CallBuiltinHelper(
@ -2036,7 +2038,7 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitDegreesCall(std::ostream& out, bool GeneratorImpl::EmitDegreesCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
return CallBuiltinHelper(out, expr, builtin, return CallBuiltinHelper(out, expr, builtin,
@ -2047,7 +2049,7 @@ bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitRadiansCall(std::ostream& out, bool GeneratorImpl::EmitRadiansCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
return CallBuiltinHelper(out, expr, builtin, return CallBuiltinHelper(out, expr, builtin,
@ -2061,7 +2063,9 @@ bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
// The HLSL `sign` method always returns an `int` result (scalar or vector). In WGSL the result is // The HLSL `sign` method always returns an `int` result (scalar or vector). In WGSL the result is
// expected to be the same type as the argument. This injects a cast to the expected WGSL result // expected to be the same type as the argument. This injects a cast to the expected WGSL result
// type after the call to `sign`. // type after the call to `sign`.
bool GeneratorImpl::EmitSignCall(std::ostream& out, const sem::Call* call, const sem::Builtin*) { bool GeneratorImpl::EmitSignCall(utils::StringStream& out,
const sem::Call* call,
const sem::Builtin*) {
auto* arg = call->Arguments()[0]; auto* arg = call->Arguments()[0];
if (!EmitType(out, arg->Type(), builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, if (!EmitType(out, arg->Type(), builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite,
"")) { "")) {
@ -2075,7 +2079,7 @@ bool GeneratorImpl::EmitSignCall(std::ostream& out, const sem::Call* call, const
return true; return true;
} }
bool GeneratorImpl::EmitQuantizeToF16Call(std::ostream& out, bool GeneratorImpl::EmitQuantizeToF16Call(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
// Emulate by casting to min16float and back again. // Emulate by casting to min16float and back again.
@ -2091,7 +2095,7 @@ bool GeneratorImpl::EmitQuantizeToF16Call(std::ostream& out,
return true; return true;
} }
bool GeneratorImpl::EmitDataPackingCall(std::ostream& out, bool GeneratorImpl::EmitDataPackingCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
return CallBuiltinHelper( return CallBuiltinHelper(
@ -2154,7 +2158,7 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out, bool GeneratorImpl::EmitDataUnpackingCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
return CallBuiltinHelper( return CallBuiltinHelper(
@ -2221,7 +2225,7 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitDP4aCall(std::ostream& out, bool GeneratorImpl::EmitDP4aCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
// TODO(crbug.com/tint/1497): support the polyfill version of DP4a functions. // TODO(crbug.com/tint/1497): support the polyfill version of DP4a functions.
@ -2249,7 +2253,7 @@ bool GeneratorImpl::EmitDP4aCall(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin) { bool GeneratorImpl::EmitBarrierCall(utils::StringStream& out, const sem::Builtin* builtin) {
// TODO(crbug.com/tint/661): Combine sequential barriers to a single // TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction. // instruction.
if (builtin->Type() == sem::BuiltinType::kWorkgroupBarrier) { if (builtin->Type() == sem::BuiltinType::kWorkgroupBarrier) {
@ -2264,7 +2268,7 @@ bool GeneratorImpl::EmitBarrierCall(std::ostream& out, const sem::Builtin* built
return true; return true;
} }
bool GeneratorImpl::EmitTextureCall(std::ostream& out, bool GeneratorImpl::EmitTextureCall(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::Builtin* builtin) { const sem::Builtin* builtin) {
using Usage = sem::ParameterUsage; using Usage = sem::ParameterUsage;
@ -2773,7 +2777,7 @@ bool GeneratorImpl::EmitDiscard(const ast::DiscardStatement*) {
return true; return true;
} }
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) { bool GeneratorImpl::EmitExpression(utils::StringStream& out, const ast::Expression* expr) {
if (auto* sem = builder_.Sem().GetVal(expr)) { if (auto* sem = builder_.Sem().GetVal(expr)) {
if (auto* constant = sem->ConstantValue()) { if (auto* constant = sem->ConstantValue()) {
bool is_variable_initializer = false; bool is_variable_initializer = false;
@ -2802,7 +2806,8 @@ bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* exp
}); });
} }
bool GeneratorImpl::EmitIdentifier(std::ostream& out, const ast::IdentifierExpression* expr) { bool GeneratorImpl::EmitIdentifier(utils::StringStream& out,
const ast::IdentifierExpression* expr) {
out << builder_.Symbols().NameFor(expr->identifier->symbol); out << builder_.Symbols().NameFor(expr->identifier->symbol);
return true; return true;
} }
@ -3276,7 +3281,7 @@ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) {
return true; return true;
} }
bool GeneratorImpl::EmitConstant(std::ostream& out, bool GeneratorImpl::EmitConstant(utils::StringStream& out,
const constant::Value* constant, const constant::Value* constant,
bool is_variable_initializer) { bool is_variable_initializer) {
return Switch( return Switch(
@ -3307,7 +3312,7 @@ bool GeneratorImpl::EmitConstant(std::ostream& out,
[&](const type::Vector* v) { [&](const type::Vector* v) {
if (constant->AllEqual()) { if (constant->AllEqual()) {
{ {
ScopedParen sp(out); ScopedParen sp(out.stream());
if (!EmitConstant(out, constant->Index(0), is_variable_initializer)) { if (!EmitConstant(out, constant->Index(0), is_variable_initializer)) {
return false; return false;
} }
@ -3324,7 +3329,7 @@ bool GeneratorImpl::EmitConstant(std::ostream& out,
return false; return false;
} }
ScopedParen sp(out); ScopedParen sp(out.stream());
for (size_t i = 0; i < v->Width(); i++) { for (size_t i = 0; i < v->Width(); i++) {
if (i > 0) { if (i > 0) {
@ -3342,7 +3347,7 @@ bool GeneratorImpl::EmitConstant(std::ostream& out,
return false; return false;
} }
ScopedParen sp(out); ScopedParen sp(out.stream());
for (size_t i = 0; i < m->columns(); i++) { for (size_t i = 0; i < m->columns(); i++) {
if (i > 0) { if (i > 0) {
@ -3396,7 +3401,7 @@ bool GeneratorImpl::EmitConstant(std::ostream& out,
return true; return true;
} }
auto emit_member_values = [&](std::ostream& o) { auto emit_member_values = [&](utils::StringStream& o) {
o << "{"; o << "{";
for (size_t i = 0; i < s->Members().Length(); i++) { for (size_t i = 0; i < s->Members().Length(); i++) {
if (i > 0) { if (i > 0) {
@ -3438,7 +3443,7 @@ bool GeneratorImpl::EmitConstant(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit) { bool GeneratorImpl::EmitLiteral(utils::StringStream& out, const ast::LiteralExpression* lit) {
return Switch( return Switch(
lit, lit,
[&](const ast::BoolLiteralExpression* l) { [&](const ast::BoolLiteralExpression* l) {
@ -3474,7 +3479,7 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression*
}); });
} }
bool GeneratorImpl::EmitValue(std::ostream& out, const type::Type* type, int value) { bool GeneratorImpl::EmitValue(utils::StringStream& out, const type::Type* type, int value) {
return Switch( return Switch(
type, type,
[&](const type::Bool*) { [&](const type::Bool*) {
@ -3502,7 +3507,7 @@ bool GeneratorImpl::EmitValue(std::ostream& out, const type::Type* type, int val
"")) { "")) {
return false; return false;
} }
ScopedParen sp(out); ScopedParen sp(out.stream());
for (uint32_t i = 0; i < vec->Width(); i++) { for (uint32_t i = 0; i < vec->Width(); i++) {
if (i != 0) { if (i != 0) {
out << ", "; out << ", ";
@ -3518,7 +3523,7 @@ bool GeneratorImpl::EmitValue(std::ostream& out, const type::Type* type, int val
"")) { "")) {
return false; return false;
} }
ScopedParen sp(out); ScopedParen sp(out.stream());
for (uint32_t i = 0; i < (mat->rows() * mat->columns()); i++) { for (uint32_t i = 0; i < (mat->rows() * mat->columns()); i++) {
if (i != 0) { if (i != 0) {
out << ", "; out << ", ";
@ -3549,7 +3554,7 @@ bool GeneratorImpl::EmitValue(std::ostream& out, const type::Type* type, int val
}); });
} }
bool GeneratorImpl::EmitZeroValue(std::ostream& out, const type::Type* type) { bool GeneratorImpl::EmitZeroValue(utils::StringStream& out, const type::Type* type) {
return EmitValue(out, type, 0); return EmitValue(out, type, 0);
} }
@ -3598,7 +3603,7 @@ bool GeneratorImpl::EmitForLoop(const ast::ForLoopStatement* stmt) {
} }
TextBuffer cond_pre; TextBuffer cond_pre;
std::stringstream cond_buf; utils::StringStream cond_buf;
if (auto* cond = stmt->condition) { if (auto* cond = stmt->condition) {
TINT_SCOPED_ASSIGNMENT(current_buffer_, &cond_pre); TINT_SCOPED_ASSIGNMENT(current_buffer_, &cond_pre);
if (!EmitExpression(cond_buf, cond)) { if (!EmitExpression(cond_buf, cond)) {
@ -3690,7 +3695,7 @@ bool GeneratorImpl::EmitForLoop(const ast::ForLoopStatement* stmt) {
bool GeneratorImpl::EmitWhile(const ast::WhileStatement* stmt) { bool GeneratorImpl::EmitWhile(const ast::WhileStatement* stmt) {
TextBuffer cond_pre; TextBuffer cond_pre;
std::stringstream cond_buf; utils::StringStream cond_buf;
{ {
auto* cond = stmt->condition; auto* cond = stmt->condition;
TINT_SCOPED_ASSIGNMENT(current_buffer_, &cond_pre); TINT_SCOPED_ASSIGNMENT(current_buffer_, &cond_pre);
@ -3738,7 +3743,7 @@ bool GeneratorImpl::EmitWhile(const ast::WhileStatement* stmt) {
return true; return true;
} }
bool GeneratorImpl::EmitMemberAccessor(std::ostream& out, bool GeneratorImpl::EmitMemberAccessor(utils::StringStream& out,
const ast::MemberAccessorExpression* expr) { const ast::MemberAccessorExpression* expr) {
if (!EmitExpression(out, expr->object)) { if (!EmitExpression(out, expr->object)) {
return false; return false;
@ -3911,7 +3916,7 @@ bool GeneratorImpl::EmitSwitch(const ast::SwitchStatement* stmt) {
return true; return true;
} }
bool GeneratorImpl::EmitType(std::ostream& out, bool GeneratorImpl::EmitType(utils::StringStream& out,
const type::Type* type, const type::Type* type,
builtin::AddressSpace address_space, builtin::AddressSpace address_space,
builtin::Access access, builtin::Access access,
@ -4138,7 +4143,7 @@ bool GeneratorImpl::EmitType(std::ostream& out,
}); });
} }
bool GeneratorImpl::EmitTypeAndName(std::ostream& out, bool GeneratorImpl::EmitTypeAndName(utils::StringStream& out,
const type::Type* type, const type::Type* type,
builtin::AddressSpace address_space, builtin::AddressSpace address_space,
builtin::Access access, builtin::Access access,
@ -4249,7 +4254,7 @@ bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
return true; return true;
} }
bool GeneratorImpl::EmitUnaryOp(std::ostream& out, const ast::UnaryOpExpression* expr) { bool GeneratorImpl::EmitUnaryOp(utils::StringStream& out, const ast::UnaryOpExpression* expr) {
switch (expr->op) { switch (expr->op) {
case ast::UnaryOp::kIndirection: case ast::UnaryOp::kIndirection:
case ast::UnaryOp::kAddressOf: case ast::UnaryOp::kAddressOf:
@ -4321,7 +4326,7 @@ bool GeneratorImpl::EmitLet(const ast::Let* let) {
} }
template <typename F> template <typename F>
bool GeneratorImpl::CallBuiltinHelper(std::ostream& out, bool GeneratorImpl::CallBuiltinHelper(utils::StringStream& out,
const ast::CallExpression* call, const ast::CallExpression* call,
const sem::Builtin* builtin, const sem::Builtin* builtin,
F&& build) { F&& build) {
@ -4377,7 +4382,7 @@ bool GeneratorImpl::CallBuiltinHelper(std::ostream& out,
// Call the helper // Call the helper
out << fn; out << fn;
{ {
ScopedParen sp(out); ScopedParen sp(out.stream());
bool first = true; bool first = true;
for (auto* arg : call->args) { for (auto* arg : call->args) {
if (!first) { if (!first) {

View File

@ -88,7 +88,7 @@ class GeneratorImpl : public TextGenerator {
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the expression to emit /// @param expr the expression to emit
/// @returns true if the index accessor was emitted /// @returns true if the index accessor was emitted
bool EmitIndexAccessor(std::ostream& out, const ast::IndexAccessorExpression* expr); bool EmitIndexAccessor(utils::StringStream& out, const ast::IndexAccessorExpression* expr);
/// Handles an assignment statement /// Handles an assignment statement
/// @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
@ -97,12 +97,12 @@ class GeneratorImpl : public TextGenerator {
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the binary expression /// @param expr the binary expression
/// @returns true if the expression was emitted, false otherwise /// @returns true if the expression was emitted, false otherwise
bool EmitBinary(std::ostream& out, const ast::BinaryExpression* expr); bool EmitBinary(utils::StringStream& out, const ast::BinaryExpression* expr);
/// Handles generating a bitcast expression /// Handles generating a bitcast expression
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the as expression /// @param expr the as expression
/// @returns true if the bitcast was emitted /// @returns true if the bitcast was emitted
bool EmitBitcast(std::ostream& out, const ast::BitcastExpression* expr); bool EmitBitcast(utils::StringStream& out, const ast::BitcastExpression* expr);
/// Emits a list of statements /// Emits a list of statements
/// @param stmts the statement list /// @param stmts the statement list
/// @returns true if the statements were emitted successfully /// @returns true if the statements were emitted successfully
@ -127,25 +127,29 @@ class GeneratorImpl : public TextGenerator {
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the call expression /// @param expr the call expression
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitCall(std::ostream& out, const ast::CallExpression* expr); bool EmitCall(utils::StringStream& out, const ast::CallExpression* expr);
/// Handles generating a function call expression /// Handles generating a function call expression
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param call the call expression /// @param call the call expression
/// @param function the function being called /// @param function the function being called
/// @returns true if the expression is emitted /// @returns true if the expression is emitted
bool EmitFunctionCall(std::ostream& out, const sem::Call* call, const sem::Function* function); bool EmitFunctionCall(utils::StringStream& out,
const sem::Call* call,
const sem::Function* function);
/// Handles generating a builtin call expression /// Handles generating a builtin call expression
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param call the call expression /// @param call the call expression
/// @param builtin the builtin being called /// @param builtin the builtin being called
/// @returns true if the expression is emitted /// @returns true if the expression is emitted
bool EmitBuiltinCall(std::ostream& out, const sem::Call* call, const sem::Builtin* builtin); bool EmitBuiltinCall(utils::StringStream& out,
const sem::Call* call,
const sem::Builtin* builtin);
/// Handles generating a value conversion expression /// Handles generating a value conversion expression
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param call the call expression /// @param call the call expression
/// @param conv the value conversion /// @param conv the value conversion
/// @returns true if the expression is emitted /// @returns true if the expression is emitted
bool EmitValueConversion(std::ostream& out, bool EmitValueConversion(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::ValueConversion* conv); const sem::ValueConversion* conv);
/// Handles generating a value constructor expression /// Handles generating a value constructor expression
@ -153,7 +157,7 @@ class GeneratorImpl : public TextGenerator {
/// @param call the call expression /// @param call the call expression
/// @param ctor the value constructor /// @param ctor the value constructor
/// @returns true if the expression is emitted /// @returns true if the expression is emitted
bool EmitValueConstructor(std::ostream& out, bool EmitValueConstructor(utils::StringStream& out,
const sem::Call* call, const sem::Call* call,
const sem::ValueConstructor* ctor); const sem::ValueConstructor* ctor);
/// Handles generating a call expression to a /// Handles generating a call expression to a
@ -162,7 +166,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param intrinsic the transform::DecomposeMemoryAccess::Intrinsic /// @param intrinsic the transform::DecomposeMemoryAccess::Intrinsic
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitUniformBufferAccess(std::ostream& out, bool EmitUniformBufferAccess(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic); const transform::DecomposeMemoryAccess::Intrinsic* intrinsic);
/// Handles generating a call expression to a /// Handles generating a call expression to a
@ -171,20 +175,20 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param intrinsic the transform::DecomposeMemoryAccess::Intrinsic /// @param intrinsic the transform::DecomposeMemoryAccess::Intrinsic
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitStorageBufferAccess(std::ostream& out, bool EmitStorageBufferAccess(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic); const transform::DecomposeMemoryAccess::Intrinsic* intrinsic);
/// Handles generating a barrier intrinsic call /// Handles generating a barrier intrinsic call
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param builtin the semantic information for the barrier builtin /// @param builtin the semantic information for the barrier builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin); bool EmitBarrierCall(utils::StringStream& out, const sem::Builtin* builtin);
/// Handles generating an atomic intrinsic call for a storage buffer variable /// Handles generating an atomic intrinsic call for a storage buffer variable
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the call expression /// @param expr the call expression
/// @param intrinsic the atomic intrinsic /// @param intrinsic the atomic intrinsic
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitStorageAtomicCall(std::ostream& out, bool EmitStorageAtomicCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic); const transform::DecomposeMemoryAccess::Intrinsic* intrinsic);
/// Handles generating the helper function for the atomic intrinsic function /// Handles generating the helper function for the atomic intrinsic function
@ -198,7 +202,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the atomic builtin /// @param builtin the semantic information for the atomic builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitWorkgroupAtomicCall(std::ostream& out, bool EmitWorkgroupAtomicCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to a texture function (`textureSample`, /// Handles generating a call to a texture function (`textureSample`,
@ -207,18 +211,20 @@ class GeneratorImpl : public TextGenerator {
/// @param call the call expression /// @param call the call expression
/// @param builtin the semantic information for the texture builtin /// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitTextureCall(std::ostream& out, const sem::Call* call, const sem::Builtin* builtin); bool EmitTextureCall(utils::StringStream& out,
const sem::Call* call,
const sem::Builtin* builtin);
/// Handles generating a call to the `select()` builtin /// Handles generating a call to the `select()` builtin
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the call expression /// @param expr the call expression
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitSelectCall(std::ostream& out, const ast::CallExpression* expr); bool EmitSelectCall(utils::StringStream& out, const ast::CallExpression* expr);
/// Handles generating a call to the `modf()` builtin /// Handles generating a call to the `modf()` builtin
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitModfCall(std::ostream& out, bool EmitModfCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to the `frexp()` builtin /// Handles generating a call to the `frexp()` builtin
@ -226,7 +232,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitFrexpCall(std::ostream& out, bool EmitFrexpCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to the `degrees()` builtin /// Handles generating a call to the `degrees()` builtin
@ -234,7 +240,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitDegreesCall(std::ostream& out, bool EmitDegreesCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to the `radians()` builtin /// Handles generating a call to the `radians()` builtin
@ -242,7 +248,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitRadiansCall(std::ostream& out, bool EmitRadiansCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to the `sign()` builtin /// Handles generating a call to the `sign()` builtin
@ -250,13 +256,13 @@ class GeneratorImpl : public TextGenerator {
/// @param call the call semantic node /// @param call the call semantic node
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitSignCall(std::ostream& out, const sem::Call* call, const sem::Builtin* builtin); bool EmitSignCall(utils::StringStream& out, const sem::Call* call, const sem::Builtin* builtin);
/// Handles generating a call to data packing builtin /// Handles generating a call to data packing builtin
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitDataPackingCall(std::ostream& out, bool EmitDataPackingCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to data unpacking builtin /// Handles generating a call to data unpacking builtin
@ -264,7 +270,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitDataUnpackingCall(std::ostream& out, bool EmitDataUnpackingCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to the `quantizeToF16()` intrinsic /// Handles generating a call to the `quantizeToF16()` intrinsic
@ -272,7 +278,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitQuantizeToF16Call(std::ostream& out, bool EmitQuantizeToF16Call(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles generating a call to DP4a builtins (dot4I8Packed and dot4U8Packed) /// Handles generating a call to DP4a builtins (dot4I8Packed and dot4U8Packed)
@ -280,7 +286,7 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression /// @param expr the call expression
/// @param builtin the semantic information for the builtin /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
bool EmitDP4aCall(std::ostream& out, bool EmitDP4aCall(utils::StringStream& out,
const ast::CallExpression* expr, const ast::CallExpression* expr,
const sem::Builtin* builtin); const sem::Builtin* builtin);
/// Handles a case statement /// Handles a case statement
@ -300,7 +306,7 @@ class GeneratorImpl : public TextGenerator {
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the expression /// @param expr the expression
/// @returns true if the expression was emitted /// @returns true if the expression was emitted
bool EmitExpression(std::ostream& out, const ast::Expression* expr); bool EmitExpression(utils::StringStream& out, const ast::Expression* expr);
/// Handles generating a function /// Handles generating a function
/// @param func the function to generate /// @param func the function to generate
/// @returns true if the function was emitted /// @returns true if the function was emitted
@ -357,14 +363,14 @@ class GeneratorImpl : public TextGenerator {
/// @param is_variable_initializer true if the constant is used as the RHS of a variable /// @param is_variable_initializer true if the constant is used as the RHS of a variable
/// initializer /// initializer
/// @returns true if the constant value was successfully emitted /// @returns true if the constant value was successfully emitted
bool EmitConstant(std::ostream& out, bool EmitConstant(utils::StringStream& out,
const constant::Value* constant, const constant::Value* constant,
bool is_variable_initializer); bool is_variable_initializer);
/// Handles a literal /// Handles a literal
/// @param out the output stream /// @param out the output stream
/// @param lit the literal to emit /// @param lit the literal to emit
/// @returns true if the literal was successfully emitted /// @returns true if the literal was successfully emitted
bool EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit); bool EmitLiteral(utils::StringStream& out, const ast::LiteralExpression* lit);
/// Handles a loop statement /// Handles a loop statement
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was emitted /// @returns true if the statement was emitted
@ -381,12 +387,12 @@ class GeneratorImpl : public TextGenerator {
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the identifier expression /// @param expr the identifier expression
/// @returns true if the identifeir was emitted /// @returns true if the identifeir was emitted
bool EmitIdentifier(std::ostream& out, const ast::IdentifierExpression* expr); bool EmitIdentifier(utils::StringStream& out, const ast::IdentifierExpression* expr);
/// Handles a member accessor expression /// Handles a member accessor expression
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the member accessor expression /// @param expr the member accessor expression
/// @returns true if the member accessor was emitted /// @returns true if the member accessor was emitted
bool EmitMemberAccessor(std::ostream& out, const ast::MemberAccessorExpression* expr); bool EmitMemberAccessor(utils::StringStream& out, const ast::MemberAccessorExpression* expr);
/// Handles return statements /// Handles return statements
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was successfully emitted /// @returns true if the statement was successfully emitted
@ -412,7 +418,7 @@ class GeneratorImpl : public TextGenerator {
/// @param name_printed (optional) if not nullptr and an array was printed /// @param name_printed (optional) if not nullptr and an array was printed
/// then the boolean is set to true. /// then the boolean is set to true.
/// @returns true if the type is emitted /// @returns true if the type is emitted
bool EmitType(std::ostream& out, bool EmitType(utils::StringStream& out,
const type::Type* type, const type::Type* type,
builtin::AddressSpace address_space, builtin::AddressSpace address_space,
builtin::Access access, builtin::Access access,
@ -425,7 +431,7 @@ class GeneratorImpl : public TextGenerator {
/// @param access the access control type of the variable /// @param access the access control type of the variable
/// @param name the name to emit /// @param name the name to emit
/// @returns true if the type is emitted /// @returns true if the type is emitted
bool EmitTypeAndName(std::ostream& out, bool EmitTypeAndName(utils::StringStream& out,
const type::Type* type, const type::Type* type,
builtin::AddressSpace address_space, builtin::AddressSpace address_space,
builtin::Access access, builtin::Access access,
@ -440,18 +446,18 @@ class GeneratorImpl : public TextGenerator {
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the expression to emit /// @param expr the expression to emit
/// @returns true if the expression was emitted /// @returns true if the expression was emitted
bool EmitUnaryOp(std::ostream& out, const ast::UnaryOpExpression* expr); bool EmitUnaryOp(utils::StringStream& out, const ast::UnaryOpExpression* expr);
/// Emits `value` for the given type /// Emits `value` for the given type
/// @param out the output stream /// @param out the output stream
/// @param type the type to emit the value for /// @param type the type to emit the value for
/// @param value the value to emit /// @param value the value to emit
/// @returns true if the value was successfully emitted. /// @returns true if the value was successfully emitted.
bool EmitValue(std::ostream& out, const type::Type* type, int value); bool EmitValue(utils::StringStream& out, const type::Type* type, int value);
/// Emits the zero value for the given type /// Emits the zero value for the given type
/// @param out the output stream /// @param out the output stream
/// @param type the type to emit the value for /// @param type the type to emit the value for
/// @returns true if the zero value was successfully emitted. /// @returns true if the zero value was successfully emitted.
bool EmitZeroValue(std::ostream& out, const type::Type* type); bool EmitZeroValue(utils::StringStream& out, const type::Type* type);
/// Handles generating a 'var' declaration /// Handles generating a 'var' declaration
/// @param var the variable to generate /// @param var the variable to generate
/// @returns true if the variable was emitted /// @returns true if the variable was emitted
@ -541,7 +547,7 @@ class GeneratorImpl : public TextGenerator {
/// `params` is the name of all the generated function parameters /// `params` is the name of all the generated function parameters
/// @returns true if the call expression is emitted /// @returns true if the call expression is emitted
template <typename F> template <typename F>
bool CallBuiltinHelper(std::ostream& out, bool CallBuiltinHelper(utils::StringStream& out,
const ast::CallExpression* call, const ast::CallExpression* call,
const sem::Builtin* builtin, const sem::Builtin* builtin,
F&& build); F&& build);

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
@ -28,7 +29,7 @@ TEST_F(HlslGeneratorImplTest_Expression, IndexAccessor) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "ary[5]"); EXPECT_EQ(out.str(), "ary[5]");
} }

View File

@ -14,6 +14,7 @@
#include "src/tint/ast/call_statement.h" #include "src/tint/ast/call_statement.h"
#include "src/tint/ast/variable_decl_statement.h" #include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
@ -62,7 +63,7 @@ TEST_P(HlslBinaryTest, Emit_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), params.result); EXPECT_EQ(out.str(), params.result);
} }
@ -94,7 +95,7 @@ TEST_P(HlslBinaryTest, Emit_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), params.result); EXPECT_EQ(out.str(), params.result);
} }
@ -117,7 +118,7 @@ TEST_P(HlslBinaryTest, Emit_u32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), params.result); EXPECT_EQ(out.str(), params.result);
} }
@ -145,7 +146,7 @@ TEST_P(HlslBinaryTest, Emit_i32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), params.result); EXPECT_EQ(out.str(), params.result);
} }
@ -182,7 +183,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorScalar_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(1.0f).xxx"); EXPECT_EQ(out.str(), "(1.0f).xxx");
} }
@ -199,7 +200,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorScalar_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(float16_t(1.0h)).xxx"); EXPECT_EQ(out.str(), "(float16_t(1.0h)).xxx");
} }
@ -214,7 +215,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarVector_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(1.0f).xxx"); EXPECT_EQ(out.str(), "(1.0f).xxx");
} }
@ -231,7 +232,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarVector_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(float16_t(1.0h)).xxx"); EXPECT_EQ(out.str(), "(float16_t(1.0h)).xxx");
} }
@ -246,7 +247,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(mat * 1.0f)"); EXPECT_EQ(out.str(), "(mat * 1.0f)");
} }
@ -263,7 +264,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(mat * float16_t(1.0h))"); EXPECT_EQ(out.str(), "(mat * float16_t(1.0h))");
} }
@ -278,7 +279,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(1.0f * mat)"); EXPECT_EQ(out.str(), "(1.0f * mat)");
} }
@ -295,7 +296,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(float16_t(1.0h) * mat)"); EXPECT_EQ(out.str(), "(float16_t(1.0h) * mat)");
} }
@ -310,7 +311,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "mul((1.0f).xxx, mat)"); EXPECT_EQ(out.str(), "mul((1.0f).xxx, mat)");
} }
@ -327,7 +328,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "mul((float16_t(1.0h)).xxx, mat)"); EXPECT_EQ(out.str(), "mul((float16_t(1.0h)).xxx, mat)");
} }
@ -342,7 +343,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "mul(mat, (1.0f).xxx)"); EXPECT_EQ(out.str(), "mul(mat, (1.0f).xxx)");
} }
@ -359,7 +360,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "mul(mat, (float16_t(1.0h)).xxx)"); EXPECT_EQ(out.str(), "mul(mat, (float16_t(1.0h)).xxx)");
} }
@ -373,7 +374,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "mul(rhs, lhs)"); EXPECT_EQ(out.str(), "mul(rhs, lhs)");
} }
@ -389,7 +390,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "mul(rhs, lhs)"); EXPECT_EQ(out.str(), "mul(rhs, lhs)");
} }
@ -403,7 +404,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Logical_And) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(tint_tmp)"); EXPECT_EQ(out.str(), "(tint_tmp)");
EXPECT_EQ(gen.result(), R"(bool tint_tmp = a; EXPECT_EQ(gen.result(), R"(bool tint_tmp = a;
@ -428,7 +429,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Logical_Multi) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(tint_tmp)"); EXPECT_EQ(out.str(), "(tint_tmp)");
EXPECT_EQ(gen.result(), R"(bool tint_tmp_1 = a; EXPECT_EQ(gen.result(), R"(bool tint_tmp_1 = a;
@ -455,7 +456,7 @@ TEST_F(HlslGeneratorImplTest_Binary, Logical_Or) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
EXPECT_EQ(out.str(), "(tint_tmp)"); EXPECT_EQ(out.str(), "(tint_tmp)");
EXPECT_EQ(gen.result(), R"(bool tint_tmp = a; EXPECT_EQ(gen.result(), R"(bool tint_tmp = a;

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
@ -28,7 +29,7 @@ TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Float) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
EXPECT_EQ(out.str(), "asfloat(a)"); EXPECT_EQ(out.str(), "asfloat(a)");
} }
@ -40,7 +41,7 @@ TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Int) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
EXPECT_EQ(out.str(), "asint(a)"); EXPECT_EQ(out.str(), "asint(a)");
} }
@ -52,7 +53,7 @@ TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Uint) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
EXPECT_EQ(out.str(), "asuint(a)"); EXPECT_EQ(out.str(), "asuint(a)");
} }

View File

@ -16,6 +16,7 @@
#include "src/tint/ast/call_statement.h" #include "src/tint/ast/call_statement.h"
#include "src/tint/ast/stage_attribute.h" #include "src/tint/ast/stage_attribute.h"
#include "src/tint/sem/call.h" #include "src/tint/sem/call.h"
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using ::testing::HasSubstr; using ::testing::HasSubstr;
@ -64,8 +65,8 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
CallParamType type, CallParamType type,
ProgramBuilder* builder) { ProgramBuilder* builder) {
std::string name; std::string name;
std::ostringstream str(name); utils::StringStream str;
str << builtin; str << name << builtin;
switch (builtin) { switch (builtin) {
case BuiltinType::kAcos: case BuiltinType::kAcos:
case BuiltinType::kAsin: case BuiltinType::kAsin:
@ -347,7 +348,7 @@ TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
EXPECT_EQ(out.str(), "dot(param1, param2)"); EXPECT_EQ(out.str(), "dot(param1, param2)");
} }
@ -360,7 +361,7 @@ TEST_F(HlslGeneratorImplTest_Builtin, Select_Scalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
EXPECT_EQ(out.str(), "(true ? b : a)"); EXPECT_EQ(out.str(), "(true ? b : a)");
} }
@ -373,7 +374,7 @@ TEST_F(HlslGeneratorImplTest_Builtin, Select_Vector) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
EXPECT_EQ(out.str(), "(bool2(true, false) ? b : a)"); EXPECT_EQ(out.str(), "(bool2(true, false) ? b : a)");
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "src/tint/ast/call_statement.h" #include "src/tint/ast/call_statement.h"
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
@ -30,7 +31,7 @@ TEST_F(HlslGeneratorImplTest_Call, EmitExpression_Call_WithoutParams) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
EXPECT_EQ(out.str(), "my_func()"); EXPECT_EQ(out.str(), "my_func()");
} }
@ -50,7 +51,7 @@ TEST_F(HlslGeneratorImplTest_Call, EmitExpression_Call_WithParams) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
EXPECT_EQ(out.str(), "my_func(param1, param2)"); EXPECT_EQ(out.str(), "my_func(param1, param2)");
} }

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
@ -27,7 +28,7 @@ TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Scalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error();
EXPECT_EQ(out.str(), "1.0f"); EXPECT_EQ(out.str(), "1.0f");
} }
@ -38,7 +39,7 @@ TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Vector) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error();
EXPECT_EQ(out.str(), "float3(1.0f, 2.0f, 3.0f)"); EXPECT_EQ(out.str(), "float3(1.0f, 2.0f, 3.0f)");
} }

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
namespace tint::writer::hlsl { namespace tint::writer::hlsl {
@ -27,7 +28,7 @@ TEST_F(HlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, i)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, i)) << gen.error();
EXPECT_EQ(out.str(), "foo"); EXPECT_EQ(out.str(), "foo");
} }

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT
@ -39,7 +40,7 @@ TEST_P(HlslImportData_SingleParamTest, FloatScalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1.0f)"); EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1.0f)");
} }
@ -77,7 +78,7 @@ TEST_P(HlslImportData_SingleIntParamTest, IntScalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1)"); EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1)");
} }
@ -94,7 +95,7 @@ TEST_P(HlslImportData_SingleVectorParamTest, FloatVector) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), EXPECT_EQ(out.str(),
std::string(param.hlsl_name) + "(float3(0.100000001f, 0.200000003f, 0.300000012f))"); std::string(param.hlsl_name) + "(float3(0.100000001f, 0.200000003f, 0.300000012f))");
@ -134,7 +135,7 @@ TEST_P(HlslImportData_DualParam_ScalarTest, Float) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1.0f, 2.0f)"); EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1.0f, 2.0f)");
} }
@ -156,7 +157,7 @@ TEST_P(HlslImportData_DualParam_VectorTest, Float) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + EXPECT_EQ(out.str(), std::string(param.hlsl_name) +
"(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f))"); "(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f))");
@ -181,7 +182,7 @@ TEST_P(HlslImportData_DualParam_Int_Test, IntScalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1, 2)"); EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1, 2)");
} }
@ -199,7 +200,7 @@ TEST_P(HlslImportData_TripleParam_ScalarTest, Float) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1.0f, 2.0f, 3.0f)"); EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1.0f, 2.0f, 3.0f)");
} }
@ -220,7 +221,7 @@ TEST_P(HlslImportData_TripleParam_VectorTest, Float) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ( EXPECT_EQ(
out.str(), out.str(),
@ -243,7 +244,7 @@ TEST_P(HlslImportData_TripleParam_Int_Test, IntScalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1, 2, 3)"); EXPECT_EQ(out.str(), std::string(param.hlsl_name) + "(1, 2, 3)");
} }
@ -259,7 +260,7 @@ TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string("determinant(var)")); EXPECT_EQ(out.str(), std::string("determinant(var)"));
} }
@ -272,7 +273,7 @@ TEST_F(HlslGeneratorImplTest_Import, HlslImportData_QuantizeToF16_Scalar) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string("float(min16float(v))")); EXPECT_EQ(out.str(), std::string("float(min16float(v))"));
} }
@ -285,7 +286,7 @@ TEST_F(HlslGeneratorImplTest_Import, HlslImportData_QuantizeToF16_Vector) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
EXPECT_EQ(out.str(), std::string("float3(min16float3(v))")); EXPECT_EQ(out.str(), std::string("float3(min16float3(v))"));
} }

View File

@ -21,6 +21,7 @@
#include "src/tint/type/sampler.h" #include "src/tint/type/sampler.h"
#include "src/tint/type/storage_texture.h" #include "src/tint/type/storage_texture.h"
#include "src/tint/type/texture_dimension.h" #include "src/tint/type/texture_dimension.h"
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
using ::testing::HasSubstr; using ::testing::HasSubstr;
@ -38,7 +39,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "ary")) builtin::Access::kReadWrite, "ary"))
<< gen.error(); << gen.error();
@ -51,7 +52,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "ary")) builtin::Access::kReadWrite, "ary"))
<< gen.error(); << gen.error();
@ -64,7 +65,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "ary")) builtin::Access::kReadWrite, "ary"))
<< gen.error(); << gen.error();
@ -77,7 +78,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, program->TypeOf(ty), builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -89,7 +90,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Bool) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, bool_, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, bool_, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -101,7 +102,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_F16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE( ASSERT_TRUE(
gen.EmitType(out, f16, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "")) gen.EmitType(out, f16, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -113,7 +114,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_F32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE( ASSERT_TRUE(
gen.EmitType(out, f32, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "")) gen.EmitType(out, f32, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -125,7 +126,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_I32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE( ASSERT_TRUE(
gen.EmitType(out, i32, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "")) gen.EmitType(out, i32, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -139,7 +140,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix_F16) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, mat2x3, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, mat2x3, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -153,7 +154,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix_F32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, mat2x3, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, mat2x3, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -203,7 +204,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
auto* sem_s = program->TypeOf(s)->As<sem::Struct>(); auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, sem_s, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, sem_s, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -251,7 +252,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_U32) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE( ASSERT_TRUE(
gen.EmitType(out, u32, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "")) gen.EmitType(out, u32, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -264,7 +265,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Vector) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE( ASSERT_TRUE(
gen.EmitType(out, vec3, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "")) gen.EmitType(out, vec3, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -276,7 +277,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Void) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, void_, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, void_, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -288,7 +289,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitSampler) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, sampler, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, sampler, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -300,7 +301,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitSamplerComparison) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, sampler, builtin::AddressSpace::kUndefined, ASSERT_TRUE(gen.EmitType(out, sampler, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, "")) builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();
@ -511,7 +512,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitMultisampledTexture) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE( ASSERT_TRUE(
gen.EmitType(out, s, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "")) gen.EmitType(out, s, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.error(); << gen.error();

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/utils/string_stream.h"
#include "src/tint/writer/hlsl/test_helper.h" #include "src/tint/writer/hlsl/test_helper.h"
namespace tint::writer::hlsl { namespace tint::writer::hlsl {
@ -26,7 +27,7 @@ TEST_F(HlslUnaryOpTest, AddressOf) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error();
EXPECT_EQ(out.str(), "expr"); EXPECT_EQ(out.str(), "expr");
} }
@ -38,7 +39,7 @@ TEST_F(HlslUnaryOpTest, Complement) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error();
EXPECT_EQ(out.str(), "~(expr)"); EXPECT_EQ(out.str(), "~(expr)");
} }
@ -51,7 +52,7 @@ TEST_F(HlslUnaryOpTest, Indirection) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error();
EXPECT_EQ(out.str(), "expr"); EXPECT_EQ(out.str(), "expr");
} }
@ -63,7 +64,7 @@ TEST_F(HlslUnaryOpTest, Not) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error();
EXPECT_EQ(out.str(), "!(expr)"); EXPECT_EQ(out.str(), "!(expr)");
} }
@ -75,7 +76,7 @@ TEST_F(HlslUnaryOpTest, Negation) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
std::stringstream out; utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(out, op)) << gen.error();
EXPECT_EQ(out.str(), "-(expr)"); EXPECT_EQ(out.str(), "-(expr)");
} }