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:
parent
dba03d30fb
commit
2b9d5b338a
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue